AndroidStudio AIDL 详细步骤

AIDL (Android Interface Definition Language)即Android接口定义语言。

最近在看Binder的原理,Android里面AIDL就是Binder的经典实现,先记录一下AIDL的使用步骤。

1 服务端Service

1.1 使用AndroidStudio创建aidl文件

然后弹出一个让你修改文件名的页面,文件名自己随便取

点Finish以后aidl文件目录如下图:

然后打开aidl文件夹目录并打开刚刚创建的 OperateNumInterface.aidl 文件:

其中NumBean是自己新建的一个java类,目录如下

NumBean一定要实现 Parcelable接口,完整代码如下

package com.sz.aidl_service_demo;

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

public class NumBean implements Parcelable {

    private String extraInfo;
    private int num1;
    private int num2;


    public NumBean(int num1, int num2, String extraInfo) {
        this.num1 = num1;
        this.num2 = num2;
        this.extraInfo = extraInfo;
    }

    protected NumBean(Parcel parcel) {
        num1 = parcel.readInt();
        num2 = parcel.readInt();
        extraInfo = parcel.readString();
    }

    public String getExtraInfo() {
        return extraInfo;
    }

    public void setExtraInfo(String extraInfo) {
        this.extraInfo = extraInfo;
    }

    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }

    public static final
    Creator<NumBean> CREATOR = new Creator<NumBean>() {

        @Override
        public NumBean createFromParcel(Parcel source) {
            return new NumBean(source);
        }

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(num1);
        dest.writeInt(num2);  
        dest.writeString(extraInfo);
    }
}
然后在aidl文件夹下创建NumBean.adil文件,内容如图

这时候你需要rebulid一下项目,用来生成OperateNumInterface.java文件,build成功以后会有如下目录:

​​

1.2 创建Service实现类

创建一个类实现Service,位置目录如下

OperateNumService.java详细代码:

package com.sz.aidl_service_demo;

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

import androidx.annotation.Nullable;

public class OperateNumService extends Service {

                          注释1:一定要先ReBuild项目,否则找不到OperateNumInterface  
    private IBinder iBinder = new OperateNumInterface.Stub() {

        @Override
        public int operateNum(NumBean numBean) throws RemoteException {
                注释2:还记得aidl文件中我们自己定义的方法么,具体实现在这里
            Log.i("tag", "num1=" + numBean.getNum1() + ",num2=" + numBean.getNum2() + ",ExtraInfo=" + numBean.getExtraInfo());
            return numBean.getNum1() + numBean.getNum2();//我是将NumBean中两个数的和返回
        }
    };


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

然后别忘了在Mainfest文件中声明Service:

        <service android:name=".OperateNumService">
            <intent-filter>
                <action android:name="com.aidl_service_demo.my_flag" />
            </intent-filter>
        </service>

到这里服务端就写好了。

2 客户端Client

2.1 将服务端的aidl文件夹整个直接复制到Client目录中

2.2 新建NumBean类

注意,NumBean类的目录要和Service端的目录结构一样

注意,你需要ReBuild项目一下

2.3 绑定Service及发送数据接收返回结果

这些操作都是在MainActivity 中进行,代码如下:

import androidx.appcompat.app.AppCompatActivity;

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 android.widget.TextView;

import com.sz.aidl_service_demo.NumBean;
import com.sz.aidl_service_demo.OperateNumInterface;

public class MainActivity extends AppCompatActivity {

    private TextView tv_operate_num_result;
    private int operateResult = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_operate_num_result = findViewById(R.id.tv_operate_num_result);
    }
    
    注释1:按钮1 绑定Service
    public void bindService(View view) {
        Intent intentBind = new Intent();
        intentBind.setAction("com.aidl_service_demo.my_flag");
        intentBind.setPackage("com.sz.aidl_service_demo");
        bindService(intentBind, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    注释2:按钮2 向Service发送数据并接收返回数据展示
    public void sendService(View view) {
        NumBean numBean = new NumBean(160, 8, "i'm extra info");
        if (operateNumInterface != null) {
            try {
                operateResult = operateNumInterface.operateNum(numBean);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        tv_operate_num_result.setText("Service 返回操作结果为: " + operateResult);
    }

    private OperateNumInterface operateNumInterface;
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i("tag", "onServiceConnected");
            注释3: 
            operateNumInterface = OperateNumInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            operateNumInterface = null;
        }
    };


}

1 先点击绑定Service按钮,此时客户端打印日志如下:

2 再点击 发送数据到Service 按钮

Service端日志如下:

Client端界面展示如下:

猜你喜欢

转载自blog.csdn.net/u011288271/article/details/111173368