欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android AIDL使用详解

程序员文章站 2022-06-23 13:39:05
本文章将介绍如何使用AIDL实现客户端与服务端的双向传值,以及如何传递自定义类型对象(AIDL默认支持基础类型传递:int,long,boolean,float,double,String)...

本文将介绍如何使用AIDL实现客户端与服务端的双向传值,以及如何传递自定义类型对象(AIDL默认支持基础类型传递:int,long,boolean,float,double,String)

目录结构:
Android AIDL使用详解

1.定义AIDL文件

IRemoteService.aidl
这些方法会在服务端实现,在客户端调用

// IRemoteService.aidl
package com.tq.demo.aidltest;
import com.tq.demo.aidltest.IMyCallback;
import com.tq.demo.aidltest.MyData;

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

interface IRemoteService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    //获取进程id
    int getPid();

    //注册更新回调
    void registerCallbackListener(in IMyCallback callback);

    //注销更新回调
    void unregisterCallbackListener(in IMyCallback callback);

    //开始计时
    void startTimeCount(int time);
}

IMyCallback.aidl
onReceiveMyData会在客户端实现,用于监听服务端的传值

package com.tq.demo.aidltest;
import com.tq.demo.aidltest.MyData;
// Declare any non-default types here with import statements

interface IMyCallback {

   void onReceiveMyData(in MyData data);
}

MyData.aidl
自定义类型实体,该文件一定要与要传递对象的类同名

package com.tq.demo.aidltest;
parcelable MyData;

定义好以上AIDL文件后,重新构建项目,会自动生成与AIDL文件同名的java类:
Android AIDL使用详解

2.编写服务端代码

class MyService : Service() {
    var i = 0
    val countTime: Long = 100000
    val countInteval: Long = 1000
    private val mRemoteCallbacks = RemoteCallbackList<IMyCallback>()

    private val timer = object : CountDownTimer(countTime, countInteval) {
        override fun onFinish() {}

        override fun onTick(millisUntilFinished: Long) {
            i += 1
            val data = MyData()
            data.time = i
            sendBroadcast(data)
        }
    }

    private val myBinder = object : IRemoteService.Stub() {
        override fun basicTypes(
            anInt: Int,
            aLong: Long,
            aBoolean: Boolean,
            aFloat: Float,
            aDouble: Double,
            aString: String?
        ) {}

        override fun getPid(): Int {
            return android.os.Process.myPid()
        }

        override fun unregisterCallbackListener(callback: IMyCallback?) {
            if (callback != null) {
                mRemoteCallbacks.unregister(callback)
            }
        }

        override fun startTimeCount(time: Int) {
            i = time
            timer.start()
        }

        override fun registerCallbackListener(callback: IMyCallback?) {
            if (callback != null) {
                mRemoteCallbacks.register(callback)
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return myBinder
    }

    // 通过RemoteCallbackList向客户端传递数据
    fun sendBroadcast(data: MyData) {
        val count = mRemoteCallbacks.beginBroadcast()
        for (i in 0 until count) {
            try {
                mRemoteCallbacks.getBroadcastItem(i).onReceiveMyData(data)
            } catch (e: RemoteException) {
                // The RemoteCallbackList will take care of removing
                // the dead object for us.
            }
        }
        mRemoteCallbacks.finishBroadcast()
    }
}

3.编写客户端代码

class MainActivity : AppCompatActivity(), View.OnClickListener, CoroutineScope by MainScope() {
    private var mService: IRemoteService? = null
    private lateinit var tvContent: TextView
    private lateinit var btnBind: Button
    private lateinit var btnUnbind: Button
    private lateinit var btnKill: Button
    private var isBind = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
    }

    fun initView() {
        tvContent = findViewById(R.id.tv_content)
        btnBind = findViewById(R.id.btn_bind)
        btnUnbind = findViewById(R.id.btn_unbind)
        btnKill = findViewById(R.id.btn_kill)

        btnBind.setOnClickListener(this)
        btnUnbind.setOnClickListener(this)
        btnKill.setOnClickListener(this)
    }

    private val mConnection = object : ServiceConnection, IMyCallback.Stub() {
        override fun onServiceDisconnected(name: ComponentName?) {
            mService = null
        }

        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            mService = IRemoteService.Stub.asInterface(service)
            mService?.registerCallbackListener(this)
            mService?.startTimeCount(10)
        }

        override fun onReceiveMyData(data: MyData?) {
            launch(Dispatchers.Main) {
                tvContent.text = data?.time.toString()
            }
        }
    }

    override fun onClick(v: View?) {
        when (v!!.id) {
            R.id.btn_bind -> bind()
            R.id.btn_unbind -> unBind()
            R.id.btn_kill -> kill()
        }
    }

    @SuppressLint("SetTextI18n")
    fun bind() {
        if (isBind) return
        val intent = Intent(this, MyService().javaClass)
        val action = MyService().javaClass.name
        intent.action = action
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
        isBind = true
        tvContent.text = "正在绑定SERVICE"
    }

    @SuppressLint("SetTextI18n")
    fun unBind() {
        if (!isBind) return
        mService?.unregisterCallbackListener(mConnection)
        unbindService(mConnection)
        isBind = false
        tvContent.text = "SERVICE已解绑"
    }

    fun kill() {
        try {
            if (mService != null) {
                android.os.Process.killProcess(mService!!.pid)
            }
            isBind = false
            tvContent.text = "进程已杀死"
        } catch (e: RemoteException) {
            e.printStackTrace()
        }
    }

}

实体类:

class MyData() : Parcelable {

    var time = 0

    constructor(parcel: Parcel) : this() {
        time = parcel.readInt()
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(time)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MyData> {
        override fun createFromParcel(parcel: Parcel): MyData {
            return MyData(parcel)
        }

        override fun newArray(size: Int): Array<MyData?> {
            return arrayOfNulls(size)
        }
    }

    override fun toString(): String {
        return "time = $time"
    }
}

效果
Android AIDL使用详解

本文地址:https://blog.csdn.net/weryoung/article/details/112596097

相关标签: android aidl