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第一次被創建的時候調用,如果當前Service已經被創建過了,不管怎樣調用startService()方法,onCreate()方法都不會再執行。
因此你可以再多點擊幾次Start Service按鈕試一次,每次都只會有onStartCommand()方法中的打印日志。
點擊一下Stop Service按鈕就可以將Service停止掉了。
Service和Thread的關系
Service和Thread之間沒有任何關系。
之所以有不少人會把它們聯系起來,主要就是因為Service的后臺概念。Thread我們大家都知道,是用于開啟一個子線程,在這里去執行一些耗時操作就不會阻塞主線程的運行。而Service我們最初理解的時候,總會覺得它是用來處理一些后臺任務的,一些比較耗時的操作也可以放在這里運行,這就會讓人產生混淆了。但是,如果我告訴你Service其實是運行在主線程里的。所以Service的onCreate方法中是不能執行耗時操作的,如果有就會ANR。
//在MainActivity的onCreate()方法里加入一行打印當前線程id的語句:
Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
//MyService的onCreate()方法里也加入一行打印當前線程id的語句
Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());
一般會在Service里創建一個子線程,那為什么不直接在Activity里創建呢?這是因為Activity很難對Thread進行控制,當Activity被銷毀之后,就沒有任何其它的辦法可以再重新獲取到之前創建的子線程的實例。而且在一個Activity中創建的子線程,另一個Activity無法對其進行操作。但是Service就不同了,所有的Activity都可以與Service進行關聯,然后可以很方便地操作其中的方法,即使Activity被銷毀了,之后只要重新與Service建立關聯,就又能夠獲取到原有的Service中Binder的實例。因此,使用Service來處理后臺任務,Activity就可以放心地finish,完全不需要擔心無法對后臺任務進行控制的情況。
啟動前臺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, "這是通知的標題", "這是通知的內容",
pendingIntent);
startForeground(1, notification);
Log.d(TAG, "onCreate() executed");
}
.........
}
這里只是修改了MyService中onCreate()方法的代碼。可以看到,我們首先創建了一個Notification對象,然后調用了它的setLatestEventInfo()方法來為通知初始化布局和數據,并在這里設置了點擊通知后就打開MainActivity。然后調用startForeground()方法就可以讓MyService變成一個前臺Service,并會將通知的圖片顯示出來。
現在重新運行一下程序,并點擊Start Service或Bind Service按鈕,MyService就會以前臺Service的模式啟動了,并且在系統狀態欄會彈出一個通欄圖標,下拉狀態欄后可以看到通知的詳細內容,如下圖所示。