Android远程服务与本地服务的特点以及功能差异
最近又重新看了點IPC的相關知識,以前看過不少Binder的知識,看到c++層思路就很模糊了,回頭再看也算是一種學習。
IPC全稱為:interprocess communication內部進程間通信,官方地址:http://developer.android.com/intl/zh-cn/guide/components/aidl.html,網上對這一塊介紹的資料也著實不少,入門的話還是推薦看老羅的。
鑒于以前也知識看看相關知識,從來也沒動手去做過,于是就照著官方文檔開始動手創建Demo, 在按照官方文檔實現之后,我察覺到有一個需求,官方只是說客戶端可以調用遠程服務端,那么遠程服務端想要調用客戶端可不可以呢?
為了盡快實現需求,那我就先將服務啟動在本地,也就是說與Service與Activity處于同一進程,進行測試。它的結果是可行的,相關代碼如下:
Activity相關代碼:
<span style="font-family:Microsoft YaHei;font-size:14px;">public class MainActivity extends ActionBarActivity implements ServiceConnection, IServiceConnect {public final static String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {...bindService(new Intent("com.example.aidl.RemoteService"), this, BIND_AUTO_CREATE);}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) { <span style="white-space:pre"> </span>Log.e(TAG, "MainActivity onServiceConnected " + name + " - " + service);if (service instanceof ServiceBinder) {ServiceBinder new_name = (ServiceBinder) service;// 獲取服務的引用,使服務與Activity建立雙向關系RemoteService service2 = new_name.getService();service2.setmServiceConnect(this);}}...@Overridepublic void callback() {// 這種模式只有在同一進程中的服務才可以被使用Log.e(TAG, "MainActivity 被服務端調用");}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(this);} } </span> Service相關代碼:
<span style="font-family:Microsoft YaHei;font-size:14px;">public class RemoteService extends Service implements Runnable {public final static String TAG = "RemoteService";public IServiceConnect mServiceConnect;...@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, "RemoteService onBind");return new ServiceBinder(this);//返回含有服務引用的內部類}public static class ServiceBinder extends Binder {private RemoteService service;public ServiceBinder(RemoteService service) {super();this.service = service;}public RemoteService getService() {return service;}}public void setmServiceConnect(IServiceConnect mServiceConnect) {this.mServiceConnect = mServiceConnect;new Handler().postDelayed(RemoteService.this, 3000);//當建立連接之后啟動一個任務}@Overridepublic void run() {if (mServiceConnect != null) {mServiceConnect.callback();//調用Activity的相關方法,驗證通信}}} </span>
上述結果是可以在同一進程的Activity與Service間互相通信的,因為在onServiceConnected中回調的Binder對象則為剛剛Service返回的對象,在Activity中打印的Log如下:
那么跨進程間互相通信可不可以呢?
我們在Service的Manifest文件中給Service添加Process屬性,屬性值為:remote:<span style="font-family:Microsoft YaHei;font-size:14px;"><serviceandroid:name="com.example.aidl.RemoteService"android:process=":remote" ><intent-filter><action android:name="com.example.aidl.RemoteService" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></service></span> 好了,這下啟動服務之后,它就屬于遠程服務了,它與Activity不屬于同一個進程,在Android中一個進程則是一個虛擬機。
如果我再按照剛才的方法進行測試,服務是啟動了,但是Activity收到的Binder對象卻是這樣的:
這里是說,返回的組件名稱為RemoteService,但是返回的Binder對象則為BinderProxy,這個BinderProxy則為RemoteService遠程服務在本地的代理,熟悉AIDL的相關信息的人,肯定知道Proxy知道是什么。
那么我們在這里可不可以從Proxy對象中把遠程的RemoteService對象拿到呢,我們看一下調試信息:
我們看到在Proxy中的并沒有RemoteService的引用,嗯,因為IPC通信,是跨進程的,我們都是通過代理與服務打交道的,所以...
那么回到標題,說說遠程服務與本地服務的特點與差異:
其實都是服務,提供的功能一致,只是一個在本地,一個在其它進程,所以,服務與客戶端打交道的時候就有了不同,要謹慎對待。
總結
以上是生活随笔為你收集整理的Android远程服务与本地服务的特点以及功能差异的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android官方开发文档Trainin
- 下一篇: 【HTML/CSS】display相关属