【6】 android 服務的應用 startService 和bindService
最基本的應用那就開啟和關閉了 我們這裡寫一個demo
並講解一下兩個開啟(StartService,BindService)有什麼區別
package com.zy.servicesdemo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; public class MainActivity extends AppCompatActivity { Intent intent; MyServiceConnention myServiceConnention=new MyServiceConnention(); MyService.SericesBinder sericesBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intent = new Intent(this, MyService.class); } public void onclick(View v) { switch (v.getId()) { case R.id.btn_start: startService(intent); break; case R.id.btn_stop: stopService(intent); break; case R.id.btn_start_bind: bindService(intent, myServiceConnention, Context.BIND_AUTO_CREATE); break; case R.id.btn_stop_bind: unbindService(myServiceConnention); break; case R.id.btn_format: sericesBinder.changeFormatBinder("yyyy-MM-dd ss"); break; default: break; } } private class MyServiceConnention implements ServiceConnection { /*服務繫結成功執行*/ @Override public void onServiceConnected(ComponentName name, IBinder service) { sericesBinder= (MyService.SericesBinder) service; } /*服務銷燬*/ @Override public void onServiceDisconnected(ComponentName name) { } } }
介面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="開始" /> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="結束" /> <Button android:id="@+id/btn_start_bind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="繫結" /> <Button android:id="@+id/btn_stop_bind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="解綁" /> <Button android:id="@+id/btn_format" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="改變輸出時間格式" /> </LinearLayout>
服務
package com.zy.servicesdemo; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.util.Log; import java.text.SimpleDateFormat; import java.util.Date; public class MyService extends Service { MyThread myThread; public MyService() { } @Override public IBinder onBind(Intent intent) { myThread.start(); return new SericesBinder(); } @Override public void onCreate() { super.onCreate(); myThread = new MyThread(); Log.e("services start", "服務建立"); } @Override public void onDestroy() { super.onDestroy(); Log.e("services stop", "服務銷燬"); myThread.setStop(); } /*服務執行過程*/ @Override public int onStartCommand(Intent intent, int flags, int startId) { myThread.start(); return super.onStartCommand(intent, flags, startId); } public void changeFormat(String format) { if (myThread != null) myThread.setFormet(format); } public class MyThread extends Thread { boolean stop = true; public void setStop() { stop = false; } String formet = "yyyy-MM-dd hh:mm:ss"; public void setFormet(String formet) { this.formet = formet; } @Override public void run() { while (stop) { SimpleDateFormat sdf = new SimpleDateFormat(formet); String format = sdf.format(new Date()); Log.e("services running", sdf.format(new Date())); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class SericesBinder extends Binder { void changeFormatBinder(String format) { changeFormat(format); } } }
startService 開啟的程式 後臺將持續存在 如果這個程序不死 app 服務也不會死 即使頁面關閉了 也不會影響
bindService 開啟的service生命週期和他繫結的頁面的生命週期相輔相成 如果頁面關閉他也會隨之關閉
更詳細的區別
1. startService和bindService關係?
服務不能自己執行。一旦Activity中呼叫了startService()方法啟動Service後,Activity就不能直接控制Service了。這時就需要bindService()把Activity和Service聯絡起來,之後就能在Activity中指揮Service去工作了。
startService()和bindService()都能啟動Service,它們的呼叫順序也會對Service產生影響,具體影響見下文。
2. startService ()時Service的生命週期
通過startService(),Service會經歷 onCreate() –> onStart() 啟動Service。然後stopService()的時候直接onDestroy()。如果呼叫者直接退出而沒有呼叫stopService(),那麼Service會一直在後臺執行。 注意在Service的一個生命週期之內只會呼叫一次onCreate()方法,stopService()之前若多次startService()則只會呼叫onStart()方法。
3. bindService()時Service的生命週期
如果打算採用bindService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onBind()方法。這個時候呼叫者和服務繫結在一起,呼叫者unbindService()退出了,系統就會先呼叫服務的onUnbind()方法,接著呼叫onDestroy()方法。多次呼叫bindService()方法並不會導致多次建立服務及繫結(也就是說onCreate()和onBind()方法並不會被多次呼叫)。
如果bindService()之前Service已經在運行了,那麼這是呼叫unbindService()只會onUnbind()而不會onDestory()。