首页 > 系统 > Android > 正文

Android实现跨进程接口回掉的方法

2019-12-12 00:12:31
字体:
来源:转载
供稿:网友

前言

        同一个进程内实现接口回掉很简单,这里不做叙述,本文主要讲的是跨进程的接口回掉实现方式。有一种跨进程通信的方式就是使用AIDL,但是单纯的AIDL通信只可以实现客户端访问服务端主动获取Binder对象,如果服务端有变化无法及时通知客户端。现在可以通过AIDL跨进程接口回掉来解决服务端发生变化通知客户端的问题。

         谷歌提供了RemoteCallbackList来实现对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);}

服务端:

         创建Service,并且在service中定义RemoteCallbackList集合,实现ITestInterface.Stub,在registerCallback,和unRegisterCallback中,分别将ITestCallBack对象注册和反注册进RemoteCallbackList中。RemoteCallbackList提供了获取注册进去的IInterface对象方法

//其实RemoteCallbackList类似于java中{@link java.util.Observable},用来批量处理接口回调对象,//其实如果确保只有一个客户端会bind到这个服务,只需要保存一个IMyAidlInterfaceCallback即可。//但是如果有多个,强烈推荐使用其实RemoteCallbackListpublic 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();  } } //结束后一定要使用finsh,否则下次执行beginBroadcast会抛出IllegalStateException异常 mCallBacks.finishBroadcast();}

在isTagValid中可以调用callBack方法去遍历注册的接口对象,也可以当服务端有变化时主动调用callBack方法去通知客户端,这样就实现了服务端变化主动通知客户端。可根据实际方法修改。

在service的onBind方法中,返回ITestInterface.Stub的对象即可,等待客户端绑定服务端。

下面是服务端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(); }}

客户端:

        客户端首先要做的是绑定服务端,实现AIDL的通信,在客户端创建绑定按钮,解绑按钮,和主动获取信息的通信按钮。在主动获取信息的通信按钮中实现iTestInterface对象的isTagValid方法可以主动去获取服务端的信息(服务端在isTagValid方法中调用了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();  } }}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对武林网的支持。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表