Android -- 小试AIDL

来源:互联网 发布:validator.js 编辑:程序博客网 时间:2024/06/15 13:09

1.关于AIDL

       AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。设计这门语言的目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信。


2.Demo

首先,在AS工程中创建一个.aidl文件,该文件定义了通信接口。

// IMyAidlInterface.aidlpackage com.leeee.aidltest;// Declare any non-default types here with import statementsinterface IMyAidlInterface {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);    String getInfo();}

这里我只添加了一个简单的方法getInfo(),建立.aidl文件后rebuild工程,系统会自动生成IMyAidlInterface.Stub();


然后,创建Service类(在Manifest中配置为独立进程的Service)

public class MyService extends Service {    public final static String TAG = "MyService";    private IBinder mBinder = new IMyAidlInterface.Stub() {        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        @Override        public String getInfo() throws RemoteException {            return "我是 Service 返回的字符串";        }    };    public MyService() {    }    @Override    public void onCreate() {        super.onCreate();        Log.e("lyt", "onCreate");    }    @Override    public IBinder onBind(Intent intent) {        Log.e("lyt", "onBind");        return mBinder;    }}

由于要用到aidl进行进程通信,在这个Service中,定义了一个mBinder并实现IMyAidlInterface定义的接口。在onBind()方法中返回该mBinder。


最后,写Activity。

public class MainActivity extends AppCompatActivity {    public final static String TAG = "MainActivity";    private Button startBtn = null;    IMyAidlInterface mAidlInterface;    private ServiceConnection mConn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.e("lyt", "onServiceConnected");            mAidlInterface = IMyAidlInterface.Stub.asInterface(service);            String s = null;            try {                s = mAidlInterface.getInfo();            } catch (RemoteException e) {                e.printStackTrace();            }            Log.e("lyt", "从Service得到的字符串:" + s);        }        @Override        public void onServiceDisconnected(ComponentName name) {            Log.e("lyt", "连接Service失败");        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        startBtn = (Button) findViewById(R.id.button);        startBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this, MyService.class);                bindService(intent, mConn, BIND_AUTO_CREATE);            }        });    }}

测试demo,界面很简单,就包含一个button,点击后启动Service。

在自定义ServiceConnection的onServiceConnected()方法中,我们用IMyAidlInterface.stub.asInterface(service)方法在Activity进程中拿到aidl接口。通过调用这个接口中定义的方法,实现进程通信。


打印信息如下:

01-01 00:05:26.211 5474-5474/com.leeee.remoteServer E/lyt: onCreate
01-01 00:05:26.213 5474-5474/com.leeee.remoteServer E/lyt: onBind
01-01 00:05:26.224 5379-5379/com.leeee.aidltest E/lyt: onServiceConnected
01-01 00:05:26.227 5379-5379/com.leeee.aidltest E/lyt: 从Service得到的字符串:我是 Service 返回的字符串


3.总结

1.启动Service时,不能用startService()方法,因为该方法不提供ServiceConnection,不能进行通信;必须用bindService()来启动。

2.IBinder类是Service提供的唯一的通信手段。

3.若要传输数据,需要用Parcelable接口进行序列化和反序列化。若aidl文件中仅包含默认支持的数据类型需要传输,则无需序列化。

4.若某个自定义类需要进行序列化并传输,需要在定义类时implements Parcelable接口。

5.编写aidl通信的基本逻辑是:在服务端实现AIDL中定义的方法接口的具体逻辑,然后在客户端调用这些方法接口,从而达到跨进程通信的目的。






0 0
原创粉丝点击