AIDL客户端与服务端数据传输

全称:Android Interface Definition Language(Android接口定义语言)

实现功能:

想要实现一个夸进程,从app1向app2请求数据,并且app2收到请求回调给app1

首先建立服务端

建立aidl文件   IMyService.aidl

package com.example.shenwchneusoftcom.testaidlone;
import com.example.shenwchneusoftcom.testaidlone.Product;
import com.example.shenwchneusoftcom.testaidlone.ITaskCallback;
interface IMyService    实现一个接口
{  
    Map getMap(in String country, in Product product);  //实现map的方法
    Product getProduct();                                //实现getProduct的方法
    void getProduc(out Product product);               //实现 带参数的方法
    
    //用来注册回调的对象
    void registerCallback(ITaskCallback cb);     //注册callback
    void unregisterCallback(ITaskCallback cb);  //取消注册callback
    void startCallBack();   //请求callback的方法
}          

ITaskCallback.aidl 

用来回调给app端传输方法

package com.example.shenwchneusoftcom.testaidlone;

//该接口在客户端实现
//private ITaskCallback mCallback = new ITaskCallback.Stub() {
//    @Override
//    public void clientTackCallBack(int actionId) throws RemoteException {
//       Log.i(TAG, "actionId :" + actionId);
//    }
//    };
    
interface ITaskCallback {

   //客户端给服务器端回调的函数,
   //前提是当客户端获取的IBinder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用哪些函数
   //void registerCallback(ITaskCallback cb);注册的函数,在IMyService.aidl文件中   
    //void unregisterCallback(ITaskCallback cb);取消注册的函数,在IMyService.aidl文件中   
    //客户端调用myService.registerCallback(mCallback);
    void clientTackCallBack(int actionId);
}

建立可序列化的实例 

Product.adil

parcelable Product; 

 

建立服务

package com.example.shenwchneusoftcom.testaidlone;


import java.util.HashMap;
import java.util.Map;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service
{ 
   private final static String TAG = "***MyService***";
   //用来注册客户端回调接口对象  
   private RemoteCallbackList<ITaskCallback> mCallbacks;   
   
   @Override
   public void onCreate() {
      Log.d(TAG, "myService onCreate()");
      super.onCreate();
      mCallbacks = new RemoteCallbackList<ITaskCallback>();
      callback(100); //用来测试
   }
   
   @Override
   public void onStart(Intent intent, int startId) {
      Log.d(TAG, "startId :" + startId);
      callback(startId);//用来测试
   }
   
   void callback(int startId) {
      final int N = mCallbacks.beginBroadcast(); 获取callback的次数
      Log.d(TAG, "mCallbacks.beginBroadcast() :" + N);
      for (int i = 0; i < N; i++) {
         try {
            mCallbacks.getBroadcastItem(i).clientTackCallBack(startId);  传递给客户端的回调
         } catch (RemoteException e) {
            // The RemoteCallbackList will take care of removing
            // the dead object for us.
         }
      }
      mCallbacks.finishBroadcast();结束callback
   }

//通过binder数据实现
   public class MyServiceImpl extends IMyService.Stub
   {

      @Override
      public Product getProduct() throws RemoteException
      {
         //app端调用该方法,服务端提供的数据
         Product product = new Product();
         product.setId(1234);
         product.setName("汽车");
         product.setPrice(31000); 
         return product;
      }

      @Override
      public void getProduc(Product product) throws RemoteException {
        //app端调用该方法,服务端提供的数据
         if(product == null) product = new Product();
         product.setId(1234);
         product.setName("飞机");
         product.setPrice(62000); 
      }

      @Override
      public Map getMap(String country, Product product)
            throws RemoteException
      {
      //app端调用该方法,服务端提供的数据
         Map map = new HashMap<String, String>();
         map.put("country", country);
         map.put("id", product.getId());
         map.put("name", product.getName());
         map.put("price", product.getPrice());
         map.put("product", product);
         return map;
      }

      @Override
      public void registerCallback(ITaskCallback cb) throws RemoteException {
         if(cb != null)
            //注册RemoteCallbackList
            mCallbacks.register(cb); 
      }  

      @Override
      public void unregisterCallback(ITaskCallback cb) throws RemoteException {
         if(cb != null)
            //解除注册RemoteCallbackList
            mCallbacks.unregister(cb);
      }

      @Override
      public void startCallBack() throws RemoteException {
         //App端请求该方法,并回调给app端
         callback(2000);
      }
   }

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

}

实体类

Product.java

该文件一定要与aidl文件同目录下,要不然aidl里面是找不到该实例的

package com.example.shenwchneusoftcom.testaidlone;

import android.os.Parcel;
import android.os.Parcelable;

public class Product implements Parcelable
{
   private int id;
   private String name;
   private float price;
   public static final Creator<Product> CREATOR = new Creator<Product>()
   {
      public Product createFromParcel(Parcel in)
      {
         return new Product(in);
      }

      public Product[] newArray(int size)
      {
         return new Product[size]; 
      }
   };
    public Product()
    {
       
    }
   private Product(Parcel in)
   {
      readFromParcel(in);
   }

   @Override
   public int describeContents()
   {
      // TODO Auto-generated method stub
      return 0;
   }

   public void readFromParcel(Parcel in)
   {
      id = in.readInt();
      name = in.readString();
      price = in.readFloat();
      
   }

   @Override
   public void writeToParcel(Parcel dest, int flags)
   {
      dest.writeInt(id);
      dest.writeString(name);
      dest.writeFloat(price);

   }

