AIDL实现应用A和B通信

29 阅读2分钟

1.新建B工程即服务端apk

1.新建aidl文件

image.png 若无法直接新建AIDL文件,则需要在app的build.gradle中加入配置:

image.png

编写代码:

image.png

📢注意:aidl文件建完编写好后需要重新rebuild,否则使用时找不到

2.创建远程service服务

package com.example.myaidldemo2;

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

public class MyService extends Service {
    IMyAidlInterface.Stub myIBinder=new IMyAidlInterface.Stub(){
        private String txt;

        @Override
        public void sendMsg(String msg) throws RemoteException {
            this.txt=msg;
        }

        @Override
        public String getMsg() throws RemoteException {
            return txt+":服务端已处理过";
        }
    };

    public MyService() {
    }

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

3.配置service

image.png

4.完结

最终文件目录结构图如下(Android模式下):

image.png

2.新建A工程即应用端apk

1.将B工程的aidl连文件夹一起拷贝到A工程

拷贝B工程的aidl文件夹,打开A工程main文件夹在电脑中的位置,将拷贝的内容放进来,rebuild工程A。

Pasted Graphic.png

image.png

2.绑定远程service并通信

package com.example.myaidldemo1

import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.myaidldemo2.IMyAidlInterface

//参考:https://blog.csdn.net/afufufufu/article/details/131723540
class MainActivity : AppCompatActivity() {
//    private var demoServiceConnection: DemoServiceConnection?=null
//    服务端的IMyAidlInterface复制过来后需要重新build
    private var myAidlInterface: IMyAidlInterface?=null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.bt).setOnClickListener {
            val intent= Intent()
//            启动方式1
//            intent.component = ComponentName("com.example.myaidldemo2", "com.example.myaidldemo2.MyService")
//            启动方式2
            intent.setAction("com.example.myaidldemo2.MyService");
            intent.setPackage("com.example.myaidldemo2");//包名
            //绑定服务--需要在配置文件中增加queries,否则启动不了
            bindService(intent,object:ServiceConnection {
                override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
                    myAidlInterface= IMyAidlInterface.Stub.asInterface(iBinder)
                    if (myAidlInterface!=null) {
                        Toast.makeText(this@MainActivity,"服务已连接",Toast.LENGTH_SHORT).show()
                    }

                }

                override fun onServiceDisconnected(p0: ComponentName?) {
                    myAidlInterface=null
                    Toast.makeText(this@MainActivity,"服务未连接",Toast.LENGTH_SHORT).show()
                }

            },BIND_AUTO_CREATE)
        }
        findViewById<Button>(R.id.bt2).setOnClickListener {
            myAidlInterface?.sendMsg("我是1向2发送的消息")

        }

        val tv=findViewById<TextView>(R.id.tv)
        tv.setOnClickListener {
            tv.setText(myAidlInterface?.msg?:"未获取到")
        }
    }
//    private inner class DemoServiceConnection : ServiceConnection {
//        override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
//            myAidlInterface= IMyAidlInterface.Stub.asInterface(iBinder)
//            if (myAidlInterface!=null) {
//                Toast.makeText(this@MainActivity,"服务已连接",Toast.LENGTH_SHORT).show()
//            }
//
//        }
//
//        override fun onServiceDisconnected(p0: ComponentName?) {
//            myAidlInterface=null
//            Toast.makeText(this@MainActivity,"服务未连接",Toast.LENGTH_SHORT).show()
//        }
//
//    }

}

3.配置文件中增加queries

<queries>
<!--  1.  对应MainActivity中的ComponentName启动方式-->
<!--    <package android:name="com.example.myaidldemo2" />-->

<!--  2.  对应MainActivity中的setAction启动方式-->
    <intent>
        <action android:name="com.example.myaidldemo2.MyService" />
        <category android:name="android.intent.category.DEFAULT"/>
<!--        <data android:mimeType="*/*" />-->
    </intent>
</queries>

即如下图:

image.png

至此整个AIDL实现进程间通信的demo就完结了