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

Android AIDL(安卓接口定义语言)基本使用方法

2018-01-04 00:30 429 查看
跨进程间通信,分别有Client端和Service端不同进程

1.定义AIDL文件,此文件现代当于一个协议,定义服务端要实现的方法。
如:

package com.example.aidl;  

interface IMyService {  

    void play();  

    void pause();  

}  

2.实现服务端Service:
如:
public class AIDLService extends Service {  

    private MyBinder mBinder;  

    @Override  

    public IBinder onBind(Intent intent) { 

mBinder = new MyBinder();

        return mBinder;  //返回binder对象

    }  

     /*  

     * 该类继承了IMyService.Stub类而不是extends Binder类。 

     * IMyService.Stub是Binder的子类。 

     * 进程内的Service定义MyBinder内部类是继承Binder类。 

     */  

    public class MyBinder extends IMyService.Stub {  

        @Override  

        public void play() throws RemoteException {  

           Log.i(tag, "service 自定义 play()...");   

        }  

        @Override  

        public void pause() throws RemoteException {  

            Log.i(tag, "service 自定义 pause()..."); 

        }  

    }  

3.把AIDL文件接口复制到Client项目

4.在Client项目中调用Service项目的服务。
如:

public class MainActivity extends Activity implements OnClickListener {  

    Button btnBind, btnPlay, btnPause;  

    IMyService mBinder; // 接口的一个引用  

    boolean mIsBind = false; // 绑定值为true,未绑定制为false;  

    private ServiceConnection mConn = new ServiceConnection() {  

        @Override  

        public void onServiceDisconnected(ComponentName name) {  

        }  

        @Override  

        public void onServiceConnected(ComponentName name, IBinder service) {  

            /* 

             * 获得另一个进程中的Service传递过来的IBinder对象-service, 

             * 用IMyService.Stub.asInterface方法转换该对象,这点与进程内的通信不同 

             */  

            mBinder = IMyService.Stub.asInterface(service);  

            mIsBind = true;  

            Log.i("MainActivity", "onServiceConnected....");  

        }  

    };   

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.activity_main);  

        btnBind = (Button) findViewById(R.id.btn_bind);  

        btnPlay = (Button) findViewById(R.id.btn_play);  

        btnPause = (Button) findViewById(R.id.btn_pause);  

        btnBind.setOnClickListener(this);  

        btnPlay.setOnClickListener(this);  

        btnPause.setOnClickListener(this);  

    }   

    @Override  

    public void onClick(View v) {  

        Intent intent = new Intent();  

        int btn = v.getId();  

        switch (btn) {  

        case R.id.btn_bind:  

            intent.setAction(Constant.ACTION_AIDL);  

            bindService(intent, mConn, BIND_AUTO_CREATE);
//绑定服务

            break;  

        case R.id.btn_play:  

            if (mIsBind){  

                try {  

                    mBinder.play(); //调用IMyService接口的方法,服务端的逻辑就可以使用

                } catch (RemoteException e) {  

                    e.printStackTrace();  

                }//调用service中的play()  

            }  

                break;  

        case R.id.btn_pause:  

            if(mIsBind){  

                try {  

                    mBinder.pause(); //调用IMyService接口的方法

                } catch (Exception e) {  

                    e.printStackTrace();  

                }  

            }  

            break;  

        }  

    }  

}  

以上可以看到,Stub是IMyService中的一个静态抽象类,继承了Binder,并且实现了IMyService接口。这也就解释了我们定义IMyInterface.Stub的时候为什么需要实现IMyService中的方法了,也说明了为什么我们可以把IMyService.Stub向上转型成IBinder了。

总结: 
AIDL的最终效果就是让 IPC的通讯就像调用函数那样简单。自动的帮你完成了参数序列化发送以及解析返回数据的那一系列麻烦。而你所需要做的就是写上一个接口文件,然后利用aidl工具转化一下得到另一个java文件,这个文件在服务和客户端程序各放一份。服务程序继承IxxxxService.Stub 然后将函数接口里面的逻辑代码实现一下。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息