Android基礎(chǔ):Service —— 默默為你服務(wù)

一. Service簡介

1.1 Service簡介:

  • Android四大組件之一,中文名叫“服務(wù)”。
  • 屬于Android中的計算型組件,作用是執(zhí)行一些需要長期運行的操作,如復(fù)雜計算和后臺下載等。
  • 特點是長生命周期、在后臺允許、沒有用戶界面。

1.2 Service分類:

  • 運行地點分類:本地服務(wù)和遠程服務(wù)
  • 運行類型分類:前臺服務(wù)和后臺服務(wù)
  • 功能類型分類:可通信和不可通信

二. Service使用

Service有兩種啟動方式,分別為context.startService()context.bindService()。這里要提到Service的生命周期,兩種不同的啟動方式有不同的生命周期:

Service生命周期.png

簡單介紹:

  • 調(diào)用startService方法,Service會經(jīng)歷onCreate()創(chuàng)建、onStartCommand()開始運行、接著便進入running階段。此時,如果再調(diào)用startService()方法,不會創(chuàng)建新的Service對象,系統(tǒng)會自動調(diào)用原來的Service實例。如果該Service被stopService()或者其它方式來停止運行,會執(zhí)行onDestory()之后便停止該服務(wù),無論之前調(diào)用過多少次startService()都會被銷毀。
  • 使用bindService()方法,系統(tǒng)首先創(chuàng)建一個Service實例,接著調(diào)用 onCreate()、onBind(),之后調(diào)用者就可以跟服務(wù)進行交互。使用unbindService()方法來解除綁定,此時onUnbind()方法和onDestroy()方法相繼調(diào)用,停止服務(wù)。

Tips:

  • startService()啟動的服務(wù),其調(diào)用者的生命周期與Service的生命周期沒有必然聯(lián)系,即使調(diào)用者的生命周期結(jié)束了,Service依舊在運行,除非調(diào)用stopService()來停止服務(wù)。
  • bindService()啟動的服務(wù),服務(wù)與調(diào)用者的生命周期是綁定的,一旦調(diào)用者退出,服務(wù)也隨著停止。
  • startService()方式啟動的服務(wù),調(diào)用者不可與Service()進行交互,而bindService()啟動可以進行交互。

2.1 具體使用: .startService()

首先創(chuàng)建自己的Service類,重寫其生命周期,并在mainfest.xml中進行注冊。

public class TestService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

}

必須注冊Service,不然不會調(diào)用。簡單注冊:

<service
     android:name=".service.TestService">
</service>

補充下Service在manifest中的屬性以及作用:

屬性 說明 備注
android:name Service類名
android:label Service標簽(名字) 默認為Service類名
android:icon Service圖標
android:permission 此Service權(quán)限 提供了該權(quán)限的應(yīng)用才能控制或連接此服務(wù)
android:process 表示該服務(wù)是否在另一個進程中運行(遠程服務(wù)) 不設(shè)置默認為本地服務(wù);remote則設(shè)置成遠程服務(wù)
android:enabled 系統(tǒng)默認啟動 true:Service 將會默認被系統(tǒng)啟動;不設(shè)置則默認為false
android:exported 該服務(wù)是否能夠被其他應(yīng)用程序所控制或連接 不設(shè)置默認此項為 false

接下來,我們就可以用下面的兩個方法來啟動和停止服務(wù)。


// 啟動服務(wù)
public void start() {  
    Intent intent = new Intent(this, TestService.class);  
    startService(intent);  
}  
// 停止服務(wù)
public void stop() {  
    Intent intent = new Intent(this, TestService.class);  
    stopService(intent);  
}  

2.2 具體使用: .bindService()

首先在我們的Activity中創(chuàng)建Service連接對象,重寫連接和斷開的方法。創(chuàng)建自定義的Binder對象,在onServiceConnected()中賦值然后可以調(diào)用自定義Binder中的方法。使用下方的bind()方法來綁定服務(wù),使用unBind()來解綁服務(wù)。


public class TestActivity extends AppCompatActivity {

    // Service中自定義的Binder對象
    private TestService.MyBinder myBinder;

