Service之AIDL

来源:互联网 发布:js中offsettop 编辑:程序博客网 时间:2024/06/07 01:22

引子

上一篇讲到了什么Service如何开启服务、绑定本地服务,这一篇说说AIDL(android接口定义语言),实现了进程间通讯(IPC机制 inner-process communication)

所谓IPC机制,即进程间通讯(Inter-Process Communication)。我们的应用有时候出于业务需要,可能是多进程的,而由于不同进程是不共享一个内存池的,所以进程之间不能直接通讯,而要通过一些特别的机制才能通讯,所以IPC机制是解决进程间通讯的一个方案

通俗讲就是在两个不同的app应用里实现通讯,A应用(客户端)调用B应用(服务端)里的一个Service的方法

实现步骤

  1. 先写一个服务端App应用BServiceApp,在BServiceApp里AndroidStudio里直接创建一个aidl文件
  2. 在这个IMyAidlInterface.aidl文件(相当于一个接口)里定义一个方法,这个方法就是你要在AClinetApp要调用的方法,写好后build一下。

    package com.mine.bserviceapp;interface IMyAidlInterface {    int add(int a,int b);    void sayHello(String str);}
  3. 定义一个可远程调用的Service

    1. 将一个普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将它的android:process属性指定成:remote就可以了,
    2. 构建Intent的时候是使用MyService.class来指定要绑定哪一个Service的,但是在另一个应用程序中去绑定Service的时候并没有MyService这个类,这时就必须使用到隐式Intent了。现在修改AndroidManifest.xml中的代码,给MyService加上一个action
     <service            android:name=".MyService"            android:process=":remote"//远程服务            android:enabled="true"            android:exported="true">            <intent-filter>                <action android:name="com.mine.bserviceapp.MyService"/>            </intent-filter>        </service>
    package com.mine.bserviceapp;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class MyService extends Service {    public MyService() {    }    @Override    public IBinder onBind(Intent intent) {    //sub相当于本地服务中的Binder        return stub;    }    IMyAidlInterface.Stub stub = new IMyAidlInterface.Stub() {        @Override        public int add(int a, int b) throws RemoteException {            return addInService(a, b);        }        @Override        public void sayHello(String str) throws RemoteException {            sayHelloInService(str);        }    };    private int addInService(int a, int b) {        return a + b;    }    private void sayHelloInService(String str) {        Log.e("c", str);    }}

    至此BServiceApp里的服务写完了,开始写AClientAPP,我们要在AClientAPP里的Activity里,通过aidl来调用BServiceApp里的MyService里的两个方法。

  4. 先在AClientAPP里新建一个aidl文件夹,在建立一个和BServiceApp一模一样路径的包,并且把其aidl文件也拷贝过来
    这里写图片描述

  5. 在Activity里远程绑定服务

    package com.mine.aclientapp;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Toast;import com.mine.bserviceapp.IMyAidlInterface;public class MainActivity extends AppCompatActivity implements ServiceConnection {    boolean isBind = false;    private IMyAidlInterface mAidlInterface;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void bind(View v) {        Intent intent = new Intent("com.mine.bserviceapp.MyService");        intent.setPackage("com.mine.bserviceapp");//必须显示地指定包名,在api23后        bindService(intent, this, BIND_AUTO_CREATE);    }    public void add(View v) {        if (isBind){            try {                int add = mAidlInterface.add(198, 230);                Toast.makeText(this, "add:"+add, Toast.LENGTH_SHORT).show();            } catch (RemoteException e) {            }        }    }    public void sayHello(View v) {        if (isBind){            try {                mAidlInterface.sayHello();            } catch (RemoteException e) {            }        }    }    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        mAidlInterface = IMyAidlInterface.Stub.asInterface(service);        Toast.makeText(this, "绑定成功", Toast.LENGTH_SHORT).show();        isBind=true;    }    @Override    public void onServiceDisconnected(ComponentName name) {    }}

    点击绑定服务,可以绑定成功过,也可以调用方法了

0 0
原创粉丝点击