Android Parcelable的介紹與使用


Parcelable使用的一個地方就是在進程間傳遞一個自定義的較為復雜的對象,對Parcelable學習了一下寫下自己的觀點。

將一個對象比如說一個名字為Cartoon的自定義類,由一個activity傳遞到另外一個activity去,這個時候就要用到Parcelable了。首先我們先構建一個bean。

package com.example.sendobjfromactivity.bean;

import android.graphics.Bitmap;

public class Cartoon {
    private Bitmap figure;
    private String name;
    private String creator;
    
    public Bitmap getFigure() {
        return figure;
    }
    public void setFigure(Bitmap figure) {
        this.figure = figure;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCreator() {
        return creator;
    }
    public void setCreator(String creator) {
        this.creator = creator;
    }
}

這就是我們要傳輸的數據的格式,下面就思考,要將其在線程間進行傳輸,就要對其實現序列化,在Android中也就是實現Parcelable接口,這個借口中需要我們實現的主要方法有writeToParcel,describe,ContentsParcelable.Creator<?>。完成完成序列化是依靠writeToParcel方法,而對對象進行反序列化並且返回一個對象實例的是依靠ContentsParcelable.Creator<?>。

下面來看這樣一段代碼,ParcelableCartoon類實現了Parcelable接口

package com.example.sendobjfromactivity.bean;

import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

public class ParcelableCartoon implements Parcelable {

    private Cartoon cartoon;
    private static final String MSG = "MESSAGE"; 
    
    public ParcelableCartoon(Cartoon cartoon){
        Log.i(MSG, "ParcelableCartoon::ParcelableCartoon@Cartoon");
        this.cartoon = cartoon;
    }
    
    // 將對象寫入Parcel容器中去
    // 完成對對象的序列化
    /**
     * Flatten this object in to a Parcel.
     * 
     * @param dest The Parcel in which the object should be written.
     * @param flags Additional flags about how the object should be written.
     * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Log.i(MSG, "ParcelableCartoon::writeToParcel");
        dest.writeString(cartoon.getName());
        dest.writeString(cartoon.getCreator());
        dest.writeParcelable(cartoon.getFigure(), PARCELABLE_WRITE_RETURN_VALUE);
    }
    
    
    // 完成對序列化的對象反序列化
    public static final Parcelable.Creator<ParcelableCartoon> CREATOR = new Parcelable.Creator<ParcelableCartoon>(){
        // 從Parcel容器中獲取序列化的對象,並將其反序列化,得到該對象的實例
        /**
         * Create a new instance of the Parcelable class, instantiating it
         * from the given Parcel whose data had previously been written by
         * {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
         * 
         * @param source The Parcel to read the object's data from.
         * @return Returns a new instance of the Parcelable class.
         */
        @Override
        public ParcelableCartoon createFromParcel(Parcel source) {
            Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::createFromParcel");
            return new ParcelableCartoon(source);
        }

        @Override
        public ParcelableCartoon[] newArray(int size) {
            Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::newArray");
            return new ParcelableCartoon[size];
        }
        
    };
    
    public ParcelableCartoon(Parcel in){
        Log.i(MSG, "ParcelableCartoon::ParcelableCartoon@Parcel");
        cartoon = new Cartoon();
        String name = in.readString();
        
        cartoon.setName(name);
        cartoon.setCreator(in.readString());
        cartoon.setFigure((Bitmap)in.readParcelable(Bitmap.class.getClassLoader()));
    }
    
    public Cartoon getCartoon() {
        Log.i(MSG, "ParcelableCartoon::getCartoon");
        return cartoon;
    }
    
    @Override
    public int describeContents() {
        Log.i(MSG, "ParcelableCartoon::describeContents");
        return 0;
    }
}

在該類中用英文的注釋引用了Android文檔中的注釋。在該類中涉及到一個Parcel,它是一個容器,它的主要任務是對需要序列化的對象進行寫入,對需要反序列化的對象進行寫出(構造一個實例)。

完成了這些,就可以對對象進行序列化了,也就是說我們可以傳遞對象了。

下面完成倆個activity,一個負責發送數據,一個用來接收數據。

SendObjFromActivity.java完成發送

package com.example.sendobjfromactivity;

import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.sendobjfromactivity.bean.Cartoon;
import com.example.sendobjfromactivity.bean.ParcelableCartoon;

public class SendObjFromActivity extends Activity {
    
    private Button sendData;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sendData = (Button)this.findViewById(R.id.button1);
        sendData.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                Cartoon cartoon = new Cartoon();
                cartoon.setName("Android");
                cartoon.setCreator("Google");
                InputStream is = getResources().openRawResource(R.drawable.ic_launcher);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                cartoon.setFigure(bitmap);

                Intent intent = new Intent(SendObjFromActivity.this, ReceiveObjActivity.class);
                // 完成對象的序列化操作
                ParcelableCartoon parcelableCartoon = new ParcelableCartoon(cartoon);
                intent.putExtra("msg", parcelableCartoon);
                startActivity(intent);
                
            }});
    }
}

 ReceiveObjActivity.java完成對數據的接收

package com.example.sendobjfromactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.sendobjfromactivity.bean.Cartoon;
import com.example.sendobjfromactivity.bean.ParcelableCartoon;

public class ReceiveObjActivity extends Activity {
    
    private ImageView showImage;
    private TextView showText;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i("MESSAGE", "進入到了另外的一個activity中去");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.display_obj);
        showImage = (ImageView)this.findViewById(R.id.imageView1);
        showText = (TextView)this.findViewById(R.id.textView1);
        
        Intent intent = getIntent();
        ParcelableCartoon parcelableCartoon = (ParcelableCartoon) intent
                .getParcelableExtra("msg");
        Cartoon cartoon = parcelableCartoon.getCartoon();
        showImage.setImageBitmap(cartoon.getFigure());
        showText.setText(cartoon.getName()+"\n"+cartoon.getCreator());
    }
}

在這個程序中會調用Parcelable.Creator<ParcelableCartoon>內的方法,來完成反序列化。

需要到兩個xml布局文件:display_obj.xml,main.xml。比較簡單不再敘述。

在AndroidManifest.xml中配置下activity。這樣就完成了一個小的數據傳輸程序了,看下運行結果

 

在控制台中輸出來的信息

這樣可以看出來Parcelable的運行方式以及順序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM