远程服务例子2

AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据时,就需要做进一步的处理。

AIDL服务支持的数据类型如下:

java的简单类型(int、char、boolean等)。不需要导入import

String和CharSequence。不需要导入import

List和Map。但要注意,List和Map对象的元素类型必现是AIDL服务支持的数据类型。不需要导入import

AIDL自动生成的接口。需要导入import

实现android.os.Parcelable接口的类。需要导入import

传递一个需要import的数据类型的步骤略显复杂。除了要建立一个实现android.os.Parcelable接口的类外,还需要为这个类单独建立一个aidl文件,并使用parcelable关键字进行定义。

aidl:

package com.example.aidl4;

import java.util.List;
import com.example.aidl4.PersionParcel;

interface IPersionBinder {

    String getName(in PersionParcel p);
    List<PersionParcel> getAllPersions();
}
在编写上面代码时需要注意如下两点:

PersionParcel是一个实现android.os.Parcelable接口的类,需要使用import导入这个类。

如果方法的类型是非简单类型,如String、List或自定义的类,需要使用in、out或inout修饰。其中in表示这个值被客户端设置;out表示这个值被服务端设置;inout表示这个值既被客户端设置,又被服务端设置。

PersionParcel的aidl文件:

package com.example.aidl4;
parcelable PersionParcel;
PersionParcel类:

package com.example.aidl4;

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

public class PersionParcel implements Parcelable {

    private String mName;
    private int mAge;
    private String mSex;

    public PersionParcel() {
    }

    public PersionParcel(Parcel in) {
        mName = in.readString();
        mAge = in.readInt();
        mSex = in.readString();
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public int getAge() {
        return mAge;
    }

    public void setmAge(int age) {
        mAge = age;
    }

    public String getSex() {
        return mSex;
    }

    public void setmSex(String sex) {
        mSex = sex;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
        dest.writeInt(mAge);
        dest.writeString(mSex);
    }

    public static final Parcelable.Creator<PersionParcel> CREATOR = new Creator<PersionParcel>() {

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

        @Override
        public PersionParcel createFromParcel(Parcel source) {
            return new PersionParcel(source);
        }
    };
}
在编写PersionParcel类时应注意如下3点:

PersionParcel类必须实现android.os.Parcelable接口。该接口用于序列化对象。在Android中之所以使用Parcelable接口序列化,而不用java.io.Serializable接口,是因为Google在开发Android时发现Serializable序列化的效率并不高,因此,特意提供了一个Parcelable接口来序列化对象。

在PersionParcel类中必须有一个静态常量,常量名必现是CREATOR,而且CREATOR常量的数据类型必须是Parcelable.Creator。

在writeToParcel方法中需要将要序列化的值写入Parcel对象。

远程服务:

public class AidlService extends Service {

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

    public class AidlBinder extends IPersionBinder.Stub {

        @Override
        public String getName(PersionParcel p) throws RemoteException {
            return p.getName();
        }

        @Override
        public List<PersionParcel> getAllPersions() throws RemoteException {
            List<PersionParcel> list = new ArrayList<PersionParcel>();
            PersionParcel p = new PersionParcel();
            p.setName("zhangsan");
            p.setmAge(20);
            p.setmSex("boy");
            list.add(p);
            return list;
        }

    }
}

其他应用调用,需要将aidl文件拷贝到对应目录下的同时,也需要将PersionParcel.java文件拷贝到对应目录下。

public class MainActivity extends Activity {

    private IPersionBinder mBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindAidlService();
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                if (mBinder != null) {
                    try {
                        List<PersionParcel> list = mBinder.getAllPersions();
                        for (PersionParcel item : list) {
                            System.out.println("姓名:" + item.getName() + ", 年龄:"
                                    + item.getAge() + ", 性别:" + item.getSex());
                            System.out.println("姓名:" + mBinder.getName(item));
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBinder != null) {
            unbindService(mConn);
        }
        mBinder = null;
    }

    private void bindAidlService() {
        Intent service = new Intent("com.example.aidl4.AidlService");
        bindService(service, mConn, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection mConn = new ServiceConnection() {
        
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
        
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinder = IPersionBinder.Stub.asInterface(service);
        }
    };

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值