Android IPC 进程间通信机制之 AIDL

从事 Android 开发也跨过了1年的时间了,在之前的工作、开发中,功能实现、第三方框架使用、Copy 网上的代码占据了我的大部分开发时间。学着学着就开始发现个人的综合能力并没有得到有效的提升,虽然大部分的功能都能通过查找来实现,但离开里网络、或者说涉及到底层实现就真的有点懵逼了。经验的积累很重要,个人的学习充电更为重要。

对于 Android 开发来说,进程间的通信是一门大课。总会有许许多多的场景让你需要使用到它。Android 中是不允许跨进程之间直接调用对方的资源的。而AIDL 是帮助我们跨进程进行通信的方式之一。AIDL是 Android Interface definition language 的简称。通过名字就能知道,它是一种跨进程间的接口定义语言,类似网络请求的 C(客户端)/S(服务器端)。 通过它我们可以定义跨进程的接口使用。 下面我们来看看如何简单的使用 AIDL 来实现进程间通信。

1、创建 AIDL 文件来创建我们的服务端。在 app 包下创建一个 aidl 包,在包内创建一个与项目包名一致的子包。并在子包中创建一个 IBookAidl.aidl 文件


在这个 IBookAidl.aidl 文件中有 getBooks() addBook()方法。

package com.mrj.zy.multiprocessdemo;
import com.mrj.zy.multiprocessdemo.Book;
interface IBookAidl {
    List<Book> getBooks();//获取所有的书籍
    void addGame(in Book book);//添加书籍
}
由于在  IBookAidl.aidl 中我们使用了 Book 这个类,它实现了 Parcelable 。所以我们应该再创建一个 Book.aidl :

package com.mrj.zy.multiprocessdemo;
parcelable Book;

2、在项目中创建一个 AidlService (服务端)继承自 Service 来实现 aidl 文件中的方法。

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class AidlService extends Service{
    //初始化书籍集合
    private CopyOnWriteArrayList<Book> books=new CopyOnWriteArrayList<>();
    
    //通过Aidl的Stub内部类实现跨进程接口 来获得一个Binder对象
    private Binder mBinder=new IBookAidl.Stub() { 
        @Override
        public List<Book> getBooks() throws RemoteException {
            return books;
        }

        @Override
        public void addGame(Book book) throws RemoteException {
            books.add(book);
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        books.add(new Book("Android 从入门到放弃","就是这么神奇的入门与放弃学"));
        books.add(new Book("Http 协议","很难的一个知识点啊"));
    }

    @Override
    public IBinder onBind(Intent intent) {
        //返回的就是我们从跨进程中获取的Binder对象
        return mBinder;
    }
}
3、在客户端进程中绑定服务端,将得到的 Binder 对象转换为 AIDL 接口,这样我们就可以在我们的进程中调用 Aidl 接口中的方法了。
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.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;


public class AidlActivity extends AppCompatActivity {

    @BindView(R.id.first_number)
    EditText firstNumber; //书名
    @BindView(R.id.second_number)
    EditText secondNumber; //内容
    @BindView(R.id.add_for_result)
    Button addForResult; //添加书籍

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);
        ButterKnife.bind(this);
    }
    //初始化一个ServiceConnection对象并且重写里面的方法
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //通过IBinder对象得到一个跨进程的AIDL对象
            IBookAidl iBookAidl = IBookAidl.Stub.asInterface(service);
            //新建一本书
            Book book = new Book(firstNumber.getText().toString(), secondNumber.getText().toString());
            
            try {
                //通过调用 AIDL 的方法添加书籍
                iBookAidl.addGame(book);
                //遍历书籍 并且打印出每本书的名字与内容
                for (Book b:iBookAidl.getBooks()) {
                    
                    Log.d("RJie", "书名: "+b.bookName+"  简介 :"+b.bookDescribe);
                    
                }
                
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @OnClick(R.id.add_for_result)
    public void onClick() {
        //与服务端进行绑定
        Intent aidlIntent = new Intent(this, AidlService.class);

        bindService(aidlIntent,connection, Context.BIND_AUTO_CREATE);
        
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        unbindService(connection);//解绑服务端
        
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <EditText
        android:id="@+id/first_number"
        android:hint="请输入书名"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/second_number"
        android:hint="请输入简介"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/add_for_result"
        android:text="相加"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />



</LinearLayout>

还有 Book 这个实体类:

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

public class Book implements Parcelable {
    public String bookName;
    public String bookDescribe;

    public Book(String bookName, String bookDescribe) {
        this.bookName = bookName;
        this.bookDescribe = bookDescribe;
    }

    protected Book(Parcel in) {
        bookName = in.readString();
        bookDescribe = in.readString();
    }

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

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

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

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

这样一个大体的使用 AIDL 来实现跨进程通信的例子就完成了。



 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值