Androidでのシーケンス化について

14932 ワード

転載は原文のリンクを添付してください.http://blog.csdn.net/a774057695/article/details/50440617
まず、確かに何かを書きたいと思って、自分がまだ書き続けていることを慰めたいと思っています.
これを書いて、ただ考えの中にこれがあるだけで、この間何人かの研修を受けたばかりの新人を面接したとき、霊性があるかどうかを聞いて、今xmlを使うのが少なすぎるので、ついでにjsonの解析ライブラリが使うかどうかを聞いて、例えばfastjson、(もちろん深く聞かないで、結局出たばかりです)、それから目的があって1つの霊性があるかどうかを見て、考えるのが苦手な問題を聞きました:app内はactivityにまたがって値を伝えて、相手を伝えるのはどのようにして、すべてparcelableインタフェースのものに答えて、他の省力の方法があるかどうかを尋ねる時、jsonを使うと言う人はいません.では、この記事では、関連する内容を振り返ってみましょう.
parcelableインタフェースについて話す前に、Javaのシーケンス化Serializableを見てみましょう.
1、まず振り返ってみると、シーケンス化と逆シーケンス化とは何か、純粋に定義されているのではないでしょうか.
Serialization(シーケンス化)は、オブジェクトを一連のバイトで記述するプロセスである.
deserialization(逆シーケンス化)は、一連のバイトをオブジェクトに再構築するプロセスです.
すなわち,ここではオブジェクト,一連のバイトにのみ関与する.2、では、どのようなシナリオをシーケンス化する必要がありますか.a)1つのオブジェクトを「一連のバイト」として保存する場合、例えば1つのファイル、データベースに書く.b)ソケットを用いてネットワーク上でオブジェクトを転送する場合,フローを思い浮かべる.
c)プロセス間でオブジェクトをシーケンス化して転送する場合--これは我々の問題と関係がある
3、シーケンス化はどうしますか.JAvaでは、シーケンス化が必要なクラスをSerializableインタフェースに実装すればよいが、Serializableインタフェースにはメソッドが定義されていないことに注意してください.4、シーケンス化と逆シーケンス化demo
オブジェクトをシーケンス化し、まずいくつかのOutputStream(FileOutputStream、ByteArrayOutputStreamなど)を作成し、これらのOutputStreamをObjectOutputStreamにカプセル化します.
次にwriteObject()メソッドを呼び出すと、オブジェクトをシーケンス化してOutputStreamに送信できます.
注:シーケンス化はオブジェクト、バイトにのみ関連しているため、Reader、Writerなど文字に関連するものは使用できません.
当然のことながら、逆シーケンスは、1つのInputStream(例えばFileInputstream、ByteArrayInputStreamなど)をObjectInputStream内にカプセル化し、readObject()を呼び出すことで、所望のオブジェクトを得ることができる.
以下は、Testクラスのシーケンス化を実現するdemoです.
package test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * @ClassName: Serialization
 * @Description: TODO
 * @date 2015 12 31    11:56:46
 * 
 * @author leobert.lan
 * @version 1.0
 */
public class Serialization {

