当前位置: 移动技术网 > 移动技术>移动开发>Android > Aidl进阶 ----- 自定义类型传输

Aidl进阶 ----- 自定义类型传输

2020年08月14日  | 移动技术网移动技术  | 我要评论
2020.8.7 第一次编辑。。。未完待续。。。package com.zhouxi.client;import androidx.appcompat.app.AppCompatActivity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import a.

2020.8.7 第一次编辑。。。未完待续。。。 

2020.8.11 第二次编辑。。。未完待续。。。

2020.8.12 第三次编辑。。。未完待续。。。

本片文章的目录结构如下:

AidlParcelableDemo
   |--client                                    
   |     |--src
   |     |   |--main
   |     |        |--aidl
   |     |        |    |--com.zhouxi.client
   |     |        |            |--IAidlService.aidl------------------------(1)
   |     |        |            |--ParcelableInfo.aidl----------------------(2)
   |     |        |--java
   |     |        |    |--com.zhouxi.client
   |     |        |            |--MainActivity.java------------------------(3)
   |     |        |            |--ParcelableInfo.java----------------------(4)
   |     
   |--aidlservice
   |     |--src
   |     |   |--main
   |     |        |--aidl
   |     |        |    |--com.zhouxi.client
   |     |        |            |--IAidlService.aidl-----------------------(5)
   |     |        |            |--ParcelableInfo.aidl---------------------(6)
   |     |        |--java
   |     |        |    |--com.zhouxi.client
   |     |        |            |--AidlService.java------------------------(7)
   |     |        |            |--ParcelableInfo.java---------------------(8)

                              AidlParcelableDemo目录结构

上一篇文章介绍了 AIDL的基础知识,通过样例代码展示了AIDL的执行过程----两个apk之间通过AIDL接口传递数据,也就是通信,但是上文中传递的数据主要是基本数据类型。实际上AIDL也支持传递其他数据类型,例如自定义数据类型,本片文章主要聚焦在自定义数据类型的传递(中间不过度的说明AIDL的原理,不理解的可以先看上一篇文章),先上client的代码。

package com.zhouxi.client;

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;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.bindAidlService).setOnClickListener(this);
        findViewById(R.id.unbindAidlService).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.bindAidlService) {
            Intent intent = new Intent();
            intent.setAction("com.zhouxi.service.AidlService");
            intent.setPackage("com.zhouxi.service");
            bindService(intent, aidlServiceConnection, Context.BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.unbindAidlService) {
            Log.e(TAG, "onClick: unbindAidlService");
            unbindService(aidlServiceConnection);
        }
    }

    public ServiceConnection aidlServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ParcelableInfo inParcelableInfo = new ParcelableInfo("这是一条传入的自定义类型");
            Log.e(TAG, "onServiceConnected: bind AidlService success.");
            IAidlService aidlService = IAidlService.Stub.asInterface(service);
            try {
                Log.e(TAG, "onServiceConnected: the info of AidlService: " + aidlService.getServiceInfo(inParcelableInfo).getInfo());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "onServiceConnected: bind AidlService fail.");
        }
    };
}

该apk定义了两个按钮用来绑定和解绑AidlService,在绑定成功后,AidlService会返回自身的代理类,也就是 

IAidlService aidlService = IAidlService.Stub.asInterface(service);

 获取到代理类后就可以通过AIDL接口访问AidlService中的数据了(具体还要看接口实现),查看aidl文件,IAidlService定义了getServiceInfo方法,传入ParcelableInfo的自定义数据类型,返回值也是该类型,在这先把这个数据类型想象看基本数据类型来理解。

// IAidlService.aidl
package com.zhouxi.client;

import com.zhouxi.client.ParcelableInfo;

interface IAidlService {
    ParcelableInfo getServiceInfo(in ParcelableInfo inParcelableInfo);
}

查看AidlService中对于这个接口的具体实现 

package com.zhouxi.client;

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

import androidx.annotation.Nullable;

public class AidlService extends Service {
    private static final String TAG = AidlService.class.getSimpleName();

    @Override
    public void onCreate() {
        Log.e(TAG, "onCreate: AidlService is onCreate.");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand: AidlService is onStartCommand.");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy: AidlService is onDestroy.");
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind: AidlService is onBind.");
        return new AidlBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "onUnbind: AidlService is onUnbind.");
        return super.onUnbind(intent);
    }

    class AidlBinder extends IAidlService.Stub {
        @Override
        public ParcelableInfo getServiceInfo(ParcelableInfo inParcelbleInfo) {
            Log.e(TAG, "the inParcelbleInfo is: " + inParcelbleInfo.getInfo());
            inParcelbleInfo.setInfo("这是一条传出的自定义类型");
            return inParcelbleInfo;
        }
    }
}

可以看出,AidlService中实现了IAidlService的接口方法,将入参inParcelbleInfo的字段修改成别的信息并输出,整个apk间的调用关系就结束了,接下来聚焦如何实现自定义类型通过AIDL接口传递

首先新建自定义类型ParcelableInfo同时实现Parcelable接口,IDE会自动提示实现并覆盖Parcelable接口的方法

设置ParcelableInfo所需要的字段和方法即可

从上面可以看出,用来AIDL接口传递的自定义类型生成很简单,新建类--实现类中的功能--实现Parcelable接口--Alter+Enter自动实现接口方法即可

package com.zhouxi.client;

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

public class ParcelableInfo implements Parcelable {
    private String info;

    public ParcelableInfo(String info) {
        this.info = info;
    }

    protected ParcelableInfo(Parcel in) {
        info = in.readString();
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    /**
     * 反序列化
     */
    public static final Creator<ParcelableInfo> CREATOR = new Creator<ParcelableInfo>() {
        @Override
        public ParcelableInfo createFromParcel(Parcel in) {
            return new ParcelableInfo(in);
        }
        @Override
        public ParcelableInfo[] newArray(int size) {
            return new ParcelableInfo[size];
        }
    };

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

    /**
     * 序列化过程
     *
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(info);
    }
}

对于自定义类型,还需要与之相对应的aidl文件来声明,具体如下,只需要简单的声明声明parcelable类型以及自定义类型名字ParcelableInfo即可,两个aidl文件都需要放置在aidl文件夹下面,同时要保证client和service的包名保持一致。

// ParcelableInfo.aidl
package com.zhouxi.client;

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

parcelable ParcelableInfo;

需要了解更多的,可以之前写的aidl入门文章

 

 

 

本文地址:https://blog.csdn.net/weixin_48968045/article/details/107853418

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网