Android AIDL线程通信之Service回调客户端Activity
2015-08-09 11:51
513 查看
之前写了一篇 Android下使用AIDL进行通信 的文章,仅仅是客户端访问远程service,并且返回数据,这种通过调用service方法,并且由方法返回数据,在很多情况下是不太合适的,比如我需要在service中的方法进行很多操作,而且不同的操作会产生不一样的数据,并且这些数据都是需要返回给客户端的,那么仅仅通过方法返回值来返回数据时远远不够的。那么今天我们就继续来研究如何通过service来回调客户端中的方法。
那么首先需要定义两个AIDL的文件,文件如下:
RemoteService.aidl
接下来实现服务端的代码,新建一个AIDLRemoteService类继承Service:
AIDLRemoteService.java
下面是客户端的实现类:首先是需要实现RemoteServiceCallBack中的方法,然后就是在获得远程RemoteService对象的时候,调用registerCallback方法,将回调对象注册到远程服务中,那么这样,远程服务就可以取出回调对象来进行调用客户端的方法。
枫
那么首先需要定义两个AIDL的文件,文件如下:
RemoteService.aidl
package cn.com.aidl.service; import cn.com.aidl.service.RemoteServiceCallBack; interface RemoteService{ void pay(in int a,in int b); void registerCallback(RemoteServiceCallBack callBack); void unregisterCallback(RemoteServiceCallBack callBack); }RemoteServiceCallBack.aidl
interface RemoteServiceCallBack{ void callClientActivity(in int c); }那么定义好了这两个AIDL文件,我们首先需要知道,RemoteService是在服务端实现的,RemoteServiceCallBack是在客户端实现的。
接下来实现服务端的代码,新建一个AIDLRemoteService类继承Service:
AIDLRemoteService.java
package cn.com.aidl.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; public class AIDLRemoteService extends Service { int c = 0; private RemoteCallbackList<RemoteServiceCallBack> mCallbacks = new RemoteCallbackList<RemoteServiceCallBack>(); @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return mBinder; } private RemoteService.Stub mBinder = new RemoteService.Stub() { public void pay(int a, int b) throws RemoteException { c = a + b; callBack(); } public void registerCallback(RemoteServiceCallBack callBack) throws RemoteException { if (callBack != null) { mCallbacks.register(callBack); } } public void unregisterCallback(RemoteServiceCallBack callBack) throws RemoteException { if (callBack != null) { mCallbacks.unregister(callBack); } } }; @SuppressWarnings("unused") //这个就是回调客户端Activity的方法 private void callBack() { int N = mCallbacks.beginBroadcast(); try { for (int i = 0; i < N; i++) { mCallbacks.getBroadcastItem(i).callClientActivity(c); } } catch (RemoteException e) { } mCallbacks.finishBroadcast(); } }这里面有很多都是特定的写法,比如RemoteCallbackList集合就是存放回调的对象,callBack()方法就是通过取出集合中的对象来调用客户端的方法。
下面是客户端的实现类:首先是需要实现RemoteServiceCallBack中的方法,然后就是在获得远程RemoteService对象的时候,调用registerCallback方法,将回调对象注册到远程服务中,那么这样,远程服务就可以取出回调对象来进行调用客户端的方法。
package cn.com.aidl; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import cn.com.aidl.service.RemoteService; import cn.com.aidl.service.RemoteServiceCallBack; public class MainActivity extends Activity { String a ,b; private EditText first, second; private TextView textView; private Button button; private RemoteService mService; private RemoteServiceCallBack.Stub callback = new RemoteServiceCallBack.Stub() { public void callClientActivity(int c) throws RemoteException { textView.setText(a + " + " + b + " = " + c); } }; //获取到service对象 private ServiceConnection conn = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { mService = null; } public void onServiceConnected(ComponentName name, IBinder service) { mService = RemoteService.Stub.asInterface(service); if(mService != null){ try { mService.registerCallback(callback); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); first = (EditText) this.findViewById(R.id.first); second = (EditText) this.findViewById(R.id.second); textView = (TextView) this.findViewById(R.id.textview); button = (Button) this.findViewById(R.id.button); //开启服务 startService(); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { a = first.getText().toString(); b = second.getText().toString(); try { mService.pay(Integer.parseInt(a), Integer.parseInt(b)); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } private void startService() { Intent intent = new Intent(); //这个Action就是在另一个应用的清单文件中配置的 intent.setAction("cn.com.feng.service"); bindService(intent, conn, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); <span style="white-space:pre"> </span>if(mService!=null){ <span style="white-space:pre"> </span>try { <span style="white-space:pre"> </span>mService.unregisterCallback(callback); <span style="white-space:pre"> </span>} catch (RemoteException e) { <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> if(conn != null){ unbindService(conn); conn = null; } } }好了,这就是基本的调用,希望可以帮助到需要的人。
枫
相关文章推荐
- 基于Android AIDL进程间通信接口使用介绍
- Android 使用【AIDL】调用外部服务的解决方法
- Android程序设计之AIDL实例详解
- Android 使用 AIDL 实现进程间通信,使用基本类型作为输入和输出参数
- AIDL入门
- aidl远程服务调用
- android的AIDL----讲述进程间通信
- 跨进程调用Service(AIDL Service)流程1(普通数据)
- 跨进程调用Service(AIDL Service)流程2(复杂数据)
- AIDL Android跨进程通信调用实例
- Android中关于AIDL的应用
- android aidl in out
- Android bind其他或第三方APK Service方法
- Aidl随笔
- android-aidl-入门-案例
- Android中的AIDL及简单示例
- 远程service下载,使用aidl,队列下载Client端
- 远程service下载,使用aidl,队列下载service端
- AIDL(2)
- AIDL