Android實(shí)現(xiàn)跨進(jìn)程接口回掉的方法
前言
同一個(gè)進(jìn)程內(nèi)實(shí)現(xiàn)接口回掉很簡(jiǎn)單,這里不做敘述,本文主要講的是跨進(jìn)程的接口回掉實(shí)現(xiàn)方式。有一種跨進(jìn)程通信的方式就是使用AIDL,但是單純的AIDL通信只可以實(shí)現(xiàn)客戶(hù)端訪(fǎng)問(wèn)服務(wù)端主動(dòng)獲取Binder對(duì)象,如果服務(wù)端有變化無(wú)法及時(shí)通知客戶(hù)端?,F(xiàn)在可以通過(guò)AIDL跨進(jìn)程接口回掉來(lái)解決服務(wù)端發(fā)生變化通知客戶(hù)端的問(wèn)題。
谷歌提供了RemoteCallbackList來(lái)實(shí)現(xiàn)對(duì)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 在注冊(cè)和反祖冊(cè)方法中,需要傳入ITestCallBack的對(duì)象
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對(duì)象注冊(cè)和反注冊(cè)進(jìn)RemoteCallbackList中。RemoteCallbackList提供了獲取注冊(cè)進(jìn)去的IInterface對(duì)象方法
//其實(shí)RemoteCallbackList類(lèi)似于java中{@link java.util.Observable},用來(lái)批量處理接口回調(diào)對(duì)象,
//其實(shí)如果確保只有一個(gè)客戶(hù)端會(huì)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會(huì)拋出IllegalStateException異常
mCallBacks.finishBroadcast();
}
在isTagValid中可以調(diào)用callBack方法去遍歷注冊(cè)的接口對(duì)象,也可以當(dāng)服務(wù)端有變化時(shí)主動(dòng)調(diào)用callBack方法去通知客戶(hù)端,這樣就實(shí)現(xiàn)了服務(wù)端變化主動(dòng)通知客戶(hù)端??筛鶕?jù)實(shí)際方法修改。
在service的onBind方法中,返回ITestInterface.Stub的對(duì)象即可,等待客戶(hù)端綁定服務(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();
}
}
客戶(hù)端:
客戶(hù)端首先要做的是綁定服務(wù)端,實(shí)現(xiàn)AIDL的通信,在客戶(hù)端創(chuàng)建綁定按鈕,解綁按鈕,和主動(dòng)獲取信息的通信按鈕。在主動(dòng)獲取信息的通信按鈕中實(shí)現(xiàn)iTestInterface對(duì)象的isTagValid方法可以主動(dòng)去獲取服務(wù)端的信息(服務(wù)端在isTagValid方法中調(diào)用了callBack方法)。
客戶(hù)端代碼:
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é)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- 詳解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(簡(jiǎn)單易懂)
- 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)文章
ASM的tree?api對(duì)匿名線(xiàn)程的hook操作詳解
這篇文章主要為大家介紹了ASM的tree?api對(duì)匿名線(xiàn)程的hook操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android Studio使用recyclerview實(shí)現(xiàn)展開(kāi)和折疊功能(在之前的微信頁(yè)面基礎(chǔ)之上)
這篇文章主要介紹了Android Studio使用recyclerview實(shí)現(xiàn)展開(kāi)和折疊(在之前的微信頁(yè)面基礎(chǔ)之上),本文通過(guò)截圖實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2020-03-03
Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡
本文通過(guò)實(shí)例代碼給大家介紹了Android使用TabLayout+Fragment實(shí)現(xiàn)頂部選項(xiàng)卡功能,包括TabLyout的使用,感興趣的朋友參考下本文吧2017-05-05
Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之線(xiàn)程監(jiān)控與線(xiàn)程統(tǒng)一詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android開(kāi)發(fā)實(shí)現(xiàn)ListView和adapter配合顯示圖片和文字列表功能示例
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)ListView和adapter配合顯示圖片和文字列表功能,涉及Android使用ListView結(jié)合adapter適配器實(shí)現(xiàn)圖文顯示功能相關(guān)的布局、解析、權(quán)限控制等操作技巧,需要的朋友可以參考下2019-04-04
簡(jiǎn)單掌握Android Widget桌面小部件的創(chuàng)建步驟
這篇文章主要介紹了簡(jiǎn)單掌握Android Widget桌面小部件的創(chuàng)建步驟,Widget一般采用web前端技術(shù)進(jìn)行開(kāi)發(fā),需要的朋友可以參考下2016-03-03
Android 3D旋轉(zhuǎn)動(dòng)畫(huà)效果實(shí)現(xiàn)分解
如何實(shí)現(xiàn)View的3D旋轉(zhuǎn)效果,實(shí)現(xiàn)的主要原理就是圍繞Y軸旋轉(zhuǎn),同時(shí)在Z軸方面上有一個(gè)深入的縮放,具體實(shí)現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06
Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解
這篇文章主要為大家介紹了Android 自定義View實(shí)現(xiàn)計(jì)時(shí)文字詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04

