Android中的Parcel机制 实现Bundle传递对象
来源:互联网 发布:青少年行知实践园地图 编辑:程序博客网 时间:2024/06/06 01:33
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 = 1;
- public final static int Sub_2_Main = 2;
- 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);
- }
- }
- 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;
- }
- }
- }
- 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 0;
- }
- @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 0;
- }
- @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机制 实现Bundle传递对象
- 简要分析Android中的Intent,Bundle,Parcel中的数据传递
- Android中的Parcel机制
- 安卓bundle传递序列化对象RuntimeException: Parcel android.os.Parcel@8325970: Unmarshalling unknown type code
- 探索Android中的Parcel机制
- 探索Android中的Parcel机制
- 关于Android中的Parcel机制
- 探索Android中的Parcel机制
- 探索Android中的Parcel机制
- Android中的Parcel机制(上)
- Android中的Parcel机制(下)
- 探索Android中的Parcel机制
- android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
- android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
- android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
- android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
- android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
- 编程之美-斐波那契(Fibonacci)数列方法整理
- 电子签章
- 开发利器--JSONVIEW插件 网页json数据直接转换
- 分布式与集群的区别
- codeforces 593E(矩阵类题目)
- Android中的Parcel机制 实现Bundle传递对象
- java访问修饰符(public……)
- php 框架 laravel安装
- 【深入Java虚拟机】之八:Java垃圾收集机制
- 点击空白处回收键盘
- 网络常用的数据结构
- 禁止ViewPager向右滑动
- 国外PHP学习网站书籍资料汇总
- [前端] 重复字符串函数