	public static void main(String[] args) {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream("my.out"));
			Test mTest = new Test();
			mTest.str1 = "111";
			mTest.str2 = "222";
			oos.writeObject(mTest);
			oos.flush();
			oos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		deserialization();
	}

	/** 
	 * @Title: deserialization 
	 * @Description:     
	 * @author: leobert.lan    
	 */
	public static void deserialization() {
		ObjectInputStream oin = null;
		try {
			oin = new ObjectInputStream(new FileInputStream("my.out"));
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		Test test = null;
		try {
			test = (Test) oin.readObject();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("str1 :" + test.str1);
		System.out.println("str2 :" + test.str2);

	}
}

class Test implements Serializable {
	/**
	 * serialVersionUID:TODO(              ).
	 */
	private static final long serialVersionUID = 1L;
	String str1;
	String str2;
}

5、シリアル化ID、serialVersionUID
先ほどのコードに静的定数が表示されました:serialVersionUID
その役割は、簡単に言えば、Javaのシーケンス化メカニズムは、実行時にクラスのserialVersionUIDを判断することによってバージョンの一貫性を検証することです.
シーケンスIDはEclipseの下で2つの生成戦略を提供し、1つは固定された1 Lであり、1つはランダムに重複しないlongタイプのデータを生成する(実際にはJDKツールを使用して生成されたという人もいれば、さらには現在のクラス構造に基づいてハッシュされたという人もいる).
6.シーケンス化前とシーケンス化後のオブジェクトが一致していることに関心を持っている可能性がありますか?
さらに,同じオブジェクトなのか,それとも2つのコンテンツが一致しているオブジェクトなのかに関心を持つ.
もちろん2つのオブジェクトですが、コンテンツが一致しているだけで、メモリアドレスが一致していません.つまり、そのうちの1つを操作し、もう1つは影響を受けません.「シーケンス化により、Serializableオブジェクトの深さコピー(deep copy)」を実現できます.-これは、基本オブジェクトとその参照だけでなく、オブジェクトネットワーク全体をコピーすることを意味します.同じ一流のオブジェクトのアドレスは同じで、同じオブジェクトであることを示しますが、他のストリームのオブジェクトアドレスとは異なります.つまり、単一ストリームにシーケンス化すれば、私たちが書いたときと同じオブジェクトネットワークを復元できます.同じ一流であれば、オブジェクトは同じです.」
次の点に注意してください.
1クラスの静的定数はクラスレベルであり、対象レベルではないため、serialVersionUIDはシーケンス化されない(形而上の理解はしないでください).
2親クラスがシーケンス化されると、子クラスはシーケンス化されます.シーケンス化はSerializableインタフェースを実現することによって行われるからである.3あるオブジェクトのインスタンス変数が他のオブジェクトを参照し、そのオブジェクトをシーケンス化するときも参照オブジェクトをシーケンス化する.
4 transient修飾変数はシーケンス化できません
上の内容はjavaでのシーケンス化ですが、Androidでのシーケンス化を見てみましょう
AndroidはもちろんjavaのようにSerializableインタフェースを使用してシーケンス化することができますが、推奨されていません.またParcelableインタフェースを実現することもできます.これはAndroid特有で、Serializableインタフェースを実現するよりも効率が高く、Intentと組み合わせてデータを伝達することができ、プロセス間通信(IPC)にも使用できます.実装Parcelableインタフェースは比較的複雑です.
AndroidでIntentオブジェクトを渡すには、次の2つの方法があります.
1:Bundle.putSerializable(Key,Object);Serializableインタフェースの実装が必要
2::Bundle.putParcelable(Key,Object);Parcelableインタフェースの実装が必要
1.parcelableインタフェースの内容を理解する
public interface Parcelable {
    /**
     * Flag for use with {@link #writeToParcel}: the object being written
     * is a return value, that is the result of a function such as
     * "<code>Parcelable someFunction()</code>",
     * "<code>void someFunction(out Parcelable)</code>", or
     * "<code>void someFunction(inout Parcelable)</code>".  Some implementations
     * may want to release resources at this point.
     */
    public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001;
    
    /**
     * Bit masks for use with {@link #describeContents}: each bit represents a
     * kind of object considered to have potential special significance when
     * marshalled.
     */
    public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001;
    
    /**
     * Describe the kinds of special objects contained in this Parcelable's
     * marshalled representation.
     *  
     * @return a bitmask indicating the set of special object types marshalled
     * by the Parcelable.
     */
    public int describeContents();
    
    /**
     * 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}.
     */
    public void writeToParcel(Parcel dest, int flags);

    /**
     * Interface that must be implemented and provided as a public CREATOR
     * field that generates instances of your Parcelable class from a Parcel.
     */
    public interface Creator<T> {
        /**
         * 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.
         */
        public T createFromParcel(Parcel source);
        
        /**
         * Create a new array of the Parcelable class.
         * 
         * @param size Size of the array.
         * @return Returns an array of the Parcelable class, with every entry
         * initialized to null.
         */
        public T[] newArray(int size);
    }

    /**
     * Specialization of {@link Creator} that allows you to receive the
     * ClassLoader the object is being created in.
     */
    public interface ClassLoaderCreator<T> extends Creator<T> {
        /**
         * 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()} and
         * using the given ClassLoader.
         *
         * @param source The Parcel to read the object's data from.
         * @param loader The ClassLoader that this object is being created in.
         * @return Returns a new instance of the Parcelable class.
         */
        public T createFromParcel(Parcel source, ClassLoader loader);
    }
}
androidのソースコードを直接copyしました
では、インタフェースを実現した後、どのような仕事をしますか?
1.describeContents()を書き換え、デフォルトでは0を返してOKです.
2.writeToParcel()を書き換える.この方法はオブジェクトを1つのParcelオブジェクトにシーケンス化する.すなわち、クラスのデータを外部から提供されたParcelに書き込み、Parcelコンテナからデータを取得するために伝達する必要があるデータをパッケージ化する.3.静的内部オブジェクトCREATOR実装インタフェースParcelable.Creatorをインスタンス化する
例を示します.
package com.example.androidtest;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;


public class MainActivity extends Activity {
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre">		</span>super.onCreate(savedInstanceState);
<span style="white-space:pre">		</span>setContentView(R.layout.activity_main);
<span style="white-space:pre">		</span>Test t = new Test();
<span style="white-space:pre">		</span>t.setmIntData(1);
<span style="white-space:pre">		</span>t.setmStringData("str");
<span style="white-space:pre">		</span>Intent i = new Intent(MainActivity.this,SecondActivity.class);
<span style="white-space:pre">		</span>Bundle b = new Bundle();
<span style="white-space:pre">		</span>b.putParcelable("key", t);
<span style="white-space:pre">		</span>i.putExtras(b);
<span style="white-space:pre">		</span>startActivity(i);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>
}


class Test implements Parcelable {
<span style="white-space:pre">	</span>private int mIntData;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>private String mStringData;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public int getmIntData() {
<span style="white-space:pre">		</span>return mIntData;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public void setmIntData(int mIntData) {
<span style="white-space:pre">		</span>this.mIntData = mIntData;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public String getmStringData() {
<span style="white-space:pre">		</span>return mStringData;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public void setmStringData(String mStringData) {
<span style="white-space:pre">		</span>this.mStringData = mStringData;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public int describeContents() {
<span style="white-space:pre">		</span>return 0;
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public void writeToParcel(Parcel out, int flags) {
<span style="white-space:pre">		</span>out.writeInt(mIntData);
<span style="white-space:pre">		</span>out.writeString(mStringData);
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>public static final Parcelable.Creator<Test> CREATOR = new Parcelable.Creator<Test>() {
<span style="white-space:pre">		</span>public Test createFromParcel(Parcel in) {
<span style="white-space:pre">			</span>return new Test(in);
<span style="white-space:pre">		</span>}


<span style="white-space:pre">		</span>public Test[] newArray(int size) {
<span style="white-space:pre">			</span>return new Test[size];
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>};


<span style="white-space:pre">	</span>private Test(Parcel in) {
<span style="white-space:pre">		</span>mIntData = in.readInt();
<span style="white-space:pre">		</span>mStringData = in.readString();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public Test() {}
}

package com.example.androidtest;


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




public class SecondActivity extends Activity {
<span style="white-space:pre">	</span>private final String tag = "SecondActivity";
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre">		</span>super.onCreate(savedInstanceState);
<span style="white-space:pre">		</span>setContentView(R.layout.activity_second);
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>Intent i = getIntent();
<span style="white-space:pre">		</span>Test t = i.getParcelableExtra("key");
<span style="white-space:pre">		</span>Log.d(tag, "int data:"+t.getmIntData()+"\r
String data:"+t.getmStringData()); <span style="white-space:pre"> </span>} }

とにかく、使うときは煩わしいので、たくさん書く必要があります.そして、とても重要なのは、
public void writeToParcel(Parcel out, int flags) {
<span>		</span>out.writeInt(mIntData);
<span>		</span>out.writeString(mStringData);
<span>	</span>}

<span>	</span>private Test(Parcel in) {
<span>		</span>mIntData = in.readInt();
<span>		</span>mStringData = in.readString();
<span>	</span>}

この2つの方法は書く順序と読む順序が一致しなければならない.
私のように頭を働かすのが好きな人は、そんなことをするのが好きではありません.jsonで伝えてくれた人がいつ思ったのかは分からないけど.
オブジェクトをjson(Stringフォーマット)に変換します.stringは複雑なフォーマットではないので、直接putStringExtraでいいです(注意、1つのStringデータしか伝えられません)、複数がほしいので、ArrayListにします.逆に考えると、jsonは非常に良いフォーマットであり、バイト(私たちが伝えたString)であり、オブジェクトを正確に記述することができます.
この文章を書くのは、ただ何かを書きたいだけで、再び自分の意識を深めたいだけです.本当に問題を考えて、もっと多くのことを得ることができます.