Service

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的模式啟動了,并且在系統狀態欄會彈出一個通欄圖標,下拉狀態欄后可以看到通知的詳細內容,如下圖所示。



Service from local to remote


參考資料

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容