菜鸟对使用AIDL的一点理解

AIDL,即Android Interface Definition Language,android接口定义语言,官方文档这么说的(好正式)

Note: Using AIDL is necessary only if you allow clients from different
applications to access your service for IPC and want to handle
multithreading in your service. If you do not need to perform
concurrent IPC across different applications, you should create your
interface by implementing a Binder or, if you want to perform IPC, but
do not need to handle multithreading, implement your interface using a
Messenger. Regardless, be sure that you understand Bound Services
before implementing an AIDL.

嗯。。个人理解,就是说有多个应用程序客户端访问IPC并且有多线程,则使用AIDL,如果没有多线程则使用Binder,只有IPC的话则使用Messenger啦。
1、首先需要创建一个 .aidl 的文件,是一个接口,这里名为“IMyAidlInterface”,里面定义我们想要服务器做的事情,也就是一个个的方法,创建之后记得编译,编译之后会生成 IMyAidlInterface.java文件。。
2、第二部是实现 IMyAidlInterface 接口,我们在服务里面实现接口,

public class IRemoteService extends Service
{

    @Override
    public IBinder onBind(Intent intent)
    {
        return iBinder;
    }

    private IBinder iBinder = new IMyAidlInterface.Stub()
    {
        //这里会生成在接口中的方法
    };
}

或者这样写

public class IRemoteService extends Service
{

    @Override
    public IBinder onBind(Intent intent)
    {
        return iBinder;
    }

    private final IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() 
    {
        //这里会生成在接口中的方法
    };
}

然后看一下Stub源码,

public static abstract class Stub extends android.os.Binder implements com.example.z.aidltest.IMyAidlInterface
{
    private static final java.lang.String DESCRIPTOR = "com.example.z.aidltest.IMyAidlInterface";
    public Stub()
    {
        this.attachInterface(this, DESCRIPTOR);
    }
    public static com.example.z.aidltest.IMyAidlInterface asInterface(android.os.IBinder obj)
    {
        if ((obj==null)) 
        {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin!=null)&&(iin instanceof com.example.z.aidltest.IMyAidlInterface))) 
        {
            return ((com.example.z.aidltest.IMyAidlInterface)iin);
        }
        return new com.example.z.aidltest.IMyAidlInterface.Stub.Proxy(obj);
    }
}

Stub继承Binder类,Binder实现了IBinder接口,所以两种写法是一样的,并且Stub提供了一个asInterface方法返回一个 IMyAidlInterface 类型的 IBinder对象,客户端服务绑定的时候需要使用到IBinder对象,因此即可以调用这个方法。
上面是服务端的代码
3、Expose the interface to clients,暴露接口给客户端,需要在客户端建立同样的 .aidl文件,直接将服务端的aidl文件拷过来即可,复制粘贴大法好,然后在 Activity中即可绑定服务,记得配置文件加上相应的配置。

public class MainActivity extends AppCompatActivity 
{
    IMyAidlInterface iMyAidlInterface;
    ServiceConnection conn = new ServiceConnection()
    {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service)
        {

            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            Log.d("haha","success");
        }

        @Override
        public void onServiceDisconnected(ComponentName name)
        {
            iMyAidlInterface = null;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        bindService();
    }
    @OnClick(R.id.btn)
    public void onClick()
    {
        try
        {
           //调用接口方法
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }

    private void bindService() 
    {
        Intent intent = new Intent();
//        显式 Intent 启动
        intent.setComponent(new ComponentName("com.example.z.aidltest","com.example.z.aidetest.IRemoteService"));

        bindService(intent,conn,BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        unbindService(conn);
    }
}

以上便是菜鸟中的菜鸟对 AIDL的理解,放在这里以后可以看,有什么不对欢迎指正

猜你喜欢

转载自blog.csdn.net/handsonn/article/details/51508951