    // 創(chuàng)建一個Service連接對象
    private ServiceConnection serviceConnection = new ServiceConnection() {
        // Service連接時調(diào)用
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            // 使用向下轉(zhuǎn)型來給myBinder賦值,然后可以調(diào)用自定義Binder中的方法
            myBinder = (TestService.MyBinder) iBinder;
            myBinder.service_connect_Activity();
        }
        // Service斷開連接或異常丟失連接時調(diào)用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };
    /**
     * 綁定服務(wù)
     */
    private void bind(){
        Intent intent = new Intent(this, TestService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }
    /**
     * 解綁服務(wù)
     */
    private void unBind(){
        unbindService(serviceConnection);
    }
}

這里會用到Service的onBind()onUnbind()的生命周期,我們在TestService中重寫之。這里要注意的是,使用bindService()方法啟動的Service,不會調(diào)用onStartCommand()的生命周期。此外,創(chuàng)建自定義Binder類和對象。

public class TestService extends Service {

    private MyBinder mBinder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    //新建一個子類繼承自Binder類
    class MyBinder extends Binder {

        // service和Activity連接用
        public void service_connect_Activity() {
            Log.i("tag","Activity調(diào)用Service,并成功調(diào)用此方法。");
        }
    }

}

這樣,當我們使用Activity中的bind()方法來綁定服務(wù),會自動啟動服務(wù),而我們又重寫了onServiceConnected()方法并使用myBinder來調(diào)用方法。這樣我們就可以用它來Activity和Service來進行通信。

特別Tips:
如果先使用startService()來開啟服務(wù)和bindService()來綁定服務(wù),當使用unbindService()解綁時,Service并不會被銷毀。而是使用stopService()才能銷毀服務(wù)。

2.3 前臺服務(wù):

前臺服務(wù)和后臺服務(wù)的區(qū)別:

  • 前臺服務(wù)會在通知欄顯示通知,而后臺服務(wù)沒有。
  • 前臺服務(wù)優(yōu)先級較高,不會在系統(tǒng)內(nèi)存不足時被回收,而后臺服務(wù)會被回收。

2.3.1具體使用:

在Service中進行操作,將服務(wù)類型以前臺的方式運行顯示在通知欄。

    @Override
    public void onCreate() {
        super.onCreate();
        // 創(chuàng)建Intent,跳轉(zhuǎn)到指定的類
        Intent notificationIntent = new Intent(this,TestActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);

        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("前臺服務(wù)標題"); // 設(shè)置標題
        builder.setContentText("前臺服務(wù)內(nèi)容");  // 設(shè)置內(nèi)容
        builder.setSmallIcon(R.mipmap.ic_launcher);  // 設(shè)置圖標
        builder.setContentIntent(pendingIntent); // 設(shè)置點擊跳轉(zhuǎn)后的intent

        Notification notification = builder.getNotification(); // builder獲取Notification對象
        startForeground(1,notification); // 開啟前臺服務(wù),第一個參數(shù)為id

    }

運行效果:

前臺Service.png

2.4 遠程服務(wù):

暫時引用吧,有空再實現(xiàn)一個:

Android:遠程服務(wù)Service(含AIDL & IPC講解)

三.總結(jié)一下各類Service的特性和使用場景:

  • 按運行地點分類:
類別 特點 優(yōu)點 缺點 應(yīng)用場景
本地服務(wù)(Local) 運行在主線程 節(jié)約資源、方便通信 限制性大,依賴主進程運行 依附某個進程進行服務(wù),如音樂播放
遠程服務(wù)(Remote) 運行在獨立進程,常駐后臺,不受其它Activity影響 比較靈活,不太受約束 消耗資源(單獨進程)、使用復(fù)雜(AIDL IPC) 系統(tǒng)級別服務(wù)
  • 按運行類型分類:
類別 特點 應(yīng)用場景
前臺服務(wù)(forceground) 在通知欄顯示(用戶可以看到) 使用時需要讓用戶了解并能進行操作,如通知欄音樂播放(終止服務(wù),通知欄橫幅消失)
后臺服務(wù)(background) 后臺運行 使用時無需讓用戶知道和操作,如更新天氣,計時提醒等。(終止服務(wù),用戶無法知道)
  • 按功能分類:
類別 特點 應(yīng)用場景
不可通信的后臺服務(wù) startService()啟動,退出后service仍然運行 在后臺運行不進行通信
可通信的后臺服務(wù) bindService()啟動,不執(zhí)行onStartCommand(),隨著調(diào)用者銷毀 該后臺服務(wù)需要進行通信

參考資料:

基礎(chǔ)總結(jié)篇之四:Service完全解析
Android四大組件:Service服務(wù)史上最全面解析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容