【Android】遠程服務(Remote Service)的使用

1.遠程服務簡介

  • 什么是遠程服務
    遠程服務(Remote Service)也被稱之為獨立進程,它不受其它進程影響,可以為其它應用程序提供調用的接口——實際上就是進程間通信IPC(Inter-Process Communication),Android提供了AIDL(Android Interface Definition Language,接口描述語言)工具來幫助進程間接口的建立。

在Android中,不同的應用屬于不同的進程(Process),一個進程不能訪問其它進程的存儲(可以通過ContentProvider實現(xiàn),如:通訊錄的讀取)。

  • 遠程服務的適用場景
    一般適用于為其它應用程序提供公共服務的Service,這種Service即為系統(tǒng)常駐的Service(如:天氣服務等)。
  • 遠程服務的優(yōu)缺點
  • 優(yōu)點
    1.遠程服務有自己的獨立進程,不會受到其它進程的影響;
    2.可以被其它進程復用,提供公共服務;
    3.具有很高的靈活性。
  • 缺點
    相對普通服務,占用系統(tǒng)資源較多,使用AIDL進行IPC也相對麻煩。

2.遠程服務的創(chuàng)建

  • 定義AIDL接口
    通過AIDL文件定義服務(Service)向客戶端(Client)提供的接口,我們需要在對應的目錄下添加一個后綴為.aidl的文件(注意,不是.java),IMyAidlInterface.aidl文件內容如下:
package com.zihao.remoteservice.server;
interface IMyAidlInterface {
  String getMessage();
}

注:如果服務端與客戶端不在同一App上,需要在客戶端、服務端兩側都建立該aidl文件。

  • 新建Remote Service
    在遠程服務中,通過Service的onBind(),在客戶端與服務端建立連接時,用來傳遞Stub(存根)對象。
// 遠程服務示例
public class RemoteService extends Service {
  
  public RemoteService() {
  }
  
  @Override
  public IBinder onBind(Intent intent) {
    return stub;// 在客戶端連接服務端時,Stub通過ServiceConnection傳遞到客戶端
  }
  
  // 實現(xiàn)接口中暴露給客戶端的Stub--Stub繼承自Binder,它實現(xiàn)了IBinder接口
  private IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub(){
  
    // 實現(xiàn)了AIDL文件中定義的方法
    @Override
    public String getMessage() throws RemoteException {
      // 在這里我們只是用來模擬調用效果,因此隨便反饋值給客戶端
      return "Remote Service方法調用成功";        
    }    
  };
  
}

同時,在AndroidManifest.xml中對Remote Service進行如下配置:

<service
  android:name=".RemoteService"
  android:process="com.test.remote.msg">
  <intent-filter>
    <action android:name="com.zihao.remoteservice.RemoteService"/>
  </intent-filter>
</service>

如果客戶端與服務端在同個App中,AndroidManifest.xml中設置Remote Service的andorid:process屬性時,如果被設置的進程名是以一個冒號(:)開頭的,則這個新的進程對于這個應用來說是私有的,當它被需要或者這個服務需要在新進程中運行的時候,這個新進程將會被創(chuàng)建。如果這個進程的名字是以小寫字符開頭的,則這個服務將運行在一個以這個名字命名的全局的進程中,當然前提是它有相應的權限。這將允許在不同應用中的各種組件可以共享一個進程,從而減少資源的占用。


3.客戶端調用遠程服務接口

在客戶端中建立與Remote Service的連接,獲取Stub,然后調用Remote Service提供的方法來獲取對應數(shù)據(jù)。

public class MainActivity extends AppCompatActivity {
  
  private IMyAidlInterface iMyAidlInterface;// 定義接口變量
  private ServiceConnection connection;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main);
    bindRemoteService();
  }
  
  private void bindRemoteService() {
    Intent intentService = new Intent();
    intentService.setClassName(this,"com.zihao.remoteservice.RemoteService");
  
    connection = new ServiceConnection() {
      @Override
      public void onServiceConnected(ComponentName componentName,IBinder iBinder) {
        // 從連接中獲取Stub對象
        iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
        // 調用Remote Service提供的方法
        try {
          Log.d("MainActivity", "獲取到消息:" + iMyAidlInterface.getMessage()); 
        } catch (RemoteException e) {
          e.printStackTrace();
        } 
      } 
  
      @Override
      public void onServiceDisconnected(ComponentName componentName) {
        // 斷開連接
        iMyAidlInterface = null;
      }
    }; 
  
    bindService(intentService, connection, Context.BIND_AUTO_CREATE);
  } 
  
  @Override
  protected void onDestroy() {
    super.onDestroy(); 
    if (connection != null)
      unbindService(connection);// 解除綁定
  }
}
log.png
通信示意圖.png

4.拓展閱讀

Android:關于聲明文件中android:process屬性說明
【Android】Service那點事兒
【Android】Service前臺服務的使用

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容