Android實現(xiàn)跨進(jìn)程接口回掉的方法
前言
同一個進(jìn)程內(nèi)實現(xiàn)接口回掉很簡單,這里不做敘述,本文主要講的是跨進(jìn)程的接口回掉實現(xiàn)方式。有一種跨進(jìn)程通信的方式就是使用AIDL,但是單純的AIDL通信只可以實現(xiàn)客戶端訪問服務(wù)端主動獲取Binder對象,如果服務(wù)端有變化無法及時通知客戶端?,F(xiàn)在可以通過AIDL跨進(jìn)程接口回掉來解決服務(wù)端發(fā)生變化通知客戶端的問題。
谷歌提供了RemoteCallbackList來實現(xiàn)對IInterface的管理。public class RemoteCallbackList<E extends IInterface>
首先定義兩個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集合,實現(xiàn)ITestInterface.Stub,在registerCallback,和unRegisterCallback中,分別將ITestCallBack對象注冊和反注冊進(jìn)RemoteCallbackList中。RemoteCallbackList提供了獲取注冊進(jìn)去的IInterface對象方法
//其實RemoteCallbackList類似于java中{@link java.util.Observable},用來批量處理接口回調(diào)對象,
//其實如果確保只有一個客戶端會bind到這個服務(wù),只需要保存一個IMyAidlInterfaceCallback即可。
//但是如果有多個,強烈推薦使用其實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ù)端有變化時主動調(diào)用callBack方法去通知客戶端,這樣就實現(xiàn)了服務(wù)端變化主動通知客戶端。可根據(jù)實際方法修改。
在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ù)端,實現(xiàn)AIDL的通信,在客戶端創(chuàng)建綁定按鈕,解綁按鈕,和主動獲取信息的通信按鈕。在主動獲取信息的通信按鈕中實現(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í)價值,謝謝大家對腳本之家的支持。
- 詳解Android跨進(jìn)程通信之AIDL
- Android AIDL實現(xiàn)兩個APP間的跨進(jìn)程通信實例
- android使用AIDL跨進(jìn)程通信(IPC)
- 詳解Android跨進(jìn)程IPC通信AIDL機制原理
- Android AIDL實現(xiàn)跨進(jìn)程通信的示例代碼
- Android 跨進(jìn)程SharedPreferences異常詳解
- Android 跨進(jìn)程通Messenger(簡單易懂)
- Android編程實現(xiàn)AIDL(跨進(jìn)程通信)的方法詳解
- Android應(yīng)用程序四大組件之使用AIDL如何實現(xiàn)跨進(jìn)程調(diào)用Service
- 分析CmProcess跨進(jìn)程通信的實現(xiàn)
相關(guān)文章
Android Studio使用recyclerview實現(xiàn)展開和折疊功能(在之前的微信頁面基礎(chǔ)之上)
這篇文章主要介紹了Android Studio使用recyclerview實現(xiàn)展開和折疊(在之前的微信頁面基礎(chǔ)之上),本文通過截圖實例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2020-03-03
Android使用TabLayout+Fragment實現(xiàn)頂部選項卡
本文通過實例代碼給大家介紹了Android使用TabLayout+Fragment實現(xiàn)頂部選項卡功能,包括TabLyout的使用,感興趣的朋友參考下本文吧2017-05-05
Android性能優(yōu)化之線程監(jiān)控與線程統(tǒng)一詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之線程監(jiān)控與線程統(tǒng)一詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android開發(fā)實現(xiàn)ListView和adapter配合顯示圖片和文字列表功能示例
這篇文章主要介紹了Android開發(fā)實現(xiàn)ListView和adapter配合顯示圖片和文字列表功能,涉及Android使用ListView結(jié)合adapter適配器實現(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-03
Android 3D旋轉(zhuǎn)動畫效果實現(xiàn)分解
如何實現(xiàn)View的3D旋轉(zhuǎn)效果,實現(xiàn)的主要原理就是圍繞Y軸旋轉(zhuǎn),同時在Z軸方面上有一個深入的縮放,具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06

