您的位置:首页 > 移动开发 > Android开发

Android AIDL线程通信之Service回调客户端Activity

2015-08-09 11:51 513 查看
之前写了一篇 Android下使用AIDL进行通信 的文章,仅仅是客户端访问远程service,并且返回数据,这种通过调用service方法,并且由方法返回数据,在很多情况下是不太合适的,比如我需要在service中的方法进行很多操作,而且不同的操作会产生不一样的数据,并且这些数据都是需要返回给客户端的,那么仅仅通过方法返回值来返回数据时远远不够的。那么今天我们就继续来研究如何通过service来回调客户端中的方法。

那么首先需要定义两个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;
}
}
}
好了,这就是基本的调用,希望可以帮助到需要的人。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  aidl