Android进程间传输大量数据,Android间的进程通讯(传递复杂对象)

Android间的进程通讯(传递复杂对象)

完成对复杂对象的序列化

在Android中传递复杂数据类型的时候要通过将序列化,在Android中提供了一个接口Parcelable来实现对对象的序列化。

下面对需要传输的对象进行序列化操作,首先看自定义的类Person。

fcecaa27ea5212ceb9bf034c36bfbf34.gifpackagecom.example.service_parcelable_conmmute.bean;importandroid.graphics.Bitmap;/*** 用来传输的对象结构

*@authorXinyuyu

**/

public classPerson {privateString name;privateString age;privateBitmap figure;publicPerson(){

}publicPerson(String name, String age, Bitmap figure){this.name =name;this.age =age;this.figure =figure;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicString getAge() {returnage;

}public voidsetAge(String age) {this.age =age;

}publicBitmap getFigure() {returnfigure;

}public voidsetFigure(Bitmap figure) {this.figure =figure;

}

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

这个类就是一般的JavaBean包含了一些get/set方法,我们要做的就是在进程之间传递该对象的值。所以就要将该对象进行序列化,下面实现一个类来完成该任务。

建立ParcelablePerson类,来完成对Person的序列化和反序列化的操作。其代码如下:

fcecaa27ea5212ceb9bf034c36bfbf34.gifpublic class ParcelablePerson implementsParcelable {

Person person= newPerson();publicPerson getPerson() {returnperson;

}public voidsetPerson(Person person) {this.person =person;

}publicParcelablePerson(Person person){this.person =person;

}publicParcelablePerson(Parcel source){

person.setName(source.readString());

person.setAge(source.readString());

person.setFigure((Bitmap)source.readParcelable(Bitmap.class.getClassLoader()));

}

@Overridepublic intdescribeContents() {return 0;

}

@Overridepublic void writeToParcel(Parcel dest, intflags) {

dest.writeString(person.getName());

dest.writeString(person.getAge());

dest.writeParcelable(person.getFigure(), PARCELABLE_WRITE_RETURN_VALUE);

}public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){

@OverridepublicParcelablePerson createFromParcel(Parcel source) {return newParcelablePerson(source);

}

@Overridepublic ParcelablePerson[] newArray(intsize) {return newParcelablePerson[size];

}

};

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

这段代码中完成了对Person对象的序列化与反序列化,实现Parcelable接口要做的就是来重写几个方法(分别完成序列化和反序列化),writeToParcel(Parcel

dest, int flags)完成的就是对对象的序列化

其中的参数Parcel是一个容器,将对象放入其中就是序列化的过程。而CREATOR中的createFormParcel(Parcel

source)来完成的就是反序列化,可以返回一个复杂的对象。实现了这写,就完成了对复杂对象的序列化和反序列化操作,这样我们就可以对它进行传输了。

完成绑定服务,完成进程中的通讯

以上我们只是完成了对一个复杂对象的序列化,下面我们要做的是建立服务,并且完成传输。

首先我们要做的是创建一个服务,在Android中创建一个服务要做的就是去实现Service接口。下面是发送对象的一个服务代码

fcecaa27ea5212ceb9bf034c36bfbf34.gifpublic class ServiceForSendObject extendsService {private static final String MSG = "MESSAGE";privateParcelablePerson parcelablePerson;privatePerson person;//=====================================

SendObject.Stub sendBinder = newStub(){

@Overridepublic ParcelablePerson getPersonInfo() throwsRemoteException {

Log.i(MSG,"调用getPersonInfo()接口实现,返回一个序列化的对象");returnparcelablePerson;

}};//=====================================

@Overridepublic voidonCreate() {

person= new Person("xinyuyu", "25", BitmapFactory.decodeStream(getResources().openRawResource(R.drawable.ic_launcher)));

parcelablePerson= newParcelablePerson(person);super.onCreate();

Log.i(MSG,"回调onCreate()创建服务");

}

@Overridepublic int onStartCommand(Intent intent, int flags, intstartId) {

Log.i(MSG,"回调onStartCommand()启动服务");return super.onStartCommand(intent, flags, startId);

}

@Overridepublic booleanonUnbind(Intent intent) {

Log.i(MSG,"回调onUnbind解绑服务");return super.onUnbind(intent);

}

@Overridepublic voidonDestroy() {

Log.i(MSG,"回调onDestroy销毁服务");super.onDestroy();

}

@OverridepublicIBinder onBind(Intent intent) {

Log.i(MSG,"回调onBind()方法绑定服务");returnsendBinder;

}

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

在该段代码中输出各个阶段的一些信息,关键是在onCreat()方法中完成实例化一个对象,并且对该对象完成序列化操作。在分割线之间的代码是关键代码,注意在IBinder()中返回的是一个SendObject.Stub对象。而这个类是如何生成的呢?我们在完成进程间传输的时候需要用到Android中的AIDL语言来定义一个接口,下面我们来建立一个名为SendObject的aidl文件,SendObject.aidl

fcecaa27ea5212ceb9bf034c36bfbf34.gifpackagecom.example.service_parcelable_conmmute_service.aidl;importcom.example.service_parcelable_conmmute.bean.ParcelablePerson;interfaceSendObject {

ParcelablePerson getPersonInfo();

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

这个接口中的import会报错,这时候需要在建立一个AIDL文件,将其名字设置为和序列化类一样,这里就起做ParcelablePerson.aidl。其内容如下

package com.example.service_parcelable_conmmute.bean;

parcelable ParcelablePerson;

完成这些就不会有错误了。

这时候你会发现在gen目录下有一个和你的aidl名字一样Java文件即SendObject.java。而我们使用的SendObject.Stub就在其中。打开这个文件看一下,你会发现SendObject.Stub是这样一个类,实现了SendObject接口并且继承了android.os.Binder类。这样我们就重写SendObject方法,将其实现功能。就是分割线直接的代码。

public static abstract class Stub extendsandroid.os.Binderimplements com.example.service_parcelable_conmmute_service.aidl.SendObject

还要注意一点进程间的服务通讯应该更改AndroidManifest.xml文件的属性,如下

fcecaa27ea5212ceb9bf034c36bfbf34.gif

fcecaa27ea5212ceb9bf034c36bfbf34.gif

这样可以完成隐式的传递Intent。完成了这些,服务端就完成了。这个时候可以运行下代码。

启动界面

5e390fb37632a2cb07aed52d55f65524.png

点击初始化服务后,可以看到服务开始运行

7897aa9db500f7845e842decfd411096.png

红色框中为我们的服务。

点击两按钮后LogCat输出的信息

4f7a8961cc1b922058f3c37a65002e64.png

从中可以看出来这个服务的生命周期。

以上我们就完成了服务端的工作了,下面来进行客户端的完成。

在客户端我们首先需要的是将服务端写好的那些AIDL文件和实体类拷贝到该工程下(连同包名进行拷贝)如下图

c649c69826cbc2ef2baded6701107b44.png

然后我们所要完成的就是完成客户端的activity程序了。将俩个程序进行联系的就是我们的SendObject接口。看下面代码

fcecaa27ea5212ceb9bf034c36bfbf34.gifpublic class A extendsActivity {privateButton show_button;privateTextView show_name_age;privateImageView show_image;privateButton unbind_ser;privateSendObject sendObject;privateParcelablePerson parcelablePerson;privatePerson person;private ServiceConnection connection = newServiceConnection(){//建立绑定后service程序调用onBind()方法,返回一个IBinder对象

@Overridepublic voidonServiceConnected(ComponentName name, IBinder service) {

sendObject=SendObject.Stub.asInterface(service);try{

parcelablePerson=sendObject.getPersonInfo();

person=parcelablePerson.getPerson();

Log.i("", person.getName());

show_name_age.setText(person.getName()+ "\n" +person.getAge());

show_image.setImageBitmap(person.getFigure());

}catch(RemoteException e) {

e.printStackTrace();

}

}

@Overridepublic voidonServiceDisconnected(ComponentName name) {

Log.i("", "error");

}

};

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.a);

show_button= (Button)this.findViewById(R.id.button1);

show_name_age= (TextView)this.findViewById(R.id.textView1);

show_image= (ImageView)this.findViewById(R.id.imageView1);

unbind_ser= (Button)this.findViewById(R.id.button2);

show_button.setOnClickListener(newOnClickListener(){

@Overridepublic voidonClick(View v) {//隐式传递intent

Intent intent = newIntent();

intent.setAction("com.example.service_parcelable_conmmute.service.SEND_OBJECT");

bindService(intent, connection, BIND_AUTO_CREATE);

}});//解除绑定(服务会在activity销毁后自动销毁)

unbind_ser.setOnClickListener(newOnClickListener(){

@Overridepublic voidonClick(View v) {

unbindService(connection);

}

});

}

}

fcecaa27ea5212ceb9bf034c36bfbf34.gif

将该程序与服务进行绑定就用到了bindService()方法,看该方法中的参数,第一个是一个intent,第二个是一个ServiceConnection类,与服务建立连接,接收到onBind()传输的数据。从这个方法中我们就得到了传递过来的对象。运行客户端程序

aa33a943af87d8fb64ec6f15109a8777.png

点击第一个按钮后会显示出来一个Person对象的信息。这就说明数据从服务端传输了过来。

LogCat输出的信息

2224870dbc9f6d3ec86e054d95b6475f.png

原文:http://www.cnblogs.com/xinyuyu/p/3718678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值