android关于binder的简单通信过程

文章目录

  • 简述
  • aidl文件
  • 服务端的实现
  • 客户端的实现
  • 验证过程

简述

主要实现的是两个应用之间跨进程通信的过程,client端调用server端的具体实现,然后server端给client回调数据,详细如下所示

aidl文件

以下的文件需要在服务端与客户端都配置一份且保持一致

1.aidl 跨进程所需要的文件目录如下所示
android关于binder的简单通信过程_第1张图片
以下文件是对应的TestDataBean.aidl文件的
在这里插入图片描述

2.IOnTestDataCallback.aidl文件,用于服务端给客户端回调接口,传递一个parcel类型的数据

// IOnTestDataCallback.aidl
package com.example.test;
import com.example.test.TestDataBean;

// Declare any non-default types here with import statements

interface IOnTestDataCallback {
    void onCallback(in TestDataBean dataBean);
}

3.IOnTestDataListener.aidl文件,用于客户端给服务端请求数据的调用过程,oneway表示异步方法,不用等待方法中的实现执行完成,直接返回就行了。

// IOnTestDataListener.aidl
package com.example.test;
import com.example.test.IOnTestDataCallback;
// Declare any non-default types here with import statements

interface IOnTestDataListener {
    oneway void sendData(String str, in byte[] bytes,in IOnTestDataCallback callback);
}

4.TestDataBean.aidl文件,用于跨进程传递parcel对象数据。

// TestDataBean.aidl
package com.example.test;

parcelable TestDataBean;

5.TestDataBean.java文件,TestDataBean.aidl中的具体实现方式。

package com.example.test;

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

public class TestDataBean implements Parcelable {

    public String getName() {
        return name;
    }

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

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    private String name;
    private int number;


    public TestDataBean() {

    }

    protected TestDataBean(Parcel in) {
        name = in.readString();
        number = in.readInt();
    }

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

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

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

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

服务端的实现

1.TestBinderService.java文件

package com.tencent.wemeet.testwhitelist;

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

import androidx.annotation.Nullable;

import com.example.test.IOnTestDataCallback;
import com.example.test.IOnTestDataListener;
import com.example.test.TestDataBean;

import java.util.Arrays;

public class TestBinderService extends Service {

    private static final String TAG = "TestBinderService";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new IOnTestDataListener.Stub() {
            @Override
            public void sendData(String str, byte[] bytes, IOnTestDataCallback callback) throws RemoteException {
                Log.d(TAG, "str = " + str + ",bytes = " + Arrays.toString(bytes));
                TestDataBean bean = new TestDataBean();
                bean.setName("zhangsan");
                bean.setNumber(20);
                try {
                    Thread.sleep(5000);
                    callback.onCallback(bean);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }
}

2.AndroidManifest.xml文件配置

        <service
            android:name=".TestBinderService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.binder.test.service" />
            </intent-filter>
        </service>

客户端的实现

TestBinderActivity.java文件

package com.example.test;

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.util.Log;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class TestBinderActivity extends AppCompatActivity {

    public static final String TAG = "TestBinderActivity";
    private boolean isBinder;
    private IOnTestDataListener binder;

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

        Intent intent = new Intent();
        intent.setAction("com.binder.test.service");
        intent.setPackage("com.tencent.wemeet.testwhitelist");
        isBinder = bindService(intent, connection, Context.BIND_AUTO_CREATE);

        findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (binder == null) {
                    Log.d(TAG, "binder is null");
                    return;
                }
                Log.d(TAG, "begin");
                try {
                    binder.sendData("123", new byte[]{1, 2, 3}, new IOnTestDataCallback.Stub() {
                        @Override
                        public void onCallback(TestDataBean dataBean) throws RemoteException {
                            Log.d(TAG, "name = " + dataBean.getName() + ",number = " + dataBean.getNumber());
                        }
                    });
                } catch (RemoteException e) {
                    Log.d(TAG, "sendData RemoteException");
                    throw new RuntimeException(e);
                }

                Log.d(TAG, "end");
            }
        });


    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isBinder) {
            isBinder = false;
            unbindService(connection);
            connection = null;
            binder = null;
        }
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");
            binder = IOnTestDataListener.Stub.asInterface(service);

        }

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

验证过程

先打开server端相关的应用进程,之后再打开client端相关的应用进程,然后通过binder的方式连接server端并进行通信,记录大致的通信过程。

你可能感兴趣的:(framework,android,binder,aidl)