IPC机制之AIDL传递基础类型数据(一)

IPC机制之Messenger示例(二)

IPC机制之AIDL传递Parcelable(三)

IPC机制之AIDL实现客户端回调(四)

Q:为什么标题是基础类型呢?

  • 这个需要我简单介绍下,在Binder基础上的IPC通信主要分为Messenger和AIDL,Messenger的本质也是AIDL,所以我们需要知道AIDL支持传递哪些类型的数据,见下图。

这里写图片描述

图片来自任玉刚的《Android开发艺术探索》

Q:Messenger和AIDL的区别?

  1. Messenger底层也是AIDL,只是屏蔽了其细节;
  2. 服务端的Messenger是串行的方式执行客户端发来的消息,说明即使在有并发的情况下,Messenger也会一个个执行,而AIDL我们可以自己去处理并发;
  3. Messenger主要是传递消息,但我们时常需要跨进程调用方法;

如果需要了解Messenger传递消息可以查看 IPC机制之Messenger示例。

Show me the code.

Client#IMyAidlInterface.aidl

package com.aidl.wzf.aidl;

interface IMyAidlInterface {
   int add(int num1,int num2);
}

Client#MainActivity.java

package com.aidl.wzf.aidl;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private IMyAidlInterface aidlInterface;
    private Button btnCalc;
    private TextView tvResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnCalc = (Button) findViewById(R.id.btn_calc);
        tvResult = (TextView) findViewById(R.id.tv_result);
        btnCalc.setOnClickListener(this);
        bindService();
    }

    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.aidl.wzf.aidl", "com.aidl.wzf.aidl.IRemoteService"));
        this.bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            aidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
            try {
                // 绑定远程服务死亡代理,如果远程服务有断开,将会在binderDied中有回调
                iBinder.linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            aidlInterface = null;
        }
    };

    IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (aidlInterface == null) return;
            aidlInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);
            aidlInterface = null;
            // 重新绑定
            bindService();
        }
    };

    @Override
    public void onClick(View view) {
        try {
            int mTotal = aidlInterface.add(2, 5);
            tvResult.setText("" + mTotal);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

Server#IMyAidlInterface.aidl

package com.aidl.wzf.aidl;

interface IMyAidlInterface {
    int add(int num1,int num2);
}

Server#IRemoteService.java

package com.aidl.wzf.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

public class IRemoteService extends Service {

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

    private IBinder iBinder = new IMyAidlInterface.Stub() {

        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.i("info", "触发服务端");
            return num1 + num2;
        }
    };
}

AndroidManifest

 <service
     android:name=".IRemoteService"
     android:exported="true"
     android:process=":remote" />

注意:
1. 服务端和客户端是2个Module;
2. 服务端和客户端的.aidl文件的包名必须相同;
3. Manifest中的Service必须设置 android:exported=”true”以保证允许其他组件调用,适用于四大组件;
4. 如果已经确定了Servcer和Client在不同进程,可以删除 android:process=”:remote”属性。

源码下载

猜你喜欢

转载自blog.csdn.net/u010259369/article/details/74393053