Android實(shí)現(xiàn)跨進(jìn)程接口回掉的方法
前言
同一個(gè)進(jìn)程內(nèi)實(shí)現(xiàn)接口回掉很簡單,這里不做敘述,本文主要講的是跨進(jìn)程的接口回掉實(shí)現(xiàn)方式。有一種跨進(jìn)程通信的方式就是使用AIDL,但是單純的AIDL通信只可以實(shí)現(xiàn)客戶端訪問服務(wù)端主動獲取Binder對象,如果服務(wù)端有變化無法及時(shí)通知客戶端?,F(xiàn)在可以通過AIDL跨進(jìn)程接口回掉來解決服務(wù)端發(fā)生變化通知客戶端的問題。
谷歌提供了RemoteCallbackList來實(shí)現(xiàn)對IInterface的管理。public class RemoteCallbackList<E extends IInterface>
首先定義兩個(gè)AIDL文件:
1.ITestCallBack.aidl
interface ITestCallBack { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void onTagValid(in String tag); }
2.ITestInterface.aidl 在注冊和反祖冊方法中,需要傳入ITestCallBack的對象
interface ITestInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ boolean isTagValid(in String tag); void registerCallback(in String tag, in ITestCallBack callback); void unRegisterCallback(in String tag, in ITestCallBack callback); }
服務(wù)端:
創(chuàng)建Service,并且在service中定義RemoteCallbackList集合,實(shí)現(xiàn)ITestInterface.Stub,在registerCallback,和unRegisterCallback中,分別將ITestCallBack對象注冊和反注冊進(jìn)RemoteCallbackList中。RemoteCallbackList提供了獲取注冊進(jìn)去的IInterface對象方法
//其實(shí)RemoteCallbackList類似于java中{@link java.util.Observable},用來批量處理接口回調(diào)對象, //其實(shí)如果確保只有一個(gè)客戶端會bind到這個(gè)服務(wù),只需要保存一個(gè)IMyAidlInterfaceCallback即可。 //但是如果有多個(gè),強(qiáng)烈推薦使用其實(shí)RemoteCallbackList public void callBack() { if (mCallBacks == null) { return; } int num = mCallBacks.beginBroadcast(); for (int i = 0; i < num; i++) { try { mCallBacks.getBroadcastItem(i).onTagValid("congratulation callback success " + tag); } catch (RemoteException e) { e.printStackTrace(); } } //結(jié)束后一定要使用finsh,否則下次執(zhí)行beginBroadcast會拋出IllegalStateException異常 mCallBacks.finishBroadcast(); }
在isTagValid中可以調(diào)用callBack方法去遍歷注冊的接口對象,也可以當(dāng)服務(wù)端有變化時(shí)主動調(diào)用callBack方法去通知客戶端,這樣就實(shí)現(xiàn)了服務(wù)端變化主動通知客戶端。可根據(jù)實(shí)際方法修改。
在service的onBind方法中,返回ITestInterface.Stub的對象即可,等待客戶端綁定服務(wù)端。
下面是服務(wù)端Service的代碼:
public class TestService extends Service { private RemoteCallbackList<ITestCallBack> mCallBacks = new RemoteCallbackList<>(); private String tag = "hy"; public TestService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return iTestInterface; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } ITestInterface.Stub iTestInterface = new ITestInterface.Stub() { @Override public boolean isTagValid(String tag) throws RemoteException { if (tag.equals(TestService.this.tag)) { callBack(); return true; } return false; } @Override public void registerCallback(String tag, ITestCallBack callback) throws RemoteException { if (null != mCallBacks && null != callback) { mCallBacks.register(callback); } } @Override public void unRegisterCallback(String tag, ITestCallBack callback) throws RemoteException { if (null != mCallBacks && null != callback) { mCallBacks.unregister(callback); } } }; public void callBack() { if (mCallBacks == null) { return; } int num = mCallBacks.beginBroadcast(); for (int i = 0; i < num; i++) { try { mCallBacks.getBroadcastItem(i).onTagValid("congratulation callback success " + tag); } catch (RemoteException e) { e.printStackTrace(); } } mCallBacks.finishBroadcast(); } }
客戶端:
客戶端首先要做的是綁定服務(wù)端,實(shí)現(xiàn)AIDL的通信,在客戶端創(chuàng)建綁定按鈕,解綁按鈕,和主動獲取信息的通信按鈕。在主動獲取信息的通信按鈕中實(shí)現(xiàn)iTestInterface對象的isTagValid方法可以主動去獲取服務(wù)端的信息(服務(wù)端在isTagValid方法中調(diào)用了callBack方法)。
客戶端代碼:
public class MainActivity extends AppCompatActivity { private String tag = "hy"; private ITestInterface iTestInterface; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iTestInterface = ITestInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { iTestInterface = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindService(); ((Button) findViewById(R.id.buttonregister)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.registerCallback(tag, new ITestCallBack.Stub() { @Override public void onTagValid(String tag) throws RemoteException { Log.e("test", "registerCallback: " + tag); } }); } catch (RemoteException e) { e.printStackTrace(); } } }); ((Button) findViewById(R.id.buttonunregister)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.unRegisterCallback(tag, new ITestCallBack.Stub() { @Override public void onTagValid(String tag) throws RemoteException { } }); } catch (RemoteException e) { e.printStackTrace(); } } }); ((Button) findViewById(R.id.buttonisvalid)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { iTestInterface.isTagValid(tag); } catch (RemoteException e) { e.printStackTrace(); } } }); } private void bindService() { Intent intent = new Intent(); intent.setAction("com.example.heyang.myapplication.TestService"); intent.setPackage("com.example.heyang.myapplication"); boolean success = bindService(intent, connection, Context.BIND_AUTO_CREATE); if (success) { Log.e("test ", "bindService OK"); } else { Log.e("test ", "bindService Fail"); } } @Override protected void onDestroy() { super.onDestroy(); unBindeService(); } private void unBindeService() { try { unbindService(connection); } catch (Exception e) { e.printStackTrace(); } } }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
- 詳解Android跨進(jìn)程通信之AIDL
- Android AIDL實(shí)現(xiàn)兩個(gè)APP間的跨進(jìn)程通信實(shí)例
- android使用AIDL跨進(jìn)程通信(IPC)
- 詳解Android跨進(jìn)程IPC通信AIDL機(jī)制原理
- Android AIDL實(shí)現(xiàn)跨進(jìn)程通信的示例代碼
- Android 跨進(jìn)程SharedPreferences異常詳解
- Android 跨進(jìn)程通Messenger(簡單易懂)
- Android編程實(shí)現(xiàn)AIDL(跨進(jìn)程通信)的方法詳解
- Android應(yīng)用程序四大組件之使用AIDL如何實(shí)現(xiàn)跨進(jìn)程調(diào)用Service
- 分析CmProcess跨進(jìn)程通信的實(shí)現(xiàn)
相關(guān)文章
Android Studio使用recyclerview實(shí)現(xiàn)展開和折疊功能(在之前的微信頁面基礎(chǔ)之上)
這篇文章主要介紹了Android Studio使用recyclerview實(shí)現(xiàn)展開和折疊(在之前的微信頁面基礎(chǔ)之上),本文通過截圖實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2020-03-03Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡
本文通過實(shí)例代碼給大家介紹了Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡功能,包括TabLyout的使用,感興趣的朋友參考下本文吧2017-05-05Android性能優(yōu)化之線程監(jiān)控與線程統(tǒng)一詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之線程監(jiān)控與線程統(tǒng)一詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android開發(fā)實(shí)現(xiàn)ListView和adapter配合顯示圖片和文字列表功能示例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)ListView和adapter配合顯示圖片和文字列表功能,涉及Android使用ListView結(jié)合adapter適配器實(shí)現(xiàn)圖文顯示功能相關(guān)的布局、解析、權(quán)限控制等操作技巧,需要的朋友可以參考下2019-04-04簡單掌握Android Widget桌面小部件的創(chuàng)建步驟
這篇文章主要介紹了簡單掌握Android Widget桌面小部件的創(chuàng)建步驟,Widget一般采用web前端技術(shù)進(jìn)行開發(fā),需要的朋友可以參考下2016-03-03Android 3D旋轉(zhuǎn)動畫效果實(shí)現(xiàn)分解
如何實(shí)現(xiàn)View的3D旋轉(zhuǎn)效果,實(shí)現(xiàn)的主要原理就是圍繞Y軸旋轉(zhuǎn),同時(shí)在Z軸方面上有一個(gè)深入的縮放,具體實(shí)現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解
這篇文章主要為大家介紹了Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04