android aidl的使用及demo

demo下载地址

https://download.csdn.net/download/u010672559/10610856

----------

概述:AIDL即跨进程通信 

1.在main下面新建aidl文件
// IMyAidlInterface.aidl
package com.android.aidl;

// Declare any non-default types here with import statements
import com.android.aidl.bean.Person;
interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void addPerson(in Person person);
}
注意:如果addPerson(in Person person)不需要传Parcelable类型的Person对象,则不需要相应的Person.aidl文件及导包操作
“AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据就需要做更一步处理。AIDL服务支持的数据类型如下:
Java的简单类型(int、char、boolean等)。不需要导入(import)。
String和CharSequence。不需要导入(import)。
List和Map。但要注意,List和Map对象的元素类型必须是AIDL服务支持的数据类型。不需要导入(import)。
AIDL自动生成的接口。需要导入(import)。
实现android.os.Parcelable接口的类。需要导入(import)。
其中后两种数据类型需要使用import进行导入,将在本章的后面详细介绍。
传递不需要import的数据类型的值的方式相同。传递一个需要import的数据类型的值(例如,实现android.os.Parcelable接口的类)的步骤略显复杂。除了要建立一个实现android.os.Parcelable接口的类外,还需要为这个类单独建立一个aidl文件,并使用parcelable关键字进行定义。”
2.如果是带实体且类型为Person implements Parcelable类型的则注意需要相应aidl新建实体的aidl文件,且注意导包
---------------
// Person.aidl
package com.android.aidl.bean;

//还要和声明的实体类在一个包里
parcelable Person;
-----------
package com.android.aidl.bean;

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {
    private String mName;

    public Person(String name) {
        mName = name;
    }

    protected Person(Parcel in) {
        mName = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
    }

    @Override
    public String toString() {
        return "Person{" +
                "mName='" + mName + '\'' +
                '}';
    }
}
------------------
结构如下图所示

android aidl的使用及demo_第1张图片

3.之后make project则会生成app\build\generated\source\aidl\debug\com\android\yxz\aidltest03\IMyAidlInterface.java文件,如果没有生成则会编译报错,根据相应的错误提示修改即可

android aidl的使用及demo_第2张图片

4.之后将main下面的aidl文件拷贝到另一个工程下面,确保包名类名一致,然后同样make project生成相应的java文件
5.之后再工程A中启动工程B的bindservice,在工程A的ServiceConnection mConnection = new ServiceConnection()回调中可以得到binder,通过binder调用彼此aidl公共定义的方法就能调用到对方的方法了,当进程被杀死的时候会走onServiceDisconnected
---------
工程A
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "xiaozheng";
    private Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt=(Button)findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    Log.d(TAG, "click");
                    mAidl.addPerson(new Person("yxz"));
                }catch (Exception e){
                    e.printStackTrace();
                    Log.d(TAG, "e="+e);
                }
            }
        });
        bindService();
    }
    private void bindService() {
        Intent serverIntent = new Intent();
        serverIntent.setClassName("com.android.yxz.aidltestb", "com.android.yxz.aidltestb.MyAidlService");
        bindService(serverIntent, mConnection, Context.BIND_AUTO_CREATE);
    }
    private IMyAidlInterface mAidl;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
            Log.d(TAG, "onServiceConnected name="+name);
            mAidl = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected name="+name);
            mAidl = null;
        }
    };
}


---------
工程B的service
public class MyAidlService extends Service {
    public static final String TAG = "xiaozheng";
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyAidlService onCreate");
    }
    private IBinder mIBinder =new IMyAidlInterface.Stub(){

        @Override
        public void addPerson(Person person) throws RemoteException {
            Log.d(TAG, "AidlTestB addPerson person="+person);
        }
    };

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

6.service记得在清单里面注册,且属性里面加以下属性,否则会报错Not allowed to bind to service Intent
    android:exported="true"/>
7.点击button即工程A调用到了工程B的方法,即实现了跨进程通信的目的

你可能感兴趣的:(android)