zoukankan      html  css  js  c++  java
  • Android中的Parcel和Parcelable

    对于Android来说传递复杂类型,主要是将自己的类转换为基础的字节数组,Activity之间传递数据是通过Intent实现的。 Android序列化对象主要有两种方法,实现Serializable接口、或者实现Parcelable接口。实现Serializable接口是JavaSE本身就支持的,而Parcelable是Android特有的功能,效率比实现Serializable接口高,而且还可以用在进程间通信(IPC)中。实现Serializable接口非常简单,声明一下就可以了。而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。

    Parcel 在英文中有两个意思,其一是名词,为包裹,小包的意思; 其二为动词,意为打包,扎包。邮寄快递中的包裹也用的是这个词。Android采用这个词来表示封装消息数据。这个是通过IBinder通信的消息的载体。需要明确的是Parcel用来存放数据的是内存(RAM),而不是永久性介质(Nand等)。

    Parcelable,定义了将数据写入Parcel,和从Parcel中读出的接口。一个实体(用类来表示),如果需要封装到消息中去,就必须实现这一接口,实现了这一接口,该实体就成为“可打包的”了。

    Parcelable接口的作用:实现了Parcelable接口的实例可以将自身的状态信息(状态信息通常指的是各成员变量的值)写入Parcel,也可以从Parcel中恢复其状态。Parcel用来完成数据的序列化传递。下面就介绍一下实现Parcelable接口的方法。

    通过实现Parcelable接口序列化对象的步骤:

    1. 实现Parcelable接口。

    2. 实现Parcelable接口的public void writeToParcel(Parcel dest, int flags)方法 。

    3. 自定义类型中必须含有一个名称为CREATOR的静态成员,该成员对象要求实现Parcelable.Creator接口及其方法。

    简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。 clip_image002

    在实现Parcelable的实现中,规定了必须定义一个静态成员, 初始化为嵌入接口的实现类。

    Intent 可以携带对象来在不同的Activity中传递数据,要传递的数据必须实现三个方法

    1. describeContents()返回0就可以

    2. writeToParcel(Parcel parcel, int flag) 把需要写入的数据写入Parcel中,然后框架调用此方法发送给接收端的Activity

    3. public static final Parcelable.Creator<ParcelableObject> CREATOR 外部类反序列化该类时调用此方法

    一定要注意:写入parcel和反序列化parcel时顺序一定要相同,不然数据会出错

    案例介绍:

    /**  
    
     * ParcelableObject.java  
    
     * com.androidtest.parcelable  
    
     *  
    
     * Function: TODO  
    
     *  
    
     *   ver     date           author  
    
     * ──────────────────────────────────  
    
     *           2011-5-11      Leon  
    
     *  
    
     * Copyright (c) 2011, TNT All Rights Reserved.  
    
    */  
    
       
    
    package com.androidtest.parcelable;  
    
       
    
    import android.os.Parcel;  
    
    import android.os.Parcelable;  
    
       
    
    /**  
    
     * ClassName:ParcelableObject 需要实现三个方法,describeContents()返回0就可以 、 writeToParcel(Parcel parcel, int flag)  
    
     * 写入Parcel和public static final Parcelable.Creator  
    
    <parcelableobject><span style="font-size: 14px"> CREATOR 供外部类反序列化该类  
    
     * 一定要注意顺序后面这个两个函数读和写的顺序要相同,不然数据会出错  
    
     * Function: TODO  
    
     * Reason:   TODO ADD REASON  
    
     *  
    
     * @author   Leon  
    
     * @version  
    
     * @since    Ver 1.1  
    
     * @Date     2011-5-11  
    
     */  
    
    public class ParcelableObject implements Parcelable{  
    
        private  String  name  ;  
    
        private  String  surName ;  
    
        private  int     age ;   
    
       
    
        public String getName() {  
    
            return name;  
    
        }  
    
       
    
        public void setName(String name) {  
    
            this.name = name;  
    
        }  
    
       
    
        public String getSurName() {  
    
            return surName;  
    
        }  
    
       
    
        public void setSurName(String surName) {  
    
            this.surName = surName;  
    
        }  
    
       
    
        public int getAge() {  
    
            return age;  
    
        }  
    
       
    
        public void setAge(int age) {  
    
            this.age = age;  
    
        }  
    
       
    
        @Override  
    
        public int describeContents() {  
    
       
    
            // TODO Auto-generated method stub  
    
            return 0;  
    
       
    
        }  
    
       
    
        @Override  
    
        public void writeToParcel(Parcel dest, int flag) {  
    
       
    
            // TODO Auto-generated method stub  
    
       
    
            dest.writeInt(age);  
    
            dest.writeString(name);  
    
            dest.writeString(surName);  
    
       
    
        }  
    
        public static final Parcelable.Creator CREATOR = new Creator() {  
    
       
    
            @Override  
    
            public ParcelableObject createFromParcel(Parcel source) {  
    
       
    
                // TODO Auto-generated method stub  
    
                ParcelableObject parcelableObj = new ParcelableObject();  
    
                parcelableObj.age=source.readInt();  
    
                parcelableObj.surName=source.readString();  
    
                parcelableObj.name = source.readString();  
    
                return parcelableObj;  
    
       
    
            }  
    
       
    
            @Override  
    
            public ParcelableObject[] newArray(int size) {  
    
       
    
                // TODO Auto-generated method stub  
    
                return new ParcelableObject[size];  
    
       
    
            }   
    
       
    
        };  
    
    } 

    ParcelableActivity1 发送的代码:

    package com.androidtest.parcelable;  
    
       
    
    import android.app.Activity;  
    
    import android.content.Intent;  
    
    import android.os.Bundle;  
    
    import android.view.View;  
    
    import android.view.View.OnClickListener;  
    
    import android.widget.Button;  
    
    import android.widget.LinearLayout;  
    
    public class ParcelableActivity1 extends Activity {  
    
       
    
        @Override  
    
        protected void onCreate(Bundle savedInstanceState) {  
    
            // TODO Auto-generated method stub  
    
            super.onCreate(savedInstanceState);  
    
            LinearLayout linearLayout = new LinearLayout(this);  
    
            Button button = new Button(this);  
    
            button.setText("Send Parcelable Object");  
    
            linearLayout.addView(button);  
    
            button.setOnClickListener(new OnClickListener(){  
    
                @Override  
    
                public void onClick(View arg0) {  
    
                    ParcelableObject passObject = new ParcelableObject();  
    
                    passObject.setName("Leon Zhang");  
    
                    passObject.setAge(18);  
    
                    passObject.setSurName("xxx");  
    
       
    
                    Intent intent = new Intent(ParcelableActivity1.this,ParcelableActivity2.class);  
    
    //              使用Bundle发送  
    
    //              Bundle bundle = new Bundle();  
    
    //              bundle.putParcelable("key", passObject);  
    
                    intent.putExtra("key", passObject);  
    
    //              intent.putExtras(bundle);  
    
                    intent.putExtra("key2", "out of bundle");  
    
                    startActivity(intent);  
    
                }  
    
            });  
    
           this.setContentView(linearLayout);  
    
        }  
    
       
    
    } 

    ParcelableActivity2 接收的代码:

    package com.androidtest.parcelable;  
    
       
    
    import android.app.Activity;  
    
    import android.os.Bundle;  
    
    import android.util.Log;  
    
       
    
    public class ParcelableActivity2 extends Activity {  
    
       
    
        private static final String TAG = ParcelableActivity2.class.getSimpleName();  
    
       
    
        @Override  
    
        protected void onCreate(Bundle savedInstanceState) {  
    
       
    
            // TODO Auto-generated method stub  
    
            super.onCreate(savedInstanceState);  
    
            ParcelableObject passObject = this.getIntent()  
    
                    .getParcelableExtra("key");  
    
       
    
            Log.v(TAG, "Name: " + passObject.getName() + " Surname: "  
    
                            + passObject.getSurName() + " Age: "  
    
                            + String.valueOf(passObject.getAge())  
    
                            + " out of bundle is :"  
    
                            + this.getIntent().getStringExtra("key2"));  
    
            Bundle myBundle = this.getIntent().getExtras();  
    
            Log.v(TAG,"XX: "  
    
                            + ((ParcelableObject) myBundle.getParcelable("key"))  
    
                                    .getName()+ " Key2 :"+ myBundle.getString("key2"));  
    
       
    
        }  
    
       
    
    } 

    经过测试发现,当使用Intent传递数据时,如果你自己创建了一个Bundle,则无论要传的数据是否放入Bundle(如直接intent.putExtra("xx" , "xx")),都会放到放到此Bundle中。如果没有创建此Bundle,则会默认创建一个Bundle来存放数据。当取数据时可以先取Bundle再从Bundle中取数据,或者直接取就好了。

    参考:

    http://zuiniuwang.blog.51cto.com/3709988/718330

    http://www.2cto.com/kf/201205/132814.html

    http://blog.csdn.net/dairyman000/article/details/7247619

  • 相关阅读:
    输入挂
    最长递增子序列nlogn的做法
    lca 倍增模版
    讨厌字符串
    js的事件处理与闭包:
    http
    html的语义化
    js性能优化
    js的缓存
    字面量声明和函数式声明
  • 原文地址:https://www.cnblogs.com/kevinhigher/p/2712733.html
Copyright © 2011-2022 走看看