Android中的Parcel机制 实现Bundle传递对象
Android中的Parcel机制
实现了Bundle传递对象
使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parcel机制,即,Android实现的轻量级的高效的对象序列化和反序列化机制。
JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。
Android中的新的序列化机制
在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,
Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。
Android中序列化有以下几个特征:
1. 整个读写全是在内存中进行,所以效率比JAVA序列化中使用外部存储器会高很多;
2. 读写时是4字节对齐的
3. 如果预分配的空间不够时,会一次多分配50%;
4. 对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。
package com.parcel.main; import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MyTestParcelActivity extends Activity { public final static int Sub_Main = ;
public final static int Sub_2_Main = ; private Button setSubMain;
private Button setSub2Main;
private TextView mTextView; private Drawable defDrawable;
private MyParcel mMyParcel = new MyParcel();
private BinderMyParcel mBinderMyParcel = new BinderMyParcel(); /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); initComponent();
} private void initComponent() {
setSubMain = (Button) findViewById(R.id.btn01);
if (setSubMain != null) {
setSubMain.setOnClickListener(setSubMainXML);
} setSub2Main = (Button) findViewById(R.id.btn04);
if (setSub2Main != null) {
setSub2Main.setOnClickListener(setSub2MainXML);
} mTextView = (TextView) findViewById(R.id.main_tv);
defDrawable = mTextView.getBackground();
} private View.OnClickListener setSubMainXML = new OnClickListener() { @Override
public void onClick(View v) {
Intent mIntent = new Intent();
if (mMyParcel != null) {
mMyParcel.setColor(Color.RED);
mIntent.putExtra("MyColor", mMyParcel);
}
mIntent.setClass(MyTestParcelActivity.this,
SubMyTestParcelActivity.class); mTextView.setBackgroundDrawable(defDrawable); startActivityForResult(mIntent, Sub_Main);
}
};
private View.OnClickListener setSub2MainXML = new OnClickListener() { @Override
public void onClick(View v) {
Intent intent = new Intent();
if (mBinderMyParcel != null) {
mBinderMyParcel.setColor(Color.MAGENTA);
intent.putExtra("BinderMyColor", mBinderMyParcel);
}
intent.setClass(MyTestParcelActivity.this,
Sub2MyTestParcelActivity.class); mTextView.setBackgroundDrawable(defDrawable); startActivityForResult(intent, Sub_2_Main);
}
}; @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == Sub_Main) {
if (data.hasExtra("MyColor")) {
/**
* color=data.getParcelableExtra("MyColor"),
* 这说明反序列化后是一个新的MyColor对象
*
* 如果数据本身是IBinder类型,那么反序列化的结果就是原对象,而不是新建的对象
*/
mMyParcel = data.getParcelableExtra("MyColor");
((TextView) findViewById(R.id.main_tv))
.setTextColor(mMyParcel.getColor());
}
} else if (requestCode == Sub_2_Main) {
if (data.hasExtra("BinderMyColor")) {
((TextView) findViewById(R.id.main_tv))
.setBackgroundColor(mBinderMyParcel.getColor());
}
}
}
} @Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
} }
使用非binder类型代码
package com.parcel.main; import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class SubMyTestParcelActivity extends Activity implements
OnClickListener { private Button setSub2XML;
private TextView mTextView;
private MyParcel myColor; private Drawable defDrawable; /** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.submain); setSub2XML = (Button) findViewById(R.id.btn02);
setSub2XML.setOnClickListener(this); mTextView = (TextView)findViewById(R.id.sub_tv);
defDrawable = mTextView.getBackground(); Intent intent = getIntent();
if (intent != null) {
if (intent.hasExtra("MyColor")) {
myColor = intent.getParcelableExtra("MyColor");
mTextView.setBackgroundColor(myColor.getColor());
}
}
} @Override
protected void onStart() {
super.onStart();
} @Override
protected void onRestart() {
super.onRestart();
} @Override
protected void onResume() {
super.onResume();
} @Override
protected void onPause() {
super.onPause();
} @Override
protected void onStop() {
super.onStop();
} @Override
protected void onDestroy() {
super.onDestroy();
} @Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn02:
Intent mIntent = new Intent(getApplicationContext(),
Sub2MyTestParcelActivity.class);
if (myColor != null) {
myColor.setColor(Color.GREEN);
mIntent.putExtra("MyColor", myColor);
} mTextView.setBackgroundDrawable(defDrawable);
setResult(RESULT_OK, mIntent);
finish();
break; default:
break;
}
} }
使用binder类型代码
package com.parcel.main; import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class Sub2MyTestParcelActivity extends Activity implements
OnClickListener { private Button setMainXML;
private TextView mTextView;
private BinderMyParcel myColor; private Drawable defDrawable; /** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.sub2main); setMainXML = (Button) findViewById(R.id.btn03);
setMainXML.setOnClickListener(this); mTextView = (TextView) findViewById(R.id.sub_tv);
defDrawable = mTextView.getBackground(); Intent intent = getIntent();
if (intent != null) {
if (intent.hasExtra("BinderMyColor")) {
myColor = intent.getParcelableExtra("BinderMyColor");
mTextView.setBackgroundColor(myColor.getColor());
}
}
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn03:
Intent mIntent = new Intent(getApplicationContext(),
MyTestParcelActivity.class);
if (myColor != null) {
myColor.setColor(Color.WHITE);
mIntent.putExtra("BinderMyColor", myColor);
} mTextView.setBackgroundDrawable(defDrawable);
setResult(RESULT_OK, mIntent);
finish();
break; default:
break;
}
} }
非Binder类型的Parcel,实现Parcelable接口即可:
package com.parcel.main; import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable; public class MyParcel implements Parcelable {
private int color = Color.BLACK; public int getColor() {
return color;
} public void setColor(int color) {
this.color = color;
} public MyParcel() {
color = Color.BLACK;
} public MyParcel(Parcel in) {
color = in.readInt();
} @Override
public int describeContents() {
return ;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(color);
} public static final Parcelable.Creator<MyParcel> CREATOR = new Parcelable.Creator<MyParcel>() { public MyParcel createFromParcel(Parcel in) {
return new MyParcel(in);
} public MyParcel[] newArray(int size) {
return new MyParcel[size];
}
}; }
对于Binder类型,首先要实现一个Binder接口(其,最主要的区别在于反序列化仍然是原来的对象,而非Binder类型的反序列化并不是原来的对象,所以在MainActivity中的onActivityResult方法中会出现mMyParcel = data.getParcelableExtra("MyColor")的写法):
package com.parcel.main;
import android.os.Binder;
public class BinderData extends Binder {
public int color;
}
其次再实现Parcelable接口:
package com.parcel.main; import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable; public class BinderMyParcel implements Parcelable { private BinderData data = new BinderData(); public BinderMyParcel() {
data.color = Color.BLUE;
} public BinderMyParcel(Parcel in) {
data = (BinderData) in.readValue(BinderData.class.getClassLoader());
} public void setColor(int color) {
data.color = color;
} public int getColor() {
return data.color;
} @Override
public int describeContents() {
return ;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(data);
} public static final Parcelable.Creator<BinderMyParcel> CREATOR = new Creator<BinderMyParcel>() { @Override
public BinderMyParcel[] newArray(int size) {
return new BinderMyParcel[size];
} @Override
public BinderMyParcel createFromParcel(Parcel source) {
return new BinderMyParcel(source);
}
};
}
三个XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/main_tv" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/main_activity" />
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:text="SetSubMainXML" android:id="@+id/btn01"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
<Button android:id="@+id/btn04" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:text="SetSub2MainXML" />
</LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/sub_tv" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/sub_activity" />
<Button android:text="setMainXML" android:id="@+id/btn02"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/sub_tv" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/sub2_activity" />
<Button android:text="setMainXML" android:id="@+id/btn03"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
Android中的Parcel机制 实现Bundle传递对象的更多相关文章
- 探索Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...
- Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流当中,在需要时重新生成对象.主要应用是利用外部存储设备保存对象状态, ...
- Android中的Parcel机制(下)
上一篇中我们透过源码看到了Parcel背后的机制,本质上把它当成一个Serialize就可以了,只是它是在内存中完成的序列化和反序列化,利用的是连续的内存空间,因此会更加高效. 我们接下来要说的是Pa ...
- 在Android中通过Intent使用Bundle传递对象
IntentBundle传递对象SerializableParcelable Android开发中有时需要在应用中或进程间传递对象,下面详细介绍Intent使用Bundle传递对象的方法.被传递的对象 ...
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
- 浅析Android中的消息机制(转)
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 重温Android中的消息机制
引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...
随机推荐
- CodeFile与CodeBehind的区别
引自:http://blog.163.com/wentworth0119@126/blog/static/17321924220122852720103/ asp.net发布项目之后 存在" ...
- JVM内存模型以及垃圾收集策略解析
http://xmuzyq.iteye.com/blog/599750 一 JVM内存模型 1.1 Java栈 Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程. ...
- ASP.NET MVC(一) 什么是Razor
Razor 是一种向网页添加基于服务器的代码的标记语法 Razor 不是编程与语言.它是服务端标记语言. 当网页被写入浏览器时,基于服务器的代码能够创建动态内容.在网页加载时,服务器在向浏览器返回页面 ...
- Windows Server 2008安装Memcached笔记
分布式缓存系统Memcached简介与实践 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载.缓存是解决这个问题的好办法.但是ASP.NET中的虽然 ...
- 使用instsrv.exe+srvany.exe将应用程序安装为windows服务[转]
转自:http://qingmu.blog.51cto.com/4571483/1248649 一.什么是instsrv.exe和srvany.exe instsrv.exe.exe和srvany ...
- Visual C++ 打印编程技术-编程基础-映射模式
映射模式: Visual C++ 中采用的坐标映射方式使得用户图形坐标和输出设别的像素完全一致. eg:当屏幕的像素大小为800X600时,每英寸包含屏幕像素为96,打印机则需要几倍的点数才能达到同样 ...
- iOS-开发日志-UIButton
UIButton属性 1.UIButton状态: UIControlStateNormal // 正常状态 UIControlStateHighlighted // 高 ...
- 飞锐GIS开发基础系列
3s知识库和GIS科研站,未经允许,禁止任何形式的复制.转载和传播.联系方式:276888624@qq.com 品GIS,品开发,品人生...... http://www.3sbase.com/3sb ...
- bzoj1068:[SCOI2007]压缩
思路:区间dp,设状态f[l][r][bo]表示区间[l,r]的答案,bo=1表示该区间可以放M也可以不放M,bo=0表示该区间不能放M,并且对于任意一个状态f,l和l-1之间均有一个M,于是就可以进 ...
- 【实习记】2014-09-01从复杂到简单:一行命令区间查重+长整型在awk中的bug
9月1号,导出sql文件后,想到了awk,但很复杂.想到了用sed前期处理+python排序比较的区间查重法.编写加调试用了约3小时. 9月2号,编写C代码的sql语句过程中,发现排序可以交m ...