在前面的一篇文章<基于Android应用开发的跨进程通信实现(IPC)>介绍了通过跨进程实现基本数值类型(String)的传递,但是有的时候,需要跨进程实现传递相对较复杂的数据(比如图片之类的资源),而不仅仅是基本数据。那么,如何实现复杂数据跨进程的传递使用呢?这时候就不得不把Parcelable接口搬出来了,假设我们需要跨进程的数据都包装在一个我们自定义的类里面,那么这个类就需要实现Parcelable这个接口了;

下面就以一个Demo来说明如何通过实现Parcelable这个接口实现传递复杂数据;

这个Demo的效果如下:

实现效果:在编辑框中输入相应的姓名(这些姓名要对应服务端中保存的用户信息姓名),点击按钮,将会得到相应的用户信息(姓名、手机号、头像),这些用户信息都是来自与客户端不在同一个进程的服务端的;

这个Demo包括两个应用程序:

1. 服务端应用程序,它的文件组成结构如下:

2.客户端应用程序,它的文件组成结构如下:

通过上面的服务端和客户端应用程序的文件结构可知,它们都共同有Person.java、IMyService.aidl、Person.aidl等文件;

当然通过之前的<基于Android应用开发的跨进程通信实现(IPC)>的介绍可知,要想实现两个应用程序之间跨进程调用,两个应用程序必须共同拥有aidl文件。

下面将介绍这些文件的实现:

1. Person.java:

Person类相当于一个包装用户信息数据的javaBean,该类实现Parcelable接口,是实现跨进程传递复杂数据的自定义类,代码实现如下:

