service

service是一個不能被看見的activity,因此service是不能夠和用戶進行直接交互;簡而言之:服務就是運行在後臺的一個activate;

  • 服務的聲明:
    在manifest中使用來進行聲明並進行配置相關屬性;

  • 服務的啓動:
    服務的啓動方式分爲兩種:1.startservice 2.bindservice
    對應服務的結束方式:1.stopservice 2.unbindservice
    對於服務而言 同樣擁有自己的聲明週期:
    startservice-oncreate-onstart-運行
    stopservice-ondestroy-停止
    特別說明:如果service 服務沒有開始的時候那麼是和上面的聲明週期一樣運行 如果服務已經運行 我們再次開啓服務 那麼服務是不會被創建第二次的 也就是服務運行後重復開啓同一個服務只會在第一次開啓的時候調用oncreate方法
    同樣的 如果說服務停止後那麼系統回調摧毀服務方法(ondestroy)如果說用戶直接退出程序而沒有關閉服務,那麼服務會一直在後臺運行;
    簡單舉例說明:qq音樂,當用戶直接使用home鍵或者返回鍵等後臺音樂會一直處於播放狀態,當用戶按下停止鍵時(停止鍵監聽中有stopservice方法)纔會關閉服務;

  • 通過綁定服務的方式開啓服務:
    生命週期如下:
    bingsercice-oncreate-onbind-運行
    onunbindservice-ondestroy-結束
    說明:
    使用服務綁定:
    在service中onbind是一個提供給acticity 用戶數據交互的接口,通過該接口我們能夠實現服務和acticity的交互;
    服務通常是在後臺運行的,但是由於服務的優先級比較低,一旦出現內存緊張不夠等情況,就有可能被系統回收掉這部分內存,如果我們不希望被回收掉,服務也不會出現中斷的情況,這就得了解前臺服務

  • 前臺服務:
    前臺服務和後臺的區別在於我們能夠在手機上看到程序圖標的運行顯示在狀態欄中,這就是前臺服務一直在運行的標誌;
    如何將一個普通的服務轉化爲前臺服務 只需要在server中的oncreat方法中添加以下代碼就能實現;
    ` Notification notification=new Notification(R.drawable.ic_launcher, “你有新的消息啦”, System.currentTimeMillis());

        Intent in=new Intent(this,MainActivity.class);
        PendingIntent pendingintent=PendingIntent.getActivity(this, 0, in, 0);
        notification.setLatestEventInfo(this, "你好", "歡迎光臨", pendingintent);
    
        startForeground(1, notification);`
        再次啓動服務的時候就會在狀態欄找到該通知信息;
    
  • 遠程服務的使用(上)
    爲什麼要使用遠程服務?
    遠程服務會將服務放置在不同的進程中;注意這裏是進程,而不是線程,附帶一說的就是服務是處在主線程的,如果不信,可以使用Thread.currentThread.getId()(令外區分不同進程的方法 process.myPid()來查看進程);分別放置在acitivity中和service中進行查看;
    繼續原來的話題,當放在不同的進程中,當然就不存在主線程的一些問題比如說阻塞主線程,耗時操作等影響了;
    如何轉化爲遠程服務?
    只需要打開manifest 在你生命service中添加process 屬性其值爲“:remote”
    使用遠程服務注意:
    一旦將服務變成不同進程的時候,那麼我們再去使用bindservice的時候肯定會崩潰,因爲在當前進程中是查找不到的;如果關聯不同進程間的服務,則需要使用AIDL來進行通訊了;
    什麼是aidl?
    aidl(Android Interface Definition Language)是Android接口定義語言的意思,它可以用於讓某個Service與多個應用程序組件之間進行跨進程通信,從而可以實現多個應用程序共享同一個Service的功能。
    aidl創建方式?
    在eclipse中創建aidl文件,建議大家先寫個java文件定義好接口 該接口是實現acticity和不同進程的service通訊使用的,然後再創建一個file文件後綴爲aidl,將java中的所有包括ctrl+c/v過去,然後刪除java就可以了 。如果你發現gen文件下生成了一個對應的一個java文件表明創建成功 否則需要檢查你的代碼是否正確了。

    創建接口對象 接口名.stub=new stub(),會自動重寫aidl文件中的方法;
    在onbind中返回接口對象,該對象;
    在acticity中去實現該接口,只需要在serverconnected中把IBinder對象作爲接口賦值給我們的接口對象就可以;這樣就利用了aidl實現跨進程的通訊;
    具體操作代碼如下:

    server中:

@Override
    public IBinder onBind(Intent arg0) {
        Log.e("service", "onBind");

        return mbinder ;
    }
    myaidl.Stub mbinder=new Stub() {
        //重寫的方法
    }

acticity中:

private myaidl myaidls;
private ServiceConnection  con=new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        myaidls=null;

    }

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder arg1) {

        myaidls=myaidl.Stub.asInterface(arg1);
//通過myaidls調用接口中的方法 傳值
    }
};
  • 遠程服務(下)
    通常我們使用遠程服務希望的是在不同程序間進行交互;而不是如上面一樣在一個程序中進行操作;
    如何在不同程序間進行操作?
    不同的程序運行在不同的進程中 同樣是使用aidl來進行交互,
    創建一個不同的app項目(取名client),
    將上面項目中的你放接口的包完整的複製在client中,
    同樣的在acticity中去使用aidl接口 和上面acticity中代碼一樣,這裏我就不再複製一次到這裏,還是不知道怎麼做的看上面代碼 複製 粘貼。

    說明:
    在不同的項目中使用同一個服務的時候,bindserver所綁定的intent只能使用隱式方式。因爲client中是沒有服務的 。
    所以只需要在server中添加進入動作 intent-fileter 並聲明action
    代碼如下:<service android:name="com.example.service.myservice"
    android:process=":remote">
    <intent-filter >
    <action android:name="com.example.service.myaidl"/>
    </intent-filter>
    </service>

發佈了43 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章