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

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接口中声明静态属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值