详解Android aidl的使用方法

来自:网络
时间:2020-10-14
阅读:

AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写(对于小白来说,AIDL的作用是让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互。)

AIDL只是Android中众多进程间通讯方式中的一种方式,

AIDL和Messenger的区别:

    Messenger不适用大量并发的请求:Messenger以串行的方式来处理客户端发来的消息,如果大量的消息同时发送到服务端,服务端仍然只能一个个的去处理。 Messenger主要是为了传递消息:对于需要跨进程调用服务端的方法,这种情景不适用Messenger。 Messenger的底层实现是AIDL,系统为我们做了封装从而方便上层的调用。 AIDL适用于大量并发的请求,以及涉及到服务端端方法调用的情况

AIDL通信的原理:首先看这个文件有一个叫做proxy的类,这是一个代理类,这个类运行在客户端中,其实AIDL实现的进程间的通信并不是直接的通信,客户端和服务端都是通过proxy来进行通信的:客户端调用的方法实际是调用是proxy中的方法,然后proxy通过和服务端通信将返回的结果返回给客户端。

1、AIDL的作用

AIDL是用于Android的IPC通讯的,因此可以在一个APP内部通讯,也可以创建两个APP之间进行通讯。

AIDL的职能分配很明确,Service作为后台运行作为服务器管理各种交互,Client作为客户端请求数据或调用Service的方法。

2、AIDL的简单使用

1)创建一个aidl文件,直接右键创建就可以了,

package com.example.mytest;

// IMyAidlInterface.aidl
package com.example.mytest;
 
// Declare any non-default types here with import statements
 
interface IMyAidlInterface {
  /**
   * 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);
  String add(int x , int y);
}

2)选中刚刚建立的 .aidl文件 生产对应的java文件。

AndroidStudio 可以通过Build--》model App 完成

3)编写Service的具体对象 实现接口

package com.example.mytest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class FirstService extends Service {
  public FirstService() {
  }
  private static String Tag = "FirstService";
  @Override
  public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    //throw new UnsupportedOperationException("Not yet implemented");
    Log.d(Tag,"service on bind");
    return mBinder;
  }
  @Override
  public void onCreate() {
    super.onCreate();
    Log.d(Tag,"OnCreate");
  }
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(Tag,"onStartCommand");
    return START_STICKY;
  }
  @Override
  public boolean onUnbind(Intent intent) {
    Log.d(Tag,"onUnbind");
    return super.onUnbind(intent);
  }
  @Override
  public void onDestroy() {
    super.onDestroy();
    Log.d(Tag,"onDestroy");
  }
  IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub(){
    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
    }
    @Override
    public String add(int x, int y) throws RemoteException {
      Log.d(Tag,x + "--" + y);
      return String.valueOf(x + y);
    }
  };
}

注意:onBund 返回IBinder类型,为了后面的回调会调动

4)确定一下AndroidManifest.xml里面的Service内容

 <service
      android:name=".FirstService"
      android:enabled="true"
      android:exported="true">
      <intent-filter>
        <action android:name="com.example.mytest.aidl.FirstService"/>
      </intent-filter>
 
    </service>

5)打开服务

 private Button btnStartService; 
  private Button btnBindService;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    initView();
  }
 
  private void initView() {
    tvId = (TextView) findViewById(R.id.tv_id);
 
    btnStartService = (Button) findViewById(R.id.btn_Start_Service);
    btnStartService.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        Intent intent = new Intent();
        intent.setPackage("com.example.mytest");
        intent.setAction("com.example.mytest.aidl.FirstService");
        startService(intent);
      }
    });
 
    btnBindService = (Button) findViewById(R.id.btnBindService);
    btnBindService.setOnClickListener(new View.OnClickListener() {
      @Override
        public void onClick(View view) {
            bind();
        }
    });
  
 
  private void bind(){
    Log.d(Tag, "bind");
    Intent intent = new Intent();
    intent.setPackage("com.example.mytest");
    if(controllerConnection != null){
      this.bindService(intent,controllerConnection,this.BIND_AUTO_CREATE);//绑定服务,建立链接
    }
    else {
      Log.d(Tag, "controllerConnection != null");
    }
  }
 
  private void unbind(){
    if(controllerConnection != null && myAIDLController.asBinder().isBinderAlive()){
      try{
        Log.d(Tag, "this.unbindService(controllerConnection);");
        this.unbindService(controllerConnection);
      } catch (Exception localException) {
        Log.w(Tag, "unbind Exception localException");
      }
    }
  }

在bind的时候是异步的,因此可以通过onServiceConnected()来判断绑定上后的操作。

private ServiceConnection controllerConnection = new ServiceConnection(){
 
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
      Log.d(Tag,"onServiceConnected");
 
      myAIDLController = IMyAidlInterface.Stub.asInterface(iBinder);
      if (myAIDLController != null) {
        try {
          Log.d(Tag, "ServiceConnection success");
          Toast.makeText(MainActivity.this, "ServiceConnection success", Toast.LENGTH_LONG).show();
        } catch (Exception localException) {
          Log.w(Tag, "Exception localException");
        }
      }
    }
 
    @Override
    public void onServiceDisconnected(ComponentName componentName) {
      Log.d(Tag,"onServiceDisconnected");
      Toast.makeText(MainActivity.this, "onServiceDisconnected", Toast.LENGTH_LONG).show();
 
      myAIDLController = null;
    }
 
    @Override
    public void onBindingDied(ComponentName name) {
      Log.d(Tag,"onBindingDied");
    }
 
    @Override
    public void onNullBinding(ComponentName name) {
      Log.d(Tag,"onNullBinding");
    }
  };

6)调用Service方法add()

调用的时候需要绑定Service方法,上面已经有了,接下来调用就简单了,创建一个Button,然后拿到Service的控制对象,调用方法add

 btnServiceFunc = (Button) findViewById(R.id.btnServiceFunc);
    btnServiceFunc.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        try {
          Log.d(Tag, String.valueOf( myAIDLController.add(1,2)));
        } catch (RemoteException e) {
          e.printStackTrace();
        }
      }
    });
返回顶部
顶部