AIDL与service

 

Service:Local service,一个进程中的多线程服务。

AIDL:remote service,不同进程间通信。

 

Service启动方法:

startService():调用方destroy了那么服务不会销毁,不能与调用方直接适用,不返回任何结果。

bindService():调用方destroy了那么服务也会销毁,能与调用方直接通信。返回Binder。

 * bindService时可以传递Binder的形式与调用方直接通信。在调用方需override叫ServiceConnnection的类来与service直接通信。

    绑定成功后通过getService()获取Service对象,将Service对象设置为null,表示绑定意外失效,Service实例不再可用。

 

可以参考一下log:

操作步骤先用startService启动服务,然后destroy。

然后bindService绑定服务,然后destroy的结果如下:

 

不难看出start方式启动服务时调用方销毁后服务不会自动stop。

而bind方式绑定服务时调用方销毁后服务自动解除绑定同时销毁。

 

生命周期相关:

 

AIDL与service的区别

你可以试一试创建两个包不用AIDL的情况。

 

通过ThreadRandomServiceDemo包中的ThreadRandomServiceDemo类去开启Demo中的RandomService是可以启动的但是无法获取,

有人会说利用bindService()不是利用可以ServiceConnection类返回Binder对象吗?是的,但是你无法加载Demo包(imorpt com.example.demo.RandomService)这样就我们无法与service直接数据交互通信了。

但是我们利用AIDL就可以调用其他进程(或其他project)直接通信。

AIDL是通过MyAidl.Stub.asInterface(binder);来获取binder的。

AIDL是以获取其他进程的接口来实现IPC通信的。

使用AIDL相关可以参考之前讲过的http://www.cnblogs.com/hongguang-kim/p/5165523.html

 

简单说明一下AIDL问价自动生成的java文件中我们可以看到Parcel。

Parcel是Android系统中应用程序进程间数据传递的容器,能够在两个进程中完成数据的打包和拆包的工作,

但Parcel不同于通用意义上的序列化,Parcel的设计目的是用于高性能IPC传输,因此不能够将Parcel对象保存在任何持久存储设备上。

当数据以Parcel对象的形式传递到跨进程服务的内部时,onTransact()方法将从Parcel对象中逐一的读取每个参数,然后调用Service内部制定的方法,

并再将结果写入另一个Parcel对象,准备将这个Parcel对象返回给远程的调用者。

 

自定义Parcel:

首先建立AllResult.aidl文件,声明AllResult类

package edu.hrbeu.ParcelMathServiceDemo;
parcelable AllResult;

在第2行代码中使用parcelable声明自定义类,这样其他的AIDL文件就可以使用这个自定义的类

构造AllResult类。AllResult类除了基本的构造函数以外,还需要有以Parcel对象为输入的构造函数,并且需要重载打包函数writeToParcel()
AllResult.java文件的完整代码如下

package edu.hrbeu.ParcelMathServiceDemo;
 
import android.os.Parcel;
import android.os.Parcelable;
 
public class AllResult implements Parcelable {
    public long AddResult;
    public long SubResult;
    public long MulResult;
    public double DivResult;
.       public AllResult(long addRusult, long subResult, long mulResult, double divResult){
                              AddResult = addRusult;
        SubResult = subResult;
        MulResult = mulResult;
        DivResult = divResult;
      }
    
      public AllResult(Parcel parcel) {
        AddResult  = parcel.readLong();
        SubResult  = parcel.readLong();
        MulResult  = parcel.readLong();
        DivResult  = parcel.readDouble();
       }
    
      @Override
    public int describeContents() {
        return 0;
    }
     @Override  
       public void writeToParcel(Parcel dest, int flags) {
                             dest.writeLong(AddResult);34.
        dest.writeLong(SubResult);    
        dest.writeLong(MulResult);    
        dest.writeDouble(DivResult);    
      }
 
       public static final Parcelable.Creator<AllResult> CREATOR =
        new Parcelable.Creator<AllResult>(){
        public AllResult createFromParcel(Parcel parcel){
            return new AllResult(parcel);
        }
         public AllResult[] newArray(int size){
            return new AllResult[size];
            }
         };
   } 

AllResult类继承于Parcelable
支持通过Parcel对象实例化AllResult内容是构造函数的读取顺序。
writeToParcel()是“打包”函数,将AllResult类内部的数据,按照特定的顺序写入Parcel对象,写入的顺序必须与构造函数的读取顺序一致
静态公共字段Creator,用来使用Parcel对象构造AllResult对象。

我们可以在其他类中编写如下代码:

  long addRusult = a + b;
    long subResult = a - b;
    long mulResult = a * b;
    double divResult = (double) a / (double)b;
    AllResult allResult = new AllResult(addRusult, subResult, mulResult, divResult);

我们可以通过result.AddResult变量获取其运算结果。

 

posted on 2016-06-28 11:15  金洪光  阅读(918)  评论(0编辑  收藏  举报

导航