AIDL示例

前面的文章,介绍了aidl的几个必要组成部分,以及其关系。这里由一个例子来更好的说明,并且,可以引向更深的问题。
aidl在android应用层里面常用于单独进程的service与activity通讯。如果在同一个进程中的service与activity,当然没必要这样做。这两种使用service的方式,在形式上当然也是有区别的。
现在我们要在一个单独的进程中,实现add方法,并且把结果返回给client。我们知道Binder机制可以实现进程之间通讯,所以Client肯定要能获取到Binder,但是如何获取呢?

public class MainActivity extends AppCompatActivity {
    private ITest mITest;
    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //在这里拿到ITest
            try {
                mITest = ITest.Stub.asInterface(service);
                //调用ITest中的方法,实际上是调用了Proxy的方法
                int sum = mITest.add(1, 2);
                Log.d("test", "sum = " + sum);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, RemoteService.class);
        bindService(intent, mConnection, BIND_AUTO_CREATE);
    }
}

Proxy是代理的意思,当然是给client用的,但是,Proxy是Stub的私有类,不能直接在client中获取并调用其方法,所以只能通过Stub提供的asInterface方法暴露出来。我们再来看看这个方法

public static com.example.aidl.ITest asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.aidl.ITest))) {
return ((com.example.aidl.ITest)iin);
}
//这里很明显了
return new com.example.aidl.ITest.Stub.Proxy(obj);
}

前几篇文章分析可知,Stub是用在service中的,所以这段代码是好理解的。

public class RemoteService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return new TestBinder();
    }
	//service要实现ITest.aidl中定义的函数,它是真正干活的
    class TestBinder extends ITest.Stub{
        @Override
        public int add(int a, int b) throws RemoteException {
            return a+b;
        }
    }
}

mainifest中的配置 ,让service真正运行在独立的进程当中


我们的client是在java层定义,service也是在java层定义,似乎与底层无关,这个不太可能,但看上去又是这样的。进程之间的通讯,不可能离开系统层的,因为无论是何种机制,都是基于系统层的调用。

你可能感兴趣的:(Android,源码)