service作為四大組件值得我們的更多的關注
在Android中,Activity主要負責前臺頁面的展示,Service主要負責需要長期運行的任務。例如,一個從service播放音樂的音樂播放器,應被設置為前臺運行,因為用戶會明確地注意它的運行.在狀態欄中的通知可能會顯示當前的歌曲并且允許用戶啟動一個activity來與音樂播放器交互。
Service的兩種實現形式
1.非綁定
通過調用應用程序組件(例如Activity)的startService()方法來啟動一個服務.一旦啟動,服務就會在后臺一直運行,即使應用程序組件此時被關閉.通常,已經啟動的服務會處理一些單一功能,并且也不需要返回結果給調用者.例如,在網絡上下載或上傳文件.當服務的工作處理結束,才會自己關閉服務.
2.綁定(bind)
通過調用應用程序組件的bindService()方法來綁定一個服務.已綁定的服務會提供一個客戶端-服務端交互接口.該接口主要用來與應用程序交互,發送請求,獲取結果,甚至通過IPC來訪問進程.只要一個程序組件綁定服務就會運行綁定服務,多個應用程序組件可以同時時間綁定一個服務.當所有的應用程序組件都解除綁定,該綁定服務器就會被銷毀.
實現service的方法介紹
onStartCommand()
系統在其它組件比如activity通過調用startService()請求service啟動時調用這個方法.一旦這個方法執行,service就啟動并且在后臺長期運行.如果你實現了它,你需要負責在service完成任務時停止它,通過調用stopSelf()或stopService().(如果你只想提供綁定,你不需實現此方法).
OnBind()
當組件調用bindService()想要綁定到service時(比如想要執行進程間通訊)系統調用此方法.在你的實現中,你必須提供一個返回一個IBinder來以使客戶端能夠使用它與service通訊,你必須總是實現這個方法,但是如果你不允許綁定,那么你應返回null.
OnCreate()
系統在service第一次創建時執行此方法,來執行只運行一次的初始化工作(在調用它方法如onStartCommand()或onBind()之前).如果service已經運行,這個方法不會被調用.
OnDestroy()
系統在service不再被使用并要銷毀時調用此方法.你的service應在此方法中釋放資源,比如線程,已注冊的偵聽器,接收器等等.這是service收到的最后一個調用.
如果一個組件通過調用startService()啟動一個service(最終導致onStartCommand()被調用),之后service會保持運行,直到它通過stopSelf()停止自己或另外的組件調用stopService()停止它.
service實現代碼
1.非綁定
新建一個MyService繼承自Service,并重寫父類的onCreate()、onStartCommand()和onDestroy()方法
public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { // IntentService會使用單獨的線程來執行該方法的代碼 // 該方法內執行耗時任務,比如下載文件,此處只是讓線程等待20秒 long endTime = System.currentTimeMillis() + 20 * 1000; System.out.println("onStart"); while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("----耗時任務執行完成---"); } }我們在布局文件中加入了兩個按鈕,一個用于啟動Service,一個用于停止Service。
然后打開或新建MainActivity作為程序的主Activity,在里面加入啟動Service和停止Service的邏輯,代碼如下所示:
public class MainActivity extends Activity implements OnClickListener { private Button startService; private Button stopService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService = (Button) findViewById(R.id.start_service); stopService = (Button) findViewById(R.id.stop_service); startService.setOnClickListener(this); stopService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; default: break; } }項目中的每一個Service都必須在AndroidManifest.xml中注冊才行,所以還需要編輯AndroidManifest.xml文件,代碼如下所示:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > …… <service android:name="com.example.servicetest.MyService" > </service> </application>
周期分析
onCreate()方法只會在Service第一次被創建的時候調用,如果當前Service已經被創建過了,不管怎樣調用startService()方法,onCreate()方法都不會再執行。因此你可以再多點擊幾次Start Service按鈕試一次,每次都只會有onStartCommand()方法中的打印日志。
2.綁定的service
public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); public class LocalBinder extends Binder { LocalService getService() { // 返回本service的實例到客戶端,于是客戶端可以調用本service的公開方法 return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /**客戶端所要調用的方法*/ public int getRandomNumber() { return mGenerator.nextInt(100); } }下面是一個綁定到LocalService并且在按鈕按下時調用getRandomNumber()的actvity的例子:
public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // 綁定到類LocalService的實例 Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // 從service解除綁定 if (mBound) { unbindService(mConnection); mBound = false; } } /** 當按鈕按下時調用(在layout文件中定義的button并用android:onClick 屬性指定響應到本方法) */ public void onButtonClick(View v) { if (mBound) { // 調用LocalService的一個方法 // 然而,如果這個調用中有掛起操作,那么這個請求應發 // 生在另一個線程來避免拉低activity的性能. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** 定義service綁定的回調,傳給bindService() 的*/ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { //我們已經綁定到了LocalService,把IBinder進行強制類型轉換并且獲取LocalService實例. LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }service的周期函數
1、當采用Context.startService()方法啟動服務,與之有關的生命周期方法
onCreate() 主站蜘蛛池模板: 乌海市| 蛟河市| 那坡县| 鞍山市| 赤城县| 雅安市| 榆树市| 湖口县| 江安县| 新源县| 河南省| 边坝县| 墨脱县| 平罗县| 大荔县| 盐津县| 兴海县| 英吉沙县| 洛川县| 松溪县| 沈丘县| 古交市| 红河县| 墨脱县| 广德县| 沙田区| 岳普湖县| 莒南县| 彭水| 确山县| 康马县| 宁安市| 盈江县| 民勤县| 张家口市| 北辰区| 息烽县| 连江县| 吉安县| 台东县| 潼南县|