AIDL简介

AIDL即Android接口描述语言,用于跨进程之间的数据通信。关于其详细的信息可以网上搜,相关内容还是蛮多的。

基本类型的AIDL

AIDL支持的6中基本类型
byte,double,float,int,long,String
现在我们来实现AIDL的方法吧
1.实现*.aidl文件
IAIDLTest.aidl

   package com.pachongzhang.myservice;interface IAIDLTest {    int add(int a, int b);}

aidl文件的生成与一个接口类(interface)类的实现差不多,首先声明其所在的包名,然后定义其接口类,只是少了public,private这些属性,并且其支持的类型比较少。那我们要实现自定义类用于参数传递,我们就需要让自定义类实现Parcelable接口。下面我们来看下自定义类的AIDL的实现。

自定义类的AIDL

自定义类实现Parcelable,我们需要创建两个文件,.java和.aidl,下面举一个具体的实例。
CustomParcelable.java

   package com.pachongzhang.myservice;import android.os.Parcel;import android.os.Parcelable;public class CustomParcelable implements Parcelable {    private int a;    private String b;    public CustomParcelable(Parcel source) {        this.a = source.readInt();        this.b = source.readString();    }    public CustomParcelable(int a, String b) {        this.a = a;        this.b = b;    }    public int getA() {        return a;    }    public void setA(int a) {        this.a = a;    }    public String getB() {        return b;    }    public void setB(String b) {        this.b = b;    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(a);        dest.writeString(b);    }    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {        @Override        public CustomParcelable createFromParcel(Parcel source) {            return new CustomParcelable(source);        }        @Override        public CustomParcelable[] newArray(int size) {            return new CustomParcelable[size];        }    };}

CustomParcelable.aidl

   package com.pachongzhang.myservice;parcelable CustomParcelable;

从CustomParcelable.java可知其主要用于自定义类的实现方法,CustomParcelable.aidl用于其在AIDL的声明,那么我们要怎么样才能使用这个自定义类呢。
IAIDLTest.aidl

   package com.pachongzhang.myservice;import com.pachongzhang.myservice.CustomParcelable;interface IAIDLTest {    int add(int a, int b);    void getCustom(in CustomParcelable custom);}

从代码中我们可以看到IAIDLTest.aidl文件多了import com.pachongzhang.myservice.CustomParcelable;一个这样的声明,这个就是我们自己定义的那个类,有了这个声明我们就可以在.aidl文件中使用CustomParcelable这个类了,同时要注意的两点就是我们定义了CustomParcelable.java文件还是声明其CustomParcelable.aidl文件,其次是做为参数传递时要声明其是in还是out的方式表示其是输入参数还是输出参数。
说了这么多,我们看下具体的使用吧

AIDL的实践

Service端

首先,我们看service端的实现
代码结构

从Myservice的结构中,我们已经实现了CustomParcelable.java,CustomParcelable.aidl和IAIDLTest.aidl,下面我就看下MyService.java和AndroidManifest.xml。
MyService.java

   package com.pachongzhang.myservice;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class MyService extends Service{    protected static final String TAG = "MyService";    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    private Binder mBinder = new IAIDLTest.Stub() {        @Override        public int add(int a, int b) throws RemoteException {            return (a+b);        }        @Override        public void getCustom(CustomParcelable custom) throws RemoteException {            Log.d(TAG,"getCustom:"+custom.getA()+",getB:"+custom.getB());        }    };    @Override    public void onDestroy() {        mBinder = null;    }}

从MyService.java中我们可以看到我们实现了IAIDLTest.Stub()类,这个类就是用于接口数据传递及其实现,可以看到我们实现了add和getCustom方法。然后通过onBind把IAIDLTest.Stub()对象传递给别的进程,已使其调用MyService 里的方法。我们定义了服务自然而然就要在AndroidManifest.xml中声明。
AndroidManifest.xml

   <?xml version="1.0" encoding="utf-8"?>                                                                   

可以看到我们声明了MyService服务,并定义了一个action=”com.pachongzhang.myservice.MyService.start”方便别的进程启动本服务。下面来看下Client端访问本服务的方法。

Client端

Client端的代码结构

从结构中我们知道,我们要把那些接口类都搬过来,如果使用了自定义类,还要把自定义的类的java和aidl文件搬过来。所以这么我们就只需要看下MainActivity.java和activity_main.xml的实现了。先来看下Client端实现的效果吧。