package com.feixun.hu.ipc.service;import java.util.Map;import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;public class Person implements Parcelable
{/*picture集合保存的是头像的Bitmap* 注:此处不能是Drawable,Parcel是不能跨进程传递Drawable类型的,Bitmap类型是可以的*/private Map<String, Bitmap> picture;private String name;private String phone;public Person(String name, String phone, Map<String, Bitmap> picture){this.name = name;this.phone = phone;this.picture = picture;}public Map<String, Bitmap> getPictures() {return picture;}public void setPictures(Map<String, Bitmap> picture) {this.picture = picture;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic int describeContents() {// TODO Auto-generated method stubreturn 0;}//实现Parcel接口必须覆盖实现的方法@Overridepublic void writeToParcel(Parcel dest, int flags) {// TODO Auto-generated method stub/*将Person的成员写入Parcel,* 注:Parcel中的数据是按顺序写入和读取的,即先被写入的就会先被读取出来*/dest.writeString(name);dest.writeString(phone);dest.writeMap(picture);}//该静态域是必须要有的,而且名字必须是CREATOR,否则会出错public static final Parcelable.Creator<Person> CREATOR =new Parcelable.Creator<Person>(){@Overridepublic Person createFromParcel(Parcel source) {// TODO Auto-generated method stub//从Parcel读取通过writeToParcel方法写入的Person的相关成员信息String name = source.readString(); String phone = source.readString();Map<String, Bitmap> picture = source.readHashMap(new ClassLoader() {});//更加读取到的信息,创建返回Person对象return new Person(name, phone, picture);}@Overridepublic Person[] newArray(int size) {// TODO Auto-generated method stub//返回Person对象数组return new Person[size];}};
}

2. Person.aidl:

Person作为实现跨进程传递复杂数据的类必须要创建一个对应的aidl文件对其进行声明,内容如下:

parcelable Person;

3. IMyService.aidl:

该文件和之前的<基于Android应用开发的跨进程通信实现(IPC)>文章中介绍的IMyService.aidl文件的作用一样,是实现跨进程的重要文件实现,内容如下:

package com.feixun.hu.ipc.service;
       import com.feixun.hu.ipc.service.Person;

interface IMyService
      {
          Person getPerson(String name);
       }

IMyService.aidl文件会在应用程序的gen目录中生成对应的IMyService.java文件;

以上这些文件时服务端和客户端必须共同拥有的,服务端实现将用户数据信息保存在客户端的Person对象,而客户端通过跨进程通信(IPC)获取得到服务端保存的那些用户信息数据,然后通过ListView不断添加显示出来;

服务端应用程序的代码实现如下:

IpcService.java

package com.feixun.hu.ipc.service;import java.util.HashMap;
import java.util.Map;import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.IBinder;
import android.os.RemoteException;
public class IpcService extends Service
{//创建一个用于保存Person对象信息的HashMap对象private Map<String, Person>  mPersons = new HashMap<String, Person>();//创建一个用于保存头像图片的HashMap对象private Map<String, Bitmap> mPictures = new HashMap<String, Bitmap>(); ;private ServiceBinder mServiceBinder;private String[] names;private String[] phones;private Bitmap[] pictures;/*初始化用户的姓名、手机号、头像(注:当我们在客户端要检索这些用户信息时,* 输入的用户名必须是names数组中的任意一个)*/private void init(){names = new String[]{"steven", "lisa", "rose", "sara", "masa", "james", "wade", "bosh", "hamslan", "bati"};phones = new String[]{"15898930099", "13909456674", "13465353623", "15984347533", "18694335633", "18945660044", "13844423094", "15899335395", "18754636894", "13986745568"};pictures = new Bitmap[]{getPicture(R.drawable.image1), getPicture(R.drawable.image2),getPicture(R.drawable.image3), getPicture(R.drawable.image4),getPicture(R.drawable.image5), getPicture(R.drawable.image6), getPicture(R.drawable.image7), getPicture(R.drawable.image8),getPicture(R.drawable.image9), getPicture(R.drawable.image10)};for (int i = 0; i < names.length; i++){mPictures.put(names[i], pictures[i]);mPersons.put(names[i] , new Person(names[i], phones[i], mPictures));}}//将Drawable转为Bitmapprivate Bitmap getPicture(int resourceId){BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(resourceId);return bd.getBitmap();}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();init();//person = new Person();//创建ServiceBinder对象(Binder类型对象)mServiceBinder = new ServiceBinder();}/*定义一个继承IMyService接口内部类Stub的实现与客户端通信的Binder类型的类,* IMyService.Stub是Binder类型*/public class ServiceBinder extends IMyService.Stub{@Overridepublic Person getPerson(String name) throws RemoteException {// TODO Auto-generated method stub//根据传进来的用户姓名,返回对应的Person对象return mPersons.get(name);}}@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stub/*与客户端连接时,返回该Binder对象.* 1.如果连接的客户端和该服务端属于同一个进程,则此处直接返回mServiceBinder本身* 2.如果连接的客户端和该服务不属于同一个进程,则返回的是mServiceBinder对象的代理*/return mServiceBinder;}
}

客户端的代码实现如下:

IpcClient.java

package com.feixun.hu.ipc.client;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import com.feixun.hu.ipc.service.IMyService;
import com.feixun.hu.ipc.service.Person;public class IpcClient extends Activity
{private IMyService mIMyService;private ContactAdapter mContactAdapter;private Person mPerson;private Button mGetInfo;private ListView showView;    private EditText mInputName;private List<Person> mPersons;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);//获取各组件mGetInfo = (Button) findViewById(R.id.get);mInputName = (EditText) findViewById(R.id.person);showView = (ListView)findViewById(R.id.show);//创建mPersons集合对象mPersons = new ArrayList<Person>();//创建Intent,对应服务端注册的IntentIntent intent = new Intent();intent.setAction("com.feixun.hu.action.IPC_SERVICE");//绑定连接远程服务bindService(intent, conn, Service.BIND_AUTO_CREATE);//为设置按钮绑定监听mGetInfo.setOnClickListener(new OnClickListener() {        @Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(mInputName.getText() != null ){try {String personName = mInputName.getText().toString();//得到来自远程的Person对象mPersonmPerson = mIMyService.getPerson(personName);if (mPerson != null){getInfo(mPerson);}} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});}//该方法实现在ListView显示从远程得到的相关信息private void getInfo(Person person){//将从远程得到的mPerson对象添加入mPersons集合mPersons.add(person);   //通过远程得到的mPerson对象mContactAdapter = new ContactAdapter(this, mPersons);showView.setAdapter(mContactAdapter);}//实现客户端与服务端绑定的关键部分private ServiceConnection conn = new ServiceConnection() {//解除连接服务端@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubmIMyService = null;}//连接服务端@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stub/*此处实现获取通过IpcService的onBind方法返回的mServiceBinder对象的代理。* 参数service为绑定获得的远程服务IpcService的mServiceBinder对象,* 而调用IMyService.Stub的函数asInterface获取的是mServiceBinder对象的代理。*/mIMyService = IMyService.Stub.asInterface(service);}};@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();//解除绑定unbindService(conn);}//自定义适配器,然后将从远程得到的用户信息在ListView中显示class ContactAdapter extends BaseAdapter{private List<Person> persons = null;private LayoutInflater inflater = null;public ContactAdapter(Context context, List<Person> person){inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);persons = person;//Log.d("MainActivity", "FxAdapter()");}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn persons.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn persons.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent){// TODO Auto-generated method stub//得到来自远程服务端的Person对象Person person = (Person)persons.get(position);ImageView mPictureView = null;TextView mNameView = null;TextView mPhoneView = null;if (convertView == null){convertView = inflater.inflate(R.layout.contact_list, null);}mPictureView = (ImageView)convertView.findViewById(R.id.user_image);//显示头像mPictureView.setImageBitmap(person.getPictures().get(person.getName()));mNameView = (TextView)convertView.findViewById(R.id.name_id);//显示姓名mNameView.setText(person.getName());mPhoneView = (TextView)convertView.findViewById(R.id.phone_id);//显示手机号mPhoneView.setText(person.getPhone());return convertView;}}
}

关于通过实现Parcelable接口来进行程跨进程传递复杂数据的实现就到此结束了,相关代码下载链接地址如下:

http://download.csdn.net/detail/stevenhu_223/5676401

Android中Parcelable接口的应用相关推荐

  1. Android中Parcelable接口用法

    --  通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象.也可以将Parcel看成是一个流,通过writeToPa ...

  2. Android中Parcelable接口用法 和 Serializable实现与Parcelabel实现的区别

    1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. ...

  3. Android中Parcelable与Serializable接口用法

    转自: Android中Parcelable接口用法 1. Parcelable接口 Interface for classes whose instances can be written to a ...

  4. android studio parcelable,Android中Parcelable的使用详解

    Parcelable与Serializable Serializable是Java为我们提供的一个标准化的序列化接口. Parcelable是Android为我们提供的序列化的接口. 对比: 1.Pa ...

  5. Android中 Parcelable 的应用,以及与 Serializable 的对比

    前言 在 Android 应用开发中,经常需要在 Activity 间传递参数,有时还需要传递 Java 对象.而传递对象有两种实现方式,一种是使类实现 android.os.Parcelable 接 ...

  6. Android 中的接口回调

    Android 中的接口回调 转载于:https://www.cnblogs.com/zhujiabin/p/5223806.html

  7. Android中Parcelable的原理和使用方法

    Parcelable的简单介绍 介绍Parcelable不得不先提一下Serializable接口,Serializable是Java为我们提供的一个标准化的序列化接口,那什么是序列化呢? 进行And ...

  8. Android 的Parcelable接口

    此文转载自http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html 1. Parcelable接口 Interface ...

  9. 详细介绍Android中Parcelable的原理和使用方法

    今日推荐 经常阅读博客是个好习惯 推荐技术小黑屋的Blog 引言 本篇文章目的在于详细的理解Parcelable的使用,而不是死记代码 我的简书博客地址 (由于csdn的图片经常出现不显示问题,以后就 ...

最新文章

  1. Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件
  2. UICollectionView详解
  3. nginx upstream配置_Prometheus快速监控Nginx
  4. [九度][何海涛] 栈的压入压出
  5. oracle数据库配置助手来初始化参数,使用服务器参数文件(SPFILE)管理初始化参数...
  6. 《Oracle高性能自动化运维》一一第1章 Linux下的Oracle
  7. IT创业公司如何选型,以避免未来出现的版权之争?
  8. 导数与微分的知识点思维导图_高中物理思维导图,高中三年知识点一个不漏
  9. [转载] numpy.ma详解
  10. python多线程互斥锁_Python中线程互斥锁是什么
  11. 盛京剑客系列17:市场暴跌下投资组合的调整
  12. js对象与this指向
  13. 基于SOM算法的Iris数据分类
  14. pytorch实现猫狗分类+数据集
  15. 吐槽一下:武装GoldenDict时,好一个OALD,RAR格式,12万多的文件,晕!!
  16. Robotium-基础理论介绍
  17. Elasticsearch(二):进阶检索
  18. c语言空格eof什么意思,eof在c语言中表示什么?
  19. AAAI2021知识图谱论文集
  20. ts快捷键 vscode_vscode这篇就够了

热门文章

  1. postgrest和postgreSQL权限认证
  2. Ubuntu下codeblocks安装配置方法及opencv配置方法
  3. Apple Http Live Stream
  4. java计算机毕业设计河东街摊位管理系统MyBatis+系统+LW文档+源码+调试部署
  5. 火狐标签在中间_在Firefox中轻松组织和分组标签
  6. Android样式之drawable
  7. python常用的内置对象有哪些_#【Python】【基础知识】【内置对象常用方法】
  8. win10如何打开文件扩展名(俗称后缀名)?简单易懂!
  9. 物联网下的RFID门禁,图书防盗新变革
  10. 推荐几款基于 Markdown 语法在线制作简历的平台