知识点-----AIDL(二)简单的aidl实现,自定义实体类

服务端

1、创建实体类:如BookBean,且BookBean要实现Parcelable接口,且要手动添加readFromParcel方法(不然只支持 in 的定向tag)

/**
 * 实现序列化的实体类
 * <p>
 * 序列化:由于不同的进程有着不同的内存区域,且相互之间不能直接访问,
 * 所以我们必须将要传输的数据转化为能够在内存之间流通的形式,这个转换的过程就是序列化和反序列化
 */
public class BookBean implements Parcelable {

    private String name;
    private int price;

    protected BookBean(Parcel in) {
        name = in.readString();
        price = in.readInt();
    }

    public BookBean() {
    }

    public BookBean(String name, int price) {
        this.name = name;
        this.price = price;
    }

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

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "BookBean{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

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

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

    /**
     * 该方法不是Parcelable自动生成的,需要自己手动添加,
     * 如果不添加,则在使用AIDL时只支持 in 的定向tag
     * 如果添加了,则支持 in、out、inout
     *
     * @param dest 参数是一个Parcel,用它来存储与传输数据
     */
    public void readFromParcel(Parcel dest) {
        name = dest.readString();
        price = dest.readInt();
    }

}

2、修改gradle:修改项目内部gradle,在android{} 里添加设置代码路径,在AS中默认的java代码路径是java包目录下,这样aidl包下的java代码系统就会找不到,会包Symbol not found

android {
    defaultConfig {……}
    buildTypes {……}

    //在AS中默认的java代码路径是java包目录下,这样aidl包下的java代码系统就会找不到,会包Symbol not found
    sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }
}

3、创建AIDL文件(需要写两个):,一个是BookBean.aidl,作用是把BookBean.java代码引进aidl,以让其他aidl文件可以访问BookBean.java。另一个是具体的对外接口,如IBookManager.aidl

第一个aidl文件:

// Book.aidl
//第一类AIDL文件
//这个文件的作用是引入了一个序列化对象 Book 供其他的AIDL文件使用
//注意:BookBean.aidl与BookBean.java的包名应当是一样的
package bai.bai.bai.demoaidlservice;

//注意 parcelable 必须是小写
parcelable BookBean;

第二个aidl文件:

// BookManager.aidl
//第二类AIDL文件
//作用是定义方法接口
package bai.bai.bai.demoaidlservice;

//导入所需要使用的非默认支持数据类型的包
import bai.bai.bai.demoaidlservice.BookBean;

interface IBookManager {
    //所有的返回值前都不需要加任何东西,不管是什么数据类型
    List<BookBean> getBooks();

    //Java基本类型以及String,CharSequence的 tag 默认且只能是 in
    //传参时除了Java基本类型以及String,CharSequence之外的类型
    //都需要在前面加上定向tag,具体加什么量需而定
    void addBook(in BookBean book);
}


4、创建服务:类似add功能的aidl里服务

public class BookService extends Service {

    private List<BookBean> mBooks = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        mBooks.add(new BookBean("我是第一本", 11));
    }

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

    IBookManager.Stub mBinder = new IBookManager.Stub(){

        @Override
        public List<BookBean> getBooks() throws RemoteException {
            return mBooks;
        }

        @Override
        public void addBook(BookBean book) throws RemoteException {
            mBooks.add(book);
        }
    };

}

5、启动服务,调用方法

public class BookActivity extends AppCompatActivity {

    private IBookManager mService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_book);

        aboutService();

        findViewById(R.id.btn_book_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = ((EditText) findViewById(R.id.et_book_name)).getText().toString();
                int price = Integer.parseInt(((EditText) findViewById(R.id.et_book_price)).getText().toString());
                try {
                    mService.addBook(new BookBean(name, price));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

                try {
                    Log.d("baibai", "服务端:添加后的book列表长度:" + mService.getBooks().size());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

    }

    private void aboutService() {
        Intent intent = new Intent(this, BookService.class);
        bindService(intent, mConn, Context.BIND_AUTO_CREATE);
    }

    ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("baibai", "服务端:book 连接 Service 成功");
            mService = IBookManager.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
}

客户端

1、创建实体类:要跟服务端的包名一样(不然会找不到类)。
2、修改gradle:类似服务端(设置编译代码路径)
3、aidl移植:把服务端的aidl文件复制到客户端的aidl的包下。
4、启动服务、调用方法:类似服务端

参考git代码:服务端:https://github.com/baiyun1234/DemoAidlService

                     客户端:https://github.com/baiyun1234/DemoAidlClient

参考网址:https://blog.csdn.net/guanhang89/article/details/51386404

                  https://blog.csdn.net/luoyanglizi/article/details/51980630

猜你喜欢

转载自blog.csdn.net/qq_36968707/article/details/86087593