AIDL学习笔记(二)----自定义类型,客户端远程调用服务端

这里写图片描述

AIDL第二篇,主要记录一下自己学习AIDL自定义类型数据的过程,如下:

服务端目录结构:
这里写图片描述

客户端目录结构:
这里写图片描述

接下来是具体代码:

AIDL文件:

// IMyAidlInterface.aidl
package com.sjq.aidlservice;

// Declare any non-default types here with import statements
import com.sjq.aidlservice.Persion;
interface IMyAidlInterface {
//此处用到的实体类一要手动倒包,二要声明AIDL文件并在AIDL文件中声明类型
List<Persion> addPersion(in Persion p);
}

因为要用到自定义的类型,所以这个类型也必须新建AIDL文件

// IMyAidlInterface.aidl
package com.sjq.aidlservice;


//声明类型
parcelable Persion;

Service代码实现:

package com.sjq.aidlservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.ArrayList;
import java.util.List;

public class MyService extends Service {
    ArrayList<Persion> list ;
    public MyService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        list = new ArrayList<>();
        return binder;
    }

    IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {

        @Override
        public List<Persion> addPersion(Persion p) throws RemoteException {
            list.add(p);
            return list;
        }
    };
}

最后是实体类代码,实现Parceable接口

package com.sjq.aidlservice;

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

/**
 * Created by cs001 on 2016/6/28.
 */
public class Persion implements Parcelable {
    private String name;
    private int age;
    private String adrs;

    protected Persion(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
        this.adrs = in.readString();
        //如果此类中有另外一个自定义的类型,由于Book是另外一个可序列化对象,所以它的反序列化需要传递当前线程的上下文类加载器
        // 否则会报类无法找到的异常
        // this.book = in.readParceable(Thread.currentThread().getContextClassLoader());

    }

    /**
     * @param dest  Parcel 内部封装了可序列化的数据,可以在Binder中自由传输
     * @param flags 0或者1 为1时,当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0
     *              对象的序列化工作主要由此函数完成
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeString(adrs);
    }

    /**
     * 内容描述功能由此函数功能,仅当当前对象中存在文件描述符时返回1,
     * 几乎所有情况下都返回0
     *
     * @return
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 反序列化工作主要由CREATOR完成
     */
    public static final Creator<Persion> CREATOR = new Creator<Persion>() {
        @Override
        public Persion createFromParcel(Parcel in) {
            return new Persion(in);
        }

        @Override
        public Persion[] newArray(int size) {
            return new Persion[size];
        }
    };

    @Override
    public String toString() {
        return "Persion{" +
                "adrs='" + adrs + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

接下来是客户端代码:
同样的还是要把AIDL文件和实体类复制到客户端,包名要完全相同
如下:
这里写图片描述

代码:

package com.sjq.aidl;

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.util.Log;
import android.view.View;
import android.widget.Button;

import com.sjq.aidlservice.IMyAidlInterface;
import com.sjq.aidlservice.Persion;

import java.util.List;

public class MainActivity extends AppCompatActivity {

   private IMyAidlInterface iMyAidlInterface;
    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
              //将Binder转换为服务端的接口对象
              iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button) findViewById(R.id.add_btn);
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.sjq.aidlservice", "com.sjq.aidlservice.MyService"));
        bindService(intent, conn, BIND_AUTO_CREATE);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                 List<Persion> persions = iMyAidlInterface.addPersion(new Persion("张三",18,"宇宙中心五道口"));
                    Log.i("TAG", persions.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

以上就是全部代码,主要是跨进程通信传输自定义类型的数据

猜你喜欢

转载自blog.csdn.net/lantiankongmo/article/details/51783322