Service的生命周期
public class MyService extends Service {
public static final String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() executed");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() executed");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
第一次點擊Start Service
之后點擊
onCreate()方法只會在Service第一次被創(chuàng)建的時候調(diào)用,如果當(dāng)前Service已經(jīng)被創(chuàng)建過了湖雹,不管怎樣調(diào)用startService()方法瓷式,onCreate()方法都不會再執(zhí)行诅福。
因此你可以再多點擊幾次Start Service按鈕試一次刁笙,每次都只會有onStartCommand()方法中的打印日志。
點擊一下Stop Service按鈕就可以將Service停止掉了渊迁。
Service和Thread的關(guān)系
Service和Thread之間沒有任何關(guān)系拧揽。
之所以有不少人會把它們聯(lián)系起來剃盾,主要就是因為Service的后臺概念。Thread我們大家都知道淤袜,是用于開啟一個子線程痒谴,在這里去執(zhí)行一些耗時操作就不會阻塞主線程的運行。而Service我們最初理解的時候铡羡,總會覺得它是用來處理一些后臺任務(wù)的积蔚,一些比較耗時的操作也可以放在這里運行,這就會讓人產(chǎn)生混淆了烦周。但是尽爆,如果我告訴你Service其實是運行在主線程里的。所以Service的onCreate方法中是不能執(zhí)行耗時操作的读慎,如果有就會ANR漱贱。
//在MainActivity的onCreate()方法里加入一行打印當(dāng)前線程id的語句:
Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
//MyService的onCreate()方法里也加入一行打印當(dāng)前線程id的語句
Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());
一般會在Service里創(chuàng)建一個子線程,那為什么不直接在Activity里創(chuàng)建呢夭委?這是因為Activity很難對Thread進行控制幅狮,當(dāng)Activity被銷毀之后,就沒有任何其它的辦法可以再重新獲取到之前創(chuàng)建的子線程的實例株灸。而且在一個Activity中創(chuàng)建的子線程崇摄,另一個Activity無法對其進行操作。但是Service就不同了慌烧,所有的Activity都可以與Service進行關(guān)聯(lián)逐抑,然后可以很方便地操作其中的方法,即使Activity被銷毀了屹蚊,之后只要重新與Service建立關(guān)聯(lián)泵肄,就又能夠獲取到原有的Service中Binder的實例。因此淑翼,使用Service來處理后臺任務(wù),Activity就可以放心地finish品追,完全不需要擔(dān)心無法對后臺任務(wù)進行控制的情況玄括。
啟動前臺Service
public class MyService extends Service {
public static final String TAG = "MyService";
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
Notification notification = new Notification(R.drawable.ic_launcher,
"有通知到來", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(this, "這是通知的標題", "這是通知的內(nèi)容",
pendingIntent);
startForeground(1, notification);
Log.d(TAG, "onCreate() executed");
}
.........
}
這里只是修改了MyService中onCreate()方法的代碼∪馔撸可以看到遭京,我們首先創(chuàng)建了一個Notification對象胃惜,然后調(diào)用了它的setLatestEventInfo()方法來為通知初始化布局和數(shù)據(jù),并在這里設(shè)置了點擊通知后就打開MainActivity哪雕。然后調(diào)用startForeground()方法就可以讓MyService變成一個前臺Service船殉,并會將通知的圖片顯示出來。
現(xiàn)在重新運行一下程序斯嚎,并點擊Start Service或Bind Service按鈕利虫,MyService就會以前臺Service的模式啟動了,并且在系統(tǒng)狀態(tài)欄會彈出一個通欄圖標堡僻,下拉狀態(tài)欄后可以看到通知的詳細內(nèi)容糠惫,如下圖所示。