进程间通信 - AIDL

andriod 提供的进程间通信方式为AIDL,其中实现的原理就不说了。现在我们有两个进程A进程和B进程,A进程可以提供数据,而B进程获取数据。

A进程(发送)  ->  B进程 (获取)

A进程提供数据

整个A进程,如果我们想要给其他进程提供数据的化,我们就需要三个角色才能完成。

IWorkAidl.aidl - 文件,说一个接口,定义能提供的方法 (当编译的时候,该文件的序列化等操作,都说系统自动生成的)

WorkAidl.class - 此类需要继承aidl文件,实现aidl文件中声明的方法

WorkAidlService.class - 继承Service的服务类,在oBind()方法中返回WorkAidl的实体;这个服务开着,其他进程就可以通过这个服务获取Binder对象。

B进程获取数据

通过绑定服务的方式,获取发送进程的binder对象,然后调用其中的方法。

第一步:创建一个aidl文件(这个包名很重要,当B进程也创建aidl文件的时候,也必须是这个包名)

在com.malei.demo包下,我们来创建对外提供服务的aidl文件,MyIWorkAidl.aidl文件

interface MyIWorkAidl {
    String getName();
    void setName(String name);
}

以上就创建了一个aidl文件,可以看到这是一个接口类,当我们编译的时候,我们发现他会自动的创建一个java文件接口类,继承了

android.os.IInterface类,同时内部也提供类一个名字叫Stub的内部类,这个内部类继承了Binder,同时实现了MyIWorkAidl接口。

同时这个内部类Stub是一个抽象的方法,其中接口的方法并没有实现,而是让继承的子类去实现。

第二步:创建Stub的子类

/**
 * Created by malei on 2018/6/22.
 */
public class MyWorkAidl extends MyIWorkAidl.Stub {
    private String name;

    @Override
    public String getName() throws RemoteException {
        return name;
    }

    @Override
    public void setName(String name) throws RemoteException {
        this.name = name;
    }
}

第三步:创建一个服务,提供其他进程一个binder对象。

/**
 * Created by malei on 2018/6/22.
 */
public class MyWorkAidlService extends Service{

    private MyIWorkAidl.Stub stub = new MyWorkAidl();

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

创建的服务还需要在注册文件中进行注册处理,如下:

<service android:name=".aidl.MyWorkAidlService" >
    <intent-filter >
        <action android:name="forServiceAidl" > </action>
    </intent-filter>
</service>

第四步:启动该aidl的服务

我们在oncreate()中通过绑定服务的方式启动该服务,然后将值赋值到binder中,如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    bindService(new Intent("forServiceAidl"), conn, Service.BIND_AUTO_CREATE);
    setContentView(R.layout.activity_main);
}

private ServiceConnection conn = new ServiceConnection() {
    // 断开连接时调用
    @Override
    public void onServiceDisconnected(ComponentName arg0) {
    }
    // 连接时调用
    @Override
    public void onServiceConnected(ComponentName arg0, IBinder binder) {
        mMyAIDL = MyIWorkAidl.Stub.asInterface(binder);
        if (mMyAIDL != null) {
            try {
                mMyAIDL.setName("Service AIDL");
                Toast.makeText(MainActivity.this, "赋值成功!", Toast.LENGTH_LONG).show();
            } catch (RemoteException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "赋值失败!", Toast.LENGTH_LONG).show();
            }
        }
    }
};

这样a进程要做的事情就都完成了

第五步:B进程获取数据,先创建一个aidl文件(这个包名要和A进程的aidl包名相同才行):

interface MyIWorkAidl {
    String getName();
    void setName(String name);
}

然后通过绑定服务的方式获取A进程的binder对象。

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

    bindService(new Intent("forServiceAidl"), conn, Service.BIND_AUTO_CREATE);
    this.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(mMyWorkAidl != null){
                try {
                    //RPC方法调用
                    String name = mMyWorkAidl.getName();
                    Toast.makeText(MainActivity.this, "远程进程调用成功!值为 : "+name, Toast.LENGTH_LONG).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this, "远程进程调用失败! ", Toast.LENGTH_LONG).show();
                }
            }
        }
    });
}

private MyIWorkAidl mMyWorkAidl;
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        Toast.makeText(MainActivity.this, "远程进程调用失败! ", Toast.LENGTH_LONG).show();
    }
    //因为有可能有多个应用同时进行RPC操作,所以同步该方法
    @Override
    public synchronized void onServiceConnected(ComponentName arg0, IBinder binder) {
        //获得IPerson接口
        Toast.makeText(MainActivity.this, "远程进程调用成功! ", Toast.LENGTH_LONG).show();
        mMyWorkAidl = MyIWorkAidl.Stub.asInterface(binder);
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值