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

Android中使用AIDL时的跨进程回调—Server回调Client

2017-09-15 17:15 375 查看

Android中使用AIDL时的跨进程回调—Server回调Client

在Android应用程序开发中,可能会遇到跨进程回调问题,比如,调用一个服务,但服务是异步的,服务完成后,需要给客户一个通知,这时就需要用到跨进程回调了。跨进程回调本质上用到了Binder机制,其过程如下:

1.定义aidl

ITest.aidl

package com.example.test;
import com.example.test.ITestListener;

interface ITest {
int getValue();
void setValue(int value);
void registerlistener(ITestListener listener);
}


ITestListener.aidl

package com.example.test;

interface ITestListener {
void onFinished();
}


2.Service定义如下:

public class TestService extends ITest.Stub {
private int mValue;
private ITestListener mListener;
public ServiceImpl() {
mValue = 0;
}

@Override
public int getValue() throws RemoteException {
return mValue;
}

@Override
public void setValue(int value) throws RemoteException {
mValue = value;
if (null != mListener) {
mListener.onFinished(-1);
}
}

private List<ITestListener> mListeners = new ArrayList<ITestListener>();
@Override
public void registerlistener(ITestListener listener) throws RemoteException {
if (!mListeners.contains(listener))
{
mListeners.add(listener);
}
}

public  void dosome(){
synchronized (TestService.this)
{
for (ITestListener listener : mListeners)
{
try
{
if (listener != null)
{
listener.onFinished();
}
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
}
}
}


3.Client定义如下:

package com.example.test;
import com.example.test.ITestListener;
public class TestManager{
private static ITest sService;

public TestManager() {
}

private static ITest getService(){
if (sService == null)
{
IBinder b = ServiceManager.getService(Context.TEST_SERVICE);
sService = ITest.Stub.asInterface(b);
}
return sService;
}

public int getValue() throws RemoteException {
return getService().getValue();
}

public void setValue(int value) throws RemoteException {
getService().setValue(value);
}

public void registerlistener() throws RemoteException {
getService().registerlistener(new ITestListener.Stub(){
@Override
public void onFinished()
{
Log.i(TAG, "do something");
}
});
}
}


总结一下aidl的使用

AIDL的创建方法:

AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型:

1. 不需要import声明的简单Java编程语言类型(int,boolean等)

2. String, CharSequence不需要特殊声明

3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型.

下面是AIDL语法:

// 文件名: SomeClass.aidl // 文件可以有注释, 跟java的一样 // 在package以前的注释, 将会被忽略. // 函数和变量以前的注释, 都会被加入到生产java代码中. package com.example.test;

// import 引入语句 import com.example.test.ITestListener;

实现接口时有几个原则:

.抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的.

.IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。 也就是IPC调用会挂起应用程序导致界面失去响应. 这种情况应该考虑单起一个线程来处理.

.不能在AIDL接口中声明静态属性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android binder