AIDL实现跨APP通信(双向通信)

来源:互联网 发布:vscode vue 开发环境 编辑:程序博客网 时间:2024/06/05 14:51

某天,接到了一人任务要在两个app互相传递一些消息,上网查了以后发现有几种方式。第一是广播、第二是AIDL,由于初出茅庐全不会就选择了AIDL。。。下面简单粗暴的开始贴代码好了。也是得到了网上的一些借鉴,若有雷同,嗯你懂的。


1.我们需要先建立AIDL文件。值得一提的是,我们要在main下建立一个专门用来放AIDL文件的包。非常重要!


其中,AIDLClient.aidl是客户端使用的接口,AIDLService是服务器所用的接口,Info是我们要传的自定义实体类。客户端就是想要主动给另一个app发送信息的一端,服务器就是接收信息并可以返回信息的一端。下面来看看最简单的AIDL里面该怎么写。

(1)AIDLClient.aidl

<pre style="font-family: 宋体; font-size: 9pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java">// AIDLClient.aidlpackage AIDL;// Declare any non-default types here with import statementsinterface AIDLClient {    /**     * 接收来自另一个app返回的信息     */     void receiveByServer(String message);}

(2)AIDLClient.aidl

package AIDL;// Declare any non-default types here with import statementsimport AIDL.AIDLClient;import AIDL.AIDLService;interface AIDLService {    /**     * 接收来自客户端发来的信息     * @param info 实体类     */    Info getServerdanceInfo(in Info info);}

在客户端给服务器发送请求后,服务器会返回一个Info类型的实体。

(3)Info.aidl

// Info.aidlpackage AIDL;parcelable Info;

在Info中我们要使用我们自己写的实体类类型,而不是用基本类型。

(4)Info

public class Info implements Parcelable {    private String message;
我们实体类中其实只有一个String类型,当然也可以有多个自己设置的类型,但是一定要使用AIDL中支持的几个基本类型。剩下的就自动生成出get/set等就可以了,记得多写一个默认构造函数。

2.在客户端app中我们要实现点击按钮,发送消息并将服务器返回的消息显示着Textview中。

<pre name="code" class="java">public class MainActivity extends AppCompatActivity {    public static final String TAG = "MainActivity";    private static final String BIND_ACTION = "AIDL.service";    private Button button;    private TextView textView;    private AIDLService aidlServce;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init(){        button = (Button)findViewById(R.id.sendAIDL);        textView = (TextView)findViewById(R.id.receive);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //绑定服务                getServiceConnect();            }        });    }    private void getServiceConnect(){        Intent it = new Intent();        it.setAction(BIND_ACTION);        it.setPackage("com.example.zjl.aidlservice_demo");        startService(it);        bindService(it, serviceConnection,BIND_AUTO_CREATE);    }    ServiceConnection serviceConnection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            Log.d(TAG,"onServiceDisconnected");        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.d(TAG,"onServiceConnected");            //获取服务端传过来的IBinder对象,通过该对象调用服务端的方法            aidlServce = AIDLService.Stub.asInterface(service);            if (aidlServce != null){                handlerInfo();            }        }    };    private void handlerInfo(){        Info mInfo = new Info();        mInfo.setMessage("肿么可以次兔兔");        try {            Info serverInfo = new Info();            //调用服务端的方法            serverInfo = aidlServce.getServerInfo(mInfo,mClient);            unbindService(serviceConnection);        }catch (RemoteException e){            e.printStackTrace();        }    }    AIDLClient.Stub mClient = new AIDLClient.Stub()    {        //客户端回调方法的具体实现        @Override        public void receiveByServer(String param) throws RemoteException {            textView.setText(param);        }    };}



这里需要注意的是,在用Intent绑定服务的时候在5.0以后需要对package进行设定,否则会报错。setPackage里的参数为服务器端的包名。XML就俩控件,一个button一个Textview就不写了。


3.在服务器中需要把AIDL连同包一起复制到main下同客户端一样。build后会自动生成java文件,否则使用不了。




4.在服务端写一个service用于接收来自客户端的请求。

public class service extends Service {    public static final String TAG = "DanceAIDLService";    private AIDLClient aidlClient;    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    /**     * 创建服务     */    @Override    public void onCreate()    {        super.onCreate();    }    /**     * 销毁服务     */    @Override    public void onDestroy()    {        super.onDestroy();    }    /**     * 启动服务     */    @Override    public void onStart(Intent intent, int startId)    {        super.onStart(intent, startId);    }    /**     * 解绑服务     */    @Override    public boolean onUnbind(Intent intent)    {        aidlClient = null;        return super.onUnbind(intent);    }    //处理来自客户端的消息    AIDLService.Stub mBinder = new AIDLService.Stub() {        @Override        public Info getServerInfo(Info info, AIDLClient client) throws RemoteException {            aidlClient = client;            aidlClient.receiveByServer("收到来自客户端的消息:"+info.getMessage());            Log.d(TAG,info.getMessage()+"       ");            Info newInfo = new Info();            newInfo.setMessage(info.getMessage());            return newInfo;        }    };}

我们这把从客户端发过来的信息加了几个字又返了回去。并且配置service。

<service            android:name=".service"            android:enabled="true"            android:exported="true">            <intent-filter>                <action android:name="AIDL.service"></action>            </intent-filter></service>

5.最后,还需要在build.gradle中添加用于区分aidl和java的命令。卸载Android括号内就可以。

 sourceSets{        main{            java.srcDirs = ['src/main/java', 'src/main/aidl']        }    }

怎么样是不是好简单,但是AIDL那些文件真的很容易出错误哦,所以在第一次写的时候可能会总也调不好,有点耐心慢慢调吧~~




1 0
原创粉丝点击