編輯:關於Android編程
服務(service)是Android中實現程序後台運行的程序,非常適合去執行那些不需要和用戶交互還要長期運行的任務,其運行不依賴任何用戶界面。
服務不是運行在一個獨立的進程當中的,而是 依賴於創建服務時所在的應用程序進程。當應用程序的進程被殺掉時,所依賴於該進程的服務也會停止運行。
服務並不會自動開啟線程,所有的代碼都是默認在主線程當中的。這需要我們在服務內部手動創建子線程,並在這裡執行具體的任務,否則可能出現主線程被阻塞住的情況。
Service使用步驟如下:
1. 繼承service類
2. AndroidManifast.xml配置清單文件中節點裡對服務進行注冊
服務不能自己運行,需要通過Contex.startService()或Contex.bindService()啟動服務
通過startService()方法啟動的服務於調用者沒有關系,即使調用者關閉了,服務仍然運行想停止服務要調用Context.stopService()或者stopSelf()方法,此時系統會調用onDestory(),使用此方法啟動時,服務首次啟動系統先調用服務的onCreate()–>onStartCommand(),如果服務已經啟動再次調用只會觸發onStartCommand()方法,onStart方法在API 5時被廢棄,替代它的是onStartCommand方法。
public class MainActivity extends AppCompatActivity { private Button btn_startservice; private Button btn_stopservice; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_startservice = (Button) findViewById(R.id.btn_startserver); btn_stopservice = (Button) findViewById(R.id.btn_stopservice); btn_startservice.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //借助Intent來實現啟動服務 Intent startIntent = new Intent(MainActivity.this, StartService.class); startService(startIntent); } }); btn_stopservice.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent stopIntent = new Intent(MainActivity.this, StartService.class); //停止服務 stopService(stopIntent); } }); } }
//service類 public class StartService extends Service { @Override public void onCreate(){ super.onCreate(); Log.d("startService", "onCreate executed"); } @Override public int onStartCommand(Intent intent, int flag, int startId){ Log.d("startService", "onStartCommand executed"); return super.onStartCommand(intent, flag, startId); } @Override public void onDestroy(){ super.onDestroy(); Log.d("startService", "onDestroy executed"); } @Override public IBinder onBind(Intent intent){ throw new UnsupportedOperationException("Not yet implemented"); } }
顯示結果: 02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onCreate executed 02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onStartCommand executed 02-21 09:10:07.933 3712-3712/com.example.servicetest D/startService: onStartCommand executed 02-21 09:10:09.703 3712-3712/com.example.servicetest D/startService: onDestroy executed 應用程序界面中使用startservice按鈕 調用onCreate() onStartCommand(),再次按只調用onStartCommand(),按stopservice按鈕調用onDestroy()。
使用bindService()啟動的服務與調用者(Context)綁定,只要調用者關閉服務就終止,使用此方法啟動時,服務首次啟動系統先調用服務的onCreate()–>onBind(),如果服務已經啟動再次調用不會再觸發這兩個方法,調用者退出(或不存在)時系統會調用服務的onUnbind()–>onDestory(),想主動解除綁定可使用Contex.unbindService(),系統依次調用onUnbind()–>onDestory(),
使用bindService可以實現與正在運行的service進行聯系交流。而startService適合自己在後台長期運行,若與之交流頻繁會造成性能問題。
//創建一個Binder對象對下載功能進行管理 public class DownBinderService extends Service { /** * 1. 添加了一個public內部類繼承Binder,並添加兩個方法; * 2. 新建一個IBinder對象——new那個Binder內部類; * 3. onBind方法返還那個IBinder對象。 */ private DownloadBinder mBinder = new DownloadBinder(); //繼承Binder的DownloadBinder內部類,並寫了兩個可被操作的方法。 class DownloadBinder extends Binder { public void startDownload(){ Log.d("DownBinderService", "startdownload"); } public int getProgress(){ Log.d("DownBinderService","getprogress.."); return 0; } } @Override public IBinder onBind(Intent intent) { return mBinder; } }
//MainActivity中的onCreate()裡寫如下代碼服務的綁定與解綁定 btn_bindservice = (Button) findViewById(R.id.btn_bindservice); btn_unbindservice = (Button) findViewById(R.id.btn_unbindservice); btn_bindservice.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent bindIntent = new Intent(MainActivity.this, DownBinderService.class); //綁定服務 bindService(bindIntent, connection, BIND_AUTO_CREATE); } }); btn_unbindservice.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ //解綁服務 unbindService(connection); } });
//MainActivity裡寫下面服務回調的代碼 private DownBinderService.DownloadBinder downloadBinder; //在Activity中,我們通過ServiceConnection接口來取得建立連接 // 定義服務綁定的回調,傳遞給bindService() private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (DownBinderService.DownloadBinder) service; downloadBinder.startDownload(); downloadBinder.getProgress(); } //與服務聯系中斷的時候就調用這個方法 @Override public void onServiceDisconnected(ComponentName name) { } };
bindService()調用方法的步驟:
在服務的內部創建一個內部類(如上述的DownloadBinder)提供方法,可以間接調用服務的方法 實現服務的onBind()方法,返回的就是這個內部類DownloadBinder 的對象(實際也是IBinder對象) 在Activity 綁定服務。 在服務成功綁定的回調方法onServiceConnected, 會傳遞過來一個 IBinder對象 強制類型轉化為自定義的接口類型(如downloadBinder = (DownBinderService.DownloadBinder) service;),調用接口裡面的方法。創建了ServiceConnection匿名類,要重寫其中的兩個方法,在服務成功綁定和解綁定的時候調用。
綁定是異步進行的,bindService()將立即返回,並不會向客戶端返回 IBinder 。為了接收 IBinder ,客戶端必須創建一個 ServiceConnection 的實例,並把它傳給 bindService()。 ServiceConnection 包含了一個回調方法,系統將會調用該方法來傳遞客戶端所需的那個 IBinder。
注意:
只有activity、服務和content provider才可以綁定到服務上,不能從廣播接收器(broadcast receiver)中綁定服務。
Bounded方式下在onUnbind() 還以調用onRebind():當再綁定服務, 這次綁定的服務對象是之前已經創建好的且沒有被銷毀(被執行onDestroy()),所以這次綁定服務時就會調用onRebind()方法,並且本次不會調用onBind()。
1. 前言提到的進程間通信(IPC:Inter-Process Communication),在Android系統中,一個進程是不能直接訪問另一個進程的內存的,需要提供一
概述:當Android自帶的View滿足不了開發者時,自定義View就發揮了很好的作用。建立一個自定義View,需要繼承於View類,並且實現其中的至少一個構造函數和兩個
android-async-http開源項目可以是我們輕松的獲取網絡數據或者向服務器發送數據,使用起來非常簡單,關於android-async-http開源項目的介紹內容
獲取網絡信息需要在AndroidManifest.xml文件中加入相應的權限。 1)判斷是否有網絡連接,沒有則進入網絡設置/***檢測網絡是否連接*@retur