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前臺服務的使用