   public int getId()
   {
      return id;
   }

   public void setId(int id)
   {
      this.id = id;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   public float getPrice()
   {
      return price;
   }

   public void setPrice(float price)
   {
      this.price = price;
   }

}

AndroidManifest.xml 

<service android:name=".MyService" >
    <intent-filter>
        <action android:name="com.example.shenwchneusoftcom.testaidlone.IMyService" />
    </intent-filter>
</service>

建立客户端

将服务端的aidl放到app端下aidl并且包名一定要一致,要不然服务端是找不到app端的

客户端代码

 

package com.example.shenwchneusoftcom.testaidloneclient;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.shenwchneusoftcom.testaidlone.IMyService;
import com.example.shenwchneusoftcom.testaidlone.ITaskCallback;
import com.example.shenwchneusoftcom.testaidlone.Product;

public class Main extends Activity implements OnClickListener
{
   private final static String TAG = "***Main***";
   private IMyService myService = null;
   private Button btnInvokeAIDLService;
   private Button btnBindAIDLService;
    private Button btnStartCallBack;
   private TextView textView;
   private ServiceConnection serviceConnection = new ServiceConnection()
   {

      @Override
      public void onServiceConnected(ComponentName name, IBinder service)
      {
         myService = IMyService.Stub.asInterface(service); //获取服务端
         try {
            myService.registerCallback(mCallback); //注册callback
         } catch (RemoteException e) {
            e.printStackTrace();
         }
         btnInvokeAIDLService.setEnabled(true);

      }

      @Override
      public void onServiceDisconnected(ComponentName name)
      {
         // TODO Auto-generated method stub

      }
   };
   
   @Override
   protected void onPause() {
      super.onPause();
      try {
         myService.unregisterCallback(mCallback);
      } catch (RemoteException e) {
         e.printStackTrace();
      }
   }

   @Override
   public void onClick(View view)
   {
      switch (view.getId())
      {
         case R.id.btnBindAIDLService:
            //启动服务端服务
            Intent mIntent = new Intent();
            mIntent.setAction("com.example.shenwchneusoftcom.testaidlone.IMyService");
            bindService(getExplicitIntent(this,mIntent), serviceConnection, Context.BIND_AUTO_CREATE);
//          startService(new Intent("com.example.shenwchneusoftcom.testaidlone.IMyService"));
            break;

         case R.id.btnInvokeAIDLService:
            try
            {
               Product product = new Product();
               String s = "";
               s = "Product.id = " + myService.getProduct().getId() + "\n";
               s += "Product.name = " + myService.getProduct().getName()
                     + "\n";
               s += "Product.price = " + myService.getProduct().getPrice()
                     + "\n\n";
               
               myService.getProduc(product);
               s += "Product.id = " + product.getId() + "\n";
               s += "Product.name = " + product.getName()
                     + "\n";
               s += "Product.price = " + product.getPrice()
                     + "\n\n";
               
               s += myService.getMap("China", myService.getProduct()).toString();
               textView.setText(s);
            }
            catch (Exception e)
            {

            }
            break;
            case R.id.btnStartCallBack:
            //app端主动获取callback方法
                if (myService!=null){
                    try {
                        Log.d(TAG, "btnStartCallBack" );
                        myService.startCallBack();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
                break;
      }

   }

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService);
      btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService);
        btnStartCallBack = (Button)findViewById(R.id.btnStartCallBack);
      btnInvokeAIDLService.setEnabled(false);
      textView = (TextView) findViewById(R.id.textview);
      btnInvokeAIDLService.setOnClickListener(this);
      btnBindAIDLService.setOnClickListener(this);
        btnStartCallBack.setOnClickListener(this);
   }
   
   private ITaskCallback mCallback = new ITaskCallback.Stub() {
      @Override
      public void clientTackCallBack(int actionId) throws RemoteException {
         //app端主动获取方法之后,服务端提供的回调
         Log.d(TAG, "actionId :" + actionId);
      }
    };
//显示启动
   private static Intent getExplicitIntent(Context context,Intent implicitIntent) {
      PackageManager pm = context.getPackageManager();
      ResolveInfo resolveInfo = pm.resolveService(implicitIntent, 0);
      ComponentName component = new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
      // 创建一个新的意图。使用旧的一个额外的和这样的重用
      Intent explicitIntent = new Intent(implicitIntent);
      // 将组件设置为显式
      explicitIntent.setComponent(component);
      return explicitIntent;
   }
}

Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical" android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <TextView android:id="@+id/textview" android:layout_width="fill_parent"
      android:layout_height="wrap_content" android:textSize="16dp" />
   <Button android:id="@+id/btnBindAIDLService"
      android:layout_width="fill_parent" android:layout_height="wrap_content"
      android:text="绑定AIDL服务" android:layout_marginTop="10dp" />
   <Button android:id="@+id/btnInvokeAIDLService"
      android:layout_width="fill_parent" android:layout_height="wrap_content"
      android:text="调用AIDL服务" android:layout_marginTop="10dp" />
   <Button android:id="@+id/btnStartCallBack"
      android:layout_width="fill_parent" android:layout_height="wrap_content"
      android:text="StartCallBack" android:layout_marginTop="10dp" />
</LinearLayout>

并且实例 Product是与服务端一样的

总结:

就是跨进程的接口回调与接口调用,只不过都是靠aidl(binder)统一管理实现跨进程

(借鉴https://www.jianshu.com/p/b260051237fe

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万子开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值