这里我们通过调用Service的add方法实现了加法运算。并且通过getCustom打印了对应的信息

效果看过后我们看MainActivity.java和activity_main.xml的实现吧。
activity_main.xml

                   

MainActivity.java

   package com.pachongzhang.myclient;import com.pachongzhang.myservice.CustomParcelable;import com.pachongzhang.myservice.IAIDLTest;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;public class MainActivity extends Activity implements OnClickListener {    private static final String SERVICE_START = "com.pachongzhang.myservice.MyService.start";    private EditText mEditNum1;    private EditText mEditNum2;    private EditText mEditNum3;    private Button mBtnEqual;    private IAIDLTest mService;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        bindService(true);    }    @Override    protected void onDestroy() {        bindService(false);        super.onDestroy();    }    private void bindService(boolean isBind){        if (isBind) {            Intent intent = new Intent(SERVICE_START);            bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);        } else {            if (mServiceConnection != null) {                unbindService(mServiceConnection);                mServiceConnection = null;            }        }    }    private void initView() {        mEditNum1 = (EditText) findViewById(R.id.id_edit_num1);        mEditNum2 = (EditText) findViewById(R.id.id_edit_num2);        mEditNum3 = (EditText) findViewById(R.id.id_edit_num3);        mBtnEqual = (Button) findViewById(R.id.id_btn_equal);        mBtnEqual.setOnClickListener(this);    }    private ServiceConnection mServiceConnection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            mService = null;        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            mService = IAIDLTest.Stub.asInterface(service);        }    };    @Override    public void onClick(View v) {        if (v.getId() == R.id.id_btn_equal) {            int num1 = Integer.valueOf(mEditNum1.getText().toString());            int num2 = Integer.valueOf(mEditNum2.getText().toString());            try {                int num3 = mService.add(num1, num2);                mEditNum3.setText(num3+"");                CustomParcelable customParcelable = new CustomParcelable(num3, "Success");                mService.getCustom(customParcelable);            } catch (RemoteException e) {                e.printStackTrace();            }        }    }}

MainActivity.java的实现也是比较简单的,就简单介绍下,通过bindService获得远程服务的binder,然后通过它就可以调用那些接口了。

Android自定义类序列化

Android序列化一般是用于对象的传递的,因为在Android中一些自定义类对象是不能直接传递的,需要序列化。那我们来看看有哪些序列化的方式,Serializable是java提供的,Parcelable是Android提供的,相对来说Serializable的实现要简单很多,但Parcelable的效率要比Serializable高,可以参考这篇文章Android系统中Parcelable和Serializable的区别。下面我们来看下Parcelable和Serializable的简单实现。

Parcelable

MyParcelable.java

   import android.os.Parcel;import android.os.Parcelable;public class MyParcelable implements Parcelable{    private int a;    private String b;    public MyParcelable(Parcel source) {        this.a = source.readInt();        this.b = source.readString();    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(a);        dest.writeString(b);    }    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {        @Override        public MyParcelable createFromParcel(Parcel source) {            return new MyParcelable(source);        }        @Override        public MyParcelable[] newArray(int size) {            return new MyParcelable[size];        }    };}

Serializable

MySerializable.java

   import java.io.Serializable;public class MySerializable implements Serializable {    private static final long serialVersionUID = 6285493298229159093L;    private int a;    private String b;}

从上面两个简单类里我们可以看出Parcelable要比Serializable 复杂的多,但是效率上正好相反。所以在使用上还是推荐使用Parcelable。

更多相关文章

  1. 如何将Eclipse中的项目迁移到Android(安卓)Studio 中
  2. Android(安卓)init.rc文件解析过程详解
  3. React-native 开发之: 安卓(android) app 打签名包
  4. Android中背光系统架构
  5. Android(安卓)Studio如何自动 import
  6. 导入已有工程和更换工作空间
  7. android JNI 使用 for mac
  8. ubuntu+ndk编译ffmpeg
  9. PC 与 Android(安卓)的adb同步通信(一)

随机推荐

  1. Android(安卓)从代码中打开淘宝和亚马逊
  2. Android学习之表格布局管理器
  3. Android桌面小部件实例 桌面小时钟
  4. How C/C++ Debugging Works on Android
  5. Android监听手机网络变化
  6. 使用Scala开发Android
  7. Android(安卓)Adapter详解
  8. Android(安卓)学习笔记--android——Acti
  9. Android的AnimationSet动画实现图片的轮
  10. Android好文章