編輯:關於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()。
Android進程通信之Messenger和AIDL使用詳解
1. 前言提到的進程間通信(IPC:Inter-Process Communication),在Android系統中,一個進程是不能直接訪問另一個進程的內存的,需要提供一
Android之自定義View以及畫一個時鐘
概述:當Android自帶的View滿足不了開發者時,自定義View就發揮了很好的作用。建立一個自定義View,需要繼承於View類,並且實現其中的至少一個構造函數和兩個
08_android入門_android-async-http開源項目介紹及使用方法
android-async-http開源項目可以是我們輕松的獲取網絡數據或者向服務器發送數據,使用起來非常簡單,關於android-async-http開源項目的介紹內容
Android 網絡連接判斷並進行相關處理
獲取網絡信息需要在AndroidManifest.xml文件中加入相應的權限。 1)判斷是否有網絡連接,沒有則進入網絡設置/***檢測網絡是否連接*@retur