Service 服務
一.Service是四大元件之一,是沒有介面的activity,可以用於做一些耗時的操作,比如後臺下載等
生命週期如下
二.如何定義一個Service
1.建立一個類繼承android:app.Service類,並實現抽象方法,onCreate(),OnStartCommand,onBind(),onUnBind(),onDestry;
1 package com.example.servicetest; 2 3 import android.app.Service; 4 import android.content.Intent; 5 importandroid.os.IBinder; 6 import android.util.Log; 7 8 public class MyService extends Service { 9 10 public static final String TAG = "MyService"; 11 12 //建立服務時呼叫 13 @Override 14 public void onCreate() { 15 super.onCreate(); 16 Log.d(TAG, "onCreate");17 } 18 19 //服務執行的操作 20 @Override 21 public int onStartCommand(Intent intent, int flags, int startId) { 22 Log.d(TAG, "onStartCommand"); 23 return super.onStartCommand(intent, flags, startId); 24 } 25 26 //銷燬服務時呼叫 27 @Override 28 publicvoid onDestroy() { 29 super.onDestroy(); 30 Log.d(TAG, "onDestroy"); 31 } 32 33 @Override 34 public IBinder onBind(Intent intent) { 35 return null; 36 } 37 }
2.在清單檔案中配置Service
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:enabled="true" android:exported="true"> </service>
三.服務的啟動,停止,繫結,和解綁
case R.id.start: //啟動服務 服務建立--->啟動 // 如果服務已經建立再次啟動時不會執行建立,操作還是同一個服務,除非銷燬已存在的服務 Intent intent = new Intent(this, MyService.class); startService(intent); break; case R.id.stop: //停止服務 Intent intent1 = new Intent(this, MyService.class); stopService(intent1); break; case R.id.bind: //繫結服務 Intent intent2 = new Intent(this, MyService.class); //bindService()中的引數依次是Intent,ServiceConnection和繫結時自動建立服務的標記位 //如果繫結服務沒有被啟動,那麼他會隨著activity的銷燬而銷燬 bindService(intent2, serviceConnection, BIND_AUTO_CREATE); break; case R.id.unbind: //解綁服務 Intent intent3 = new Intent(this, MyService.class); unbindService(serviceConnection); break;
事實上,onCreate()方法只會在Service第一次被建立的時候呼叫,而onStartCommand()方法在每次啟動服務的時候都會呼叫。
停止服務的兩種方式:
1.在外部使用stopService()
2.在服務的(onStartCommand方法)內部使用stopSelf()方法
onStartCommand方法執行時,返回的是一個int型。這個整型可以有三個返回值:START_NOT_STICKY、START_STICKY、START_REDELIVER_INTENT
START_NOT_STICKY:執行完onStartCommand()方法後,服務被異常kill掉了,不會自動重啟服務
START_STICKY:如果Service程序被kill掉,保留Service的狀態為開始狀態,但不保留遞送的intent物件。隨後系統會嘗試重新建立Service,由於服務狀態為開始狀態,所以建立服務後一定會呼叫onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到Service,那麼引數Intent將為nul
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,系統會自動重啟該服務,並將Intent的值傳入。
四:使用Bind Service完成Service和Activity之間的通訊
應用程式元件(客戶端)通過呼叫bindService()方法能夠繫結服務,然後Android系統會呼叫服務的onBind()回撥方法,則個方法會返回一個跟伺服器端互動的Binder物件。
這個繫結是非同步的,bindService()方法立即返回,並且不給客戶端返回IBinder物件。要接收IBinder物件,客戶端必須建立一個ServiceConnection類的例項,並且把這個例項傳遞給bindService()方法。ServiceConnection物件包含了一個系統呼叫的傳遞IBinder物件的回撥方法。
注意:只有Activity、Service、Content Provider能夠繫結服務;BroadcastReceiver廣播接收器不能繫結服務。
進度監控示例
public class MyService extends Service { private int i; public MyService() { } @Override public void onCreate() { Log.d("TAG", "服務建立了"); //開啟一個執行緒 進度,從1數到100 new Thread(){ @Override public void run() { super.run(); for (i = 1; i <=100 ; i++) { try { sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("TAG", "服務啟動了"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. Log.d("TAG", "繫結"); return new MyBind(); } /** * 由於IBinder介面中需要實現的方法太多,而Binder實現了IBinder介面 * 所以我麼你自定義一個內部類繼承他,並寫入我們所需要的方法 */ class MyBind extends Binder{ //自定義方法獲取進度 public int getProgress(){ return i; } } @Override public boolean onUnbind(Intent intent) { Log.d("TAG", "解綁"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.d("TAG", "銷燬"); super.onDestroy(); } }
在MainActivity中
public class MainActivity extends AppCompatActivity { //ibind //ServiceConnection 一個介面 用於繫結服務與客戶端 //進度監控 MyHandler myHandler = new MyHandler(this); ServiceConnection serviceConnection = new ServiceConnection() { //當客戶端與服務正常連線時,執行服務的繫結操作會被呼叫 @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { MyService.MyBind myBind = (MyService.MyBind) iBinder; int progress = myBind.getProgress(); Log.d("TAg", "handleMessage: " + progress); if (progress <= 100) { Message message = new Message(); message.arg1 = progress; myHandler.sendMessage(message); } } //當客戶端與服務的連線丟失時 @Override public void onServiceDisconnected(ComponentName componentName) { } };