標籤:android service 服務 綁定 解除綁定
開門見山
開啟服務有三種情況:如果直接使用服務,則沒有必要進行綁定,但是如果要使用服務裡面的方法,則要進行綁定。
-
具體的啟動情況有下:
-
①調用
startService(),再調用
stopService()。
-
②單獨調用
bindService()方法,再
unbindService()後,以執行服務內部的方法。
-
③先調用
startService(),再調用
bindService()方法,再調用
unbindService(),最後調用
stopService()。
-
特殊情況:
-
只要使用了bindService,不管之後是否解除綁定和停止服務,都可以調用服務中的方法
下面針對這三種啟動順序分別做詳細說明。
在講解之前先貼一下代碼:
MyService類,裡面就不加註釋了
public class MyService extends Service { @Override public IBinder onBind(Intent intent) { return new MyBinder(); } @Override public void onCreate() { System.out.println("MyService onCreate():Called by the system when the service is first created"); super.onCreate(); } @Override public boolean onUnbind(Intent intent) { System.out.println("MyService onUnbind():Called when all clients have disconnected from a particular interface published by the service."); return super.onUnbind(intent); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("MyService onStartCommand():Called by the system every time a client explicitly starts the service by calling android.content.Context.startService, providing the arguments it supplied and a unique integer token representing the start request."); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { System.out.println("MyService onDestroy():Called by the system to notify a Service that it is no longer used and is being removed. "); super.onDestroy(); } public void method1() { System.out.println("MyService is method1"); } public void method2() { System.out.println("MyService is method2"); } class MyBinder extends Binder { public void callMethod1() { method1(); } public void callMethod2() { method2(); } }}
MainActivity類
public class MainActivity extends Activity { private MyBinder myBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); conn = new MyServiceConnection(); } ServiceConnection conn; public void start(View v) { Intent service = new Intent(this, MyService.class); startService(service); } public void bind(View v) { Intent service = new Intent(this, MyService.class); bindService(service, conn, Context.BIND_AUTO_CREATE); } public void unbind(View v) { unbindService(conn); } public void stop(View v) { Intent service = new Intent(this, MyService.class); stopService(service); } public void callmethod1(View v) { myBinder.callMethod1(); } private class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("MyServiceConnection connection success"); myBinder = (MyBinder) service; } @Override public void onServiceDisconnected(ComponentName name) { System.out.println("MyServiceConnection disconnection success"); } }}
activity_main.xml頁面配置
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="start" android:text="startService" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="bind" android:text="bindService" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="unbind" android:text="unbindService" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="stop" android:text="stopService" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="callmethod1" android:text="call Method1" /></LinearLayout>
第一種
調用startService(),再調用stopService()。這種情況適用於直接使用Service,不需要外部調用服務內部的方法。
在這一種中,我們分別會點擊startService和stopService,在類MyService中,會以onCreate()開始 — 代表第一次建立服務;以onDestory()結束 — 代表格服務被銷毀;中間會一次或者多次調用(當反覆startService時)onStartCommand()方法 — 來表示用戶端想明確的啟動服務。
當點擊startService時,會觸發onCreate()和onStartCommand()方法,表示服務是第一次建立並且是用戶端明確要求的。這兩個方法執行完畢後,背景服務線程啟動。
看一下這張圖:
這個過程對應的Log圖和應用後台服務進程圖如下:
可以清楚的看到,調用了onCreate()和onStartCommand()方法,同時背景服務進程也已經啟動。
當點擊stopService時,會觸發onDesctory(),此時會去銷毀後台服務進程。
看一下這張圖:
這個過程對應的Log圖和應用後台服務進程圖如下:
可以清楚的看到,調用onDesctory()方法,同時後台服務線程也被銷毀了。
第二種
單獨調用bindService()方法將Activity和Service綁定,以達到服務內部方法的目的,再調用unbindService()解除綁定。
在這一種中,我們分別會點擊bindService和unbindService,在類MyService中,會以onCreate()開始 — 代表第一次建立服務;以onDestory()結束 — 代表格服務被銷毀;在中間,當綁定成功時,會調用onServiceConnected()表明Activity和Service串連成功;當解除綁定時,會調用onUnbind()表明Activity和Service解除串連成功。
當點擊bindService時,會觸發onCreate()和onServiceConnected()方法,以達到調用服務內部方法的目的。但是,請注意後台服務進程並沒有啟動
看一下這張圖:
這個過程對應的Log圖和應用後台服務進程圖如下:
可以清楚的看到,調用了onCreate()和onServiceConnected()方法,但是,背景服務進程卻沒有啟動。綁定後就可以調用服務內部的方法了,而MyService is method1就是證明。
當點擊unbindService時,會觸發onUnbind()和onDestory()方法表明解除綁定和銷毀服務。
看一下這張圖:
這個過程對應的Log圖和應用後台服務進程圖如下:
可以清楚的看到,調用onUnbind()和onDesctory()方法,後台也沒有服務線程。但是,雖然解除了綁定,我們卻依舊可以調用服務中的方法。
第三種
先調用startService(),再調用bindService()方法,再調用unbindService(),最後調用stopService(),這種情況適用於希望服務能夠在後台長期運行,只要不stopService就不停止,也可以讓Activity調用服務中的方法。
當著四種組合使用時,請按照的方式點擊調用:
我們可以看到,執行方法的順序是一級一級的,當上一級沒有觸發時,是無法進入到下一級的。
當點擊完startService和bindService時,Log和後台進程圖如下所示:
可以看到,後台進程啟動,並且Activity和Service綁定成功,且可以調用背景方法。
當點擊完unbindService時,會執行onUnbind()方法解除綁定,Log和後台進程圖如下:
可以看到,雖然解除綁定了,但是服務沒有銷毀,服務中的內容依舊可以被調用。
當點擊完stopService時,服務被銷毀onDestory()方法被執行,Log和後台進程圖如下:
可以看到,背景服務已經被銷毀了,但是,重點中的重點,服務中的方法依舊可以被調用。
總結
開啟服務有三種情況:如果直接使用服務,則沒有必要進行綁定,但是如果要使用服務裡面的方法,則要進行綁定。另外,只要使用了bindService,不管之後是否解除綁定和停止服務,都可以調用服務中的方法
Android基礎筆記(十六)- Service:startService()、stopService()、bindService()、unbindService()補充