view的onSaveInstanceState和onRestoreInstanceState
在View文档中对其的说明如下:
protectedvoidonRestoreInstanceState(Parcelablestate)
Since:APILevel1
Hookallowingaviewtore-applyarepresentationofitsinternalstatethathadpreviously
beengeneratedbyonSaveInstanceState().Thisfunctionwillneverbecalledwithanullstate.
Parameters
stateThefrozenstatethathadpreviouslybeenreturnedbyonSaveInstanceState().
SeeAlso
*onSaveInstanceState()
*restoreHierarchyState(SparseArray)
*dispatchRestoreInstanceState(SparseArray)
protectedParcelableonSaveInstanceState()
Since:APILevel1
Hookallowingaviewtogeneratearepresentationofitsinternalstate
thatcanlaterbeusedtocreateanewinstancewiththatsamestate.
Thisstateshouldonlycontaininformationthatisnotpersistentorcannotbereconstructedlater.
Forexample,youwillneverstoreyourcurrentpositiononscreenbecausethatwillbecomputedagain
whenanewinstanceoftheviewisplacedinitsviewhierarchy.
Someexamplesofthingsyoumaystorehere:thecurrentcursorpositioninatextview
(butusuallynotthetextitselfsincethatisstoredinacontentproviderorotherpersistentstorage),
thecurrentlyselectediteminalistview.
Returns
*ReturnsaParcelableobjectcontainingtheview'scurrentdynamicstate,
ornullifthereisnothinginterestingtosave.Thedefaultimplementationreturnsnull.
在TextView文档中对其的说明如下:
publicvoidonRestoreInstanceState(Parcelablestate)
Since:APILevel1
Hookallowingaviewtore-applyarepresentationofitsinternalstate
thathadpreviouslybeengeneratedbyonSaveInstanceState().
Thisfunctionwillneverbecalledwithanullstate.
Parameters
stateThefrozenstatethathadpreviouslybeenreturnedbyonSaveInstanceState().
publicParcelableonSaveInstanceState()
Since:APILevel1
Hookallowingaviewtogeneratearepresentationofitsinternalstate
thatcanlaterbeusedtocreateanewinstancewiththatsamestate.
Thisstateshouldonlycontaininformationthatisnotpersistentorcannotbereconstructedlater.
Forexample,youwillneverstoreyourcurrentpositiononscreen
becausethatwillbecomputedagainwhenanewinstanceoftheviewisplacedinitsviewhierarchy.
Someexamplesofthingsyoumaystorehere:thecurrentcursorposition
inatextview(butusuallynotthetextitselfsincethatisstoredinacontentprovider
orotherpersistentstorage),thecurrentlyselectediteminalistview.
Returns
*ReturnsaParcelableobjectcontainingtheview'scurrentdynamicstate,
ornullifthereisnothinginterestingtosave.Thedefaultimplementationreturnsnull
在View和TextView中对onSaveInstanceState和onRestoreInstanceState的描述都差不多。
但是在View中,这两个函数是protected的,而在TextView中这两个函数是public的。在ListView中他们也是public的。
但在他们的文档比没说系统何时回调用这两个函数。从在View的子类TextView和ListView中,都把他们声明为public的来看,
该两个函数应该不是由系统来调用的。从实例1的运行来看,也没发现系统调用它们。
因此它们应该只是设计作为一个接口,
以便在Activity的onSaveInstanceState(BundleoutState)和onRestoreInstanceState(BundlesavedInstanceState)中
调用来保存View的数据。
如何使用
对onSaveInstanceState(),是在函数里面保存一些View有用的数据到一个Parcelable对象,并返回。
在Activity的onSaveInstanceState(BundleoutState)中调用View的onSaveInstanceState(),返回Parcelable对象,
接着用Bundle的putParcelable方法保存在BundlesavedInstanceState中。
当系统调用Activity的的onRestoreInstanceState(BundlesavedInstanceState)时,
同过Bundle的getParcelable方法得到Parcelable对象,然后把该Parcelable对象传给View的onRestoreInstanceState(Parcelablestate).
在的View的onRestoreInstanceState中从Parcelable读取保存的数据以便View使用
实例1
文件1:
Hello.java
packagecom.teleca;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.os.Bundle;
importandroid.os.Parcelable;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
publicclassHelloextendsActivity{
Stringtag="hubin";
MyTextViewtextView1;
MyTextViewtv2;
finalStringkTextView1Name="tv1";
LinearLayoutlayoutRoot=null;
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Buttonbutton=(Button)findViewById(R.id.Button01);
OnClickListenerlistener=newOnClickListener(){
publicvoidonClick(Viewv){
Intentintent=newIntent(Hello.this,Hello2.class);
startActivity(intent);
//finish();
}
};
button.setOnClickListener(listener);
if(layoutRoot==null)
layoutRoot=(LinearLayout)findViewById(R.id.root);
if(textView1==null)
{
textView1=newMyTextView(this,"firstview");
layoutRoot.addView(textView1);
}
Log.i(tag,"createone1");
;
}
protectedvoidonSaveInstanceState(BundleoutState)
{
super.onSaveInstanceState(outState);
Log.i(tag,"oneSaveInstanceState");
ParcelablesavedState=textView1.onSaveInstanceState();
outState.putParcelable(kTextView1Name,savedState);
}
protectedvoidonRestoreInstanceState(BundlesavedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
Log.i(tag,"oneRestoreInstanceState");
SavedState0savedState=savedInstanceState.getParcelable(kTextView1Name);
textView1.onRestoreInstanceState(savedState);
}
protectedvoidonDestroy()
{
super.onDestroy();
Log.i(tag,"oneDestroy");
}
}
文件2:Hello2.java
packagecom.teleca;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
publicclassHello2extendsActivity{
Stringtag="hubin";
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
Buttonbutton=(Button)findViewById(R.id.Button01);
OnClickListenerlistener=newOnClickListener(){
publicvoidonClick(Viewv){
Intentintent=newIntent(Hello2.this,Hello.class);
startActivity(intent);
}
};
button.setOnClickListener(listener);
}
protectedvoidonSaveInstanceState(Bundleb)
{
Log.i(tag,"twoSaveInstanceState");
}
protectedvoidonDestroy()
{
super.onDestroy();
Log.i(tag,"twoDestroy");
}
}
文件3:MyTextView.java
packagecom.teleca;
importjava.util.HashMap;
importjava.util.Set;
importandroid.content.Context;
importandroid.os.Parcel;
importandroid.os.Parcelable;
importandroid.preference.Preference.BaseSavedState;
importandroid.util.Log;
importandroid.widget.TextView;
publicclassMyTextViewextendsTextView{
Stringtag="hubin";
intstartPage;
HashMap<Long,Boolean>checkedItemIds;
publicMyTextView(Contextcontext,Stringtext){
super(context);
//TODOAuto-generatedconstructorstub
Log.i(tag,"createTextView"+text);
this.setText(text);
startPage=(int)System.currentTimeMillis();
checkedItemIds=newHashMap<Long,Boolean>();
checkedItemIds.put((long)startPage+1,true);
checkedItemIds.put((long)startPage+2,true);
checkedItemIds.put((long)startPage+3,true);
}
publicParcelableonSaveInstanceState()
{
ParcelablesuperState=super.onSaveInstanceState();
Log.i(tag,"onSaveinTextView");
Log.i(tag,"savestartPage:"+startPage);
Set<Long>set=checkedItemIds.keySet();
Objectkeys[]=set.toArray();
for(inti=0;i<keys.length;i++)
{
Log.i(tag,"i:"+Long.parseLong(""+keys<wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">));</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0(superState,startPage,checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff00ff; line-height:25px">onRestoreInstanceState</span><span style="color:#3366ff; line-height:25px">(Parcelablestate){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">SavedState0ss=(SavedState0)state;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"onRestoreInstanceState");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.onRestoreInstanceState(ss.getSuperState());</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">startPage=ss.startPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds.clear();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds.putAll(ss.checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"restorestartPage:"+startPage);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Set<Long>set=checkedItemIds.keySet();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Objectkeys[]=(Long[])set.toArray();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(inti=0;i<keys.length;i++)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"i:"+Long.parseLong(""+keys</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">));</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">extends</span><span style="color:#3366ff; line-height:25px">BaseSavedState{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intstartPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">HashMap<Long,Boolean>checkedItemIds;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">(ParcelablesuperState,intstartPage,HashMap<Long,Boolean>checkedItemIds){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(superState);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.startPage=startPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.checkedItemIds=checkedItemIds;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">private</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">(Parcelin){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(in);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">startPage=in.readInt();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds=in.readHashMap(null);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">writeToParcel</span><span style="color:#3366ff; line-height:25px">(Parcelout,intflags){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.writeToParcel(out,flags);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">out.writeInt(startPage);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">out.writeMap(checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicString</span><span style="color:#3366ff; line-height:25px">toString(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return"TextViewSavedState{"</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">+Integer.toHexString(System.identityHashCode(this))+"}";</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/*<br style="line-height:25px"> *InterfacethatmustbeimplementedandprovidedasapublicCREATORfield<br style="line-height:25px"> *thatgeneratesinstancesofyourParcelableclassfromaParcel.<br style="line-height:25px"> */<br style="line-height:25px"> /*<br style="line-height:25px"> *InterfaceforclasseswhoseinstancescanbewrittentoandrestoredfromaParcel.<br style="line-height:25px"> *ClassesimplementingtheParcelableinterfacemustalsohaveastaticfieldcalledCREATOR,<br style="line-height:25px"> *whichisanobjectimplementingtheParcelable.Creatorinterface.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicstaticfinal</span><span style="color:#3366ff; line-height:25px">Parcelable.Creator<</span><span style="color:#99cc00; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">>CREATOR</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">=</span><span style="color:#993300; line-height:25px">new</span><span style="color:#3366ff; line-height:25px">Parcelable.Creator<</span><span style="color:#99cc00; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">>(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">public</span><span style="color:#3366ff; line-height:25px">SavedState0</span><span style="color:#ff6600; line-height:25px">createFromParcel</span><span style="color:#3366ff; line-height:25px">(Parcelin){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0(in);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">public</span><span style="color:#3366ff; line-height:25px">SavedState0[]</span><span style="color:#ff6600; line-height:25px">newArray</span><span style="color:#3366ff; line-height:25px">(intsize){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0[size];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">};</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><br style="line-height:25px"><span style="line-height:25px">注意1</span>:当我们构造一个Parcelable的子类一定要定义publicstaticfinalParcelable.Creator<SavedState0>CREATOR。<br style="line-height:25px"> 它用于从一个流创建Parcelable对象。注意是个具体的Parcelable对象。比如这里就是BaseSavedState对象。<br style="line-height:25px"> 对于Parcelable对象和流的转化机制(该示例的桥是Bundle),我想有两种可能:<br style="line-height:25px"><span style="line-height:25px">A</span>:在把Parcelable对象转为流的时候,除了Parcel的数据(通过方法writeToParcel得到),<br style="line-height:25px"> 还把Parcelable对象的构造器CREATOR的信息写到了流中。在读的时候,<br style="line-height:25px"> 就可以通过在流中读得关于CREATOR的信息找到Parcelable对象构造器CREATOR以便创建Parcelable对象(这里是BaseSavedState)<br style="line-height:25px"> 至于在写数据时,系统如何找到CREATOR,我想既然知道一个对象,那么虚拟机当然可以找他属于哪个类。<br style="line-height:25px"> 找到了属于哪个类,就可以找到CREATOR变量。当然也可能是通过一个对象的成员变量表直接找到CREATOR变量的。<br style="line-height:25px"><span style="line-height:25px">B</span>:在把Parcelable对象转为流的时候,除了Parcel的数据(通过方法writeToParcel得到),<br style="line-height:25px"> 还把Parcelable对象所属类的信息写到了流中。在读的时候,<br style="line-height:25px"> 就可以通过在流中读得关于Parcelable对象所属类的信息,找到Parcelable对象所属的类,<br style="line-height:25px"> 然后通过该类找到构造器CREATOR以便创建Parcelable对象(这里是BaseSavedState)</wbr></wbr>
在View文档中对其的说明如下:
protectedvoidonRestoreInstanceState(Parcelablestate)
Since:APILevel1
Hookallowingaviewtore-applyarepresentationofitsinternalstatethathadpreviously
beengeneratedbyonSaveInstanceState().Thisfunctionwillneverbecalledwithanullstate.
Parameters
stateThefrozenstatethathadpreviouslybeenreturnedbyonSaveInstanceState().
SeeAlso
*onSaveInstanceState()
*restoreHierarchyState(SparseArray)
*dispatchRestoreInstanceState(SparseArray)
protectedParcelableonSaveInstanceState()
Since:APILevel1
Hookallowingaviewtogeneratearepresentationofitsinternalstate
thatcanlaterbeusedtocreateanewinstancewiththatsamestate.
Thisstateshouldonlycontaininformationthatisnotpersistentorcannotbereconstructedlater.
Forexample,youwillneverstoreyourcurrentpositiononscreenbecausethatwillbecomputedagain
whenanewinstanceoftheviewisplacedinitsviewhierarchy.
Someexamplesofthingsyoumaystorehere:thecurrentcursorpositioninatextview
(butusuallynotthetextitselfsincethatisstoredinacontentproviderorotherpersistentstorage),
thecurrentlyselectediteminalistview.
Returns
*ReturnsaParcelableobjectcontainingtheview'scurrentdynamicstate,
ornullifthereisnothinginterestingtosave.Thedefaultimplementationreturnsnull.
在TextView文档中对其的说明如下:
publicvoidonRestoreInstanceState(Parcelablestate)
Since:APILevel1
Hookallowingaviewtore-applyarepresentationofitsinternalstate
thathadpreviouslybeengeneratedbyonSaveInstanceState().
Thisfunctionwillneverbecalledwithanullstate.
Parameters
stateThefrozenstatethathadpreviouslybeenreturnedbyonSaveInstanceState().
publicParcelableonSaveInstanceState()
Since:APILevel1
Hookallowingaviewtogeneratearepresentationofitsinternalstate
thatcanlaterbeusedtocreateanewinstancewiththatsamestate.
Thisstateshouldonlycontaininformationthatisnotpersistentorcannotbereconstructedlater.
Forexample,youwillneverstoreyourcurrentpositiononscreen
becausethatwillbecomputedagainwhenanewinstanceoftheviewisplacedinitsviewhierarchy.
Someexamplesofthingsyoumaystorehere:thecurrentcursorposition
inatextview(butusuallynotthetextitselfsincethatisstoredinacontentprovider
orotherpersistentstorage),thecurrentlyselectediteminalistview.
Returns
*ReturnsaParcelableobjectcontainingtheview'scurrentdynamicstate,
ornullifthereisnothinginterestingtosave.Thedefaultimplementationreturnsnull
在View和TextView中对onSaveInstanceState和onRestoreInstanceState的描述都差不多。
但是在View中,这两个函数是protected的,而在TextView中这两个函数是public的。在ListView中他们也是public的。
但在他们的文档比没说系统何时回调用这两个函数。从在View的子类TextView和ListView中,都把他们声明为public的来看,
该两个函数应该不是由系统来调用的。从实例1的运行来看,也没发现系统调用它们。
因此它们应该只是设计作为一个接口,
以便在Activity的onSaveInstanceState(BundleoutState)和onRestoreInstanceState(BundlesavedInstanceState)中
调用来保存View的数据。
如何使用
对onSaveInstanceState(),是在函数里面保存一些View有用的数据到一个Parcelable对象,并返回。
在Activity的onSaveInstanceState(BundleoutState)中调用View的onSaveInstanceState(),返回Parcelable对象,
接着用Bundle的putParcelable方法保存在BundlesavedInstanceState中。
当系统调用Activity的的onRestoreInstanceState(BundlesavedInstanceState)时,
同过Bundle的getParcelable方法得到Parcelable对象,然后把该Parcelable对象传给View的onRestoreInstanceState(Parcelablestate).
在的View的onRestoreInstanceState中从Parcelable读取保存的数据以便View使用
实例1
文件1:
Hello.java
packagecom.teleca;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.os.Bundle;
importandroid.os.Parcelable;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
publicclassHelloextendsActivity{
Stringtag="hubin";
MyTextViewtextView1;
MyTextViewtv2;
finalStringkTextView1Name="tv1";
LinearLayoutlayoutRoot=null;
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Buttonbutton=(Button)findViewById(R.id.Button01);
OnClickListenerlistener=newOnClickListener(){
publicvoidonClick(Viewv){
Intentintent=newIntent(Hello.this,Hello2.class);
startActivity(intent);
//finish();
}
};
button.setOnClickListener(listener);
if(layoutRoot==null)
layoutRoot=(LinearLayout)findViewById(R.id.root);
if(textView1==null)
{
textView1=newMyTextView(this,"firstview");
layoutRoot.addView(textView1);
}
Log.i(tag,"createone1");
;
}
protectedvoidonSaveInstanceState(BundleoutState)
{
super.onSaveInstanceState(outState);
Log.i(tag,"oneSaveInstanceState");
ParcelablesavedState=textView1.onSaveInstanceState();
outState.putParcelable(kTextView1Name,savedState);
}
protectedvoidonRestoreInstanceState(BundlesavedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
Log.i(tag,"oneRestoreInstanceState");
SavedState0savedState=savedInstanceState.getParcelable(kTextView1Name);
textView1.onRestoreInstanceState(savedState);
}
protectedvoidonDestroy()
{
super.onDestroy();
Log.i(tag,"oneDestroy");
}
}
文件2:Hello2.java
packagecom.teleca;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
publicclassHello2extendsActivity{
Stringtag="hubin";
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
Buttonbutton=(Button)findViewById(R.id.Button01);
OnClickListenerlistener=newOnClickListener(){
publicvoidonClick(Viewv){
Intentintent=newIntent(Hello2.this,Hello.class);
startActivity(intent);
}
};
button.setOnClickListener(listener);
}
protectedvoidonSaveInstanceState(Bundleb)
{
Log.i(tag,"twoSaveInstanceState");
}
protectedvoidonDestroy()
{
super.onDestroy();
Log.i(tag,"twoDestroy");
}
}
文件3:MyTextView.java
packagecom.teleca;
importjava.util.HashMap;
importjava.util.Set;
importandroid.content.Context;
importandroid.os.Parcel;
importandroid.os.Parcelable;
importandroid.preference.Preference.BaseSavedState;
importandroid.util.Log;
importandroid.widget.TextView;
publicclassMyTextViewextendsTextView{
Stringtag="hubin";
intstartPage;
HashMap<Long,Boolean>checkedItemIds;
publicMyTextView(Contextcontext,Stringtext){
super(context);
//TODOAuto-generatedconstructorstub
Log.i(tag,"createTextView"+text);
this.setText(text);
startPage=(int)System.currentTimeMillis();
checkedItemIds=newHashMap<Long,Boolean>();
checkedItemIds.put((long)startPage+1,true);
checkedItemIds.put((long)startPage+2,true);
checkedItemIds.put((long)startPage+3,true);
}
publicParcelableonSaveInstanceState()
{
ParcelablesuperState=super.onSaveInstanceState();
Log.i(tag,"onSaveinTextView");
Log.i(tag,"savestartPage:"+startPage);
Set<Long>set=checkedItemIds.keySet();
Objectkeys[]=set.toArray();
for(inti=0;i<keys.length;i++)
{
Log.i(tag,"i:"+Long.parseLong(""+keys<wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">));</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0(superState,startPage,checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff00ff; line-height:25px">onRestoreInstanceState</span><span style="color:#3366ff; line-height:25px">(Parcelablestate){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">SavedState0ss=(SavedState0)state;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"onRestoreInstanceState");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.onRestoreInstanceState(ss.getSuperState());</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">startPage=ss.startPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds.clear();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds.putAll(ss.checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"restorestartPage:"+startPage);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Set<Long>set=checkedItemIds.keySet();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Objectkeys[]=(Long[])set.toArray();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(inti=0;i<keys.length;i++)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Log.i(tag,"i:"+Long.parseLong(""+keys</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">));</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">extends</span><span style="color:#3366ff; line-height:25px">BaseSavedState{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intstartPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">HashMap<Long,Boolean>checkedItemIds;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">(ParcelablesuperState,intstartPage,HashMap<Long,Boolean>checkedItemIds){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(superState);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.startPage=startPage;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.checkedItemIds=checkedItemIds;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">private</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">(Parcelin){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(in);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">startPage=in.readInt();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">checkedItemIds=in.readHashMap(null);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">writeToParcel</span><span style="color:#3366ff; line-height:25px">(Parcelout,intflags){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.writeToParcel(out,flags);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">out.writeInt(startPage);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">out.writeMap(checkedItemIds);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">@Override</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicString</span><span style="color:#3366ff; line-height:25px">toString(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return"TextViewSavedState{"</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">+Integer.toHexString(System.identityHashCode(this))+"}";</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/*<br style="line-height:25px"> *InterfacethatmustbeimplementedandprovidedasapublicCREATORfield<br style="line-height:25px"> *thatgeneratesinstancesofyourParcelableclassfromaParcel.<br style="line-height:25px"> */<br style="line-height:25px"> /*<br style="line-height:25px"> *InterfaceforclasseswhoseinstancescanbewrittentoandrestoredfromaParcel.<br style="line-height:25px"> *ClassesimplementingtheParcelableinterfacemustalsohaveastaticfieldcalledCREATOR,<br style="line-height:25px"> *whichisanobjectimplementingtheParcelable.Creatorinterface.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicstaticfinal</span><span style="color:#3366ff; line-height:25px">Parcelable.Creator<</span><span style="color:#99cc00; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">>CREATOR</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">=</span><span style="color:#993300; line-height:25px">new</span><span style="color:#3366ff; line-height:25px">Parcelable.Creator<</span><span style="color:#99cc00; line-height:25px">SavedState0</span><span style="color:#3366ff; line-height:25px">>(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">public</span><span style="color:#3366ff; line-height:25px">SavedState0</span><span style="color:#ff6600; line-height:25px">createFromParcel</span><span style="color:#3366ff; line-height:25px">(Parcelin){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0(in);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">public</span><span style="color:#3366ff; line-height:25px">SavedState0[]</span><span style="color:#ff6600; line-height:25px">newArray</span><span style="color:#3366ff; line-height:25px">(intsize){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">newSavedState0[size];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">};</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><br style="line-height:25px"><span style="line-height:25px">注意1</span>:当我们构造一个Parcelable的子类一定要定义publicstaticfinalParcelable.Creator<SavedState0>CREATOR。<br style="line-height:25px"> 它用于从一个流创建Parcelable对象。注意是个具体的Parcelable对象。比如这里就是BaseSavedState对象。<br style="line-height:25px"> 对于Parcelable对象和流的转化机制(该示例的桥是Bundle),我想有两种可能:<br style="line-height:25px"><span style="line-height:25px">A</span>:在把Parcelable对象转为流的时候,除了Parcel的数据(通过方法writeToParcel得到),<br style="line-height:25px"> 还把Parcelable对象的构造器CREATOR的信息写到了流中。在读的时候,<br style="line-height:25px"> 就可以通过在流中读得关于CREATOR的信息找到Parcelable对象构造器CREATOR以便创建Parcelable对象(这里是BaseSavedState)<br style="line-height:25px"> 至于在写数据时,系统如何找到CREATOR,我想既然知道一个对象,那么虚拟机当然可以找他属于哪个类。<br style="line-height:25px"> 找到了属于哪个类,就可以找到CREATOR变量。当然也可能是通过一个对象的成员变量表直接找到CREATOR变量的。<br style="line-height:25px"><span style="line-height:25px">B</span>:在把Parcelable对象转为流的时候,除了Parcel的数据(通过方法writeToParcel得到),<br style="line-height:25px"> 还把Parcelable对象所属类的信息写到了流中。在读的时候,<br style="line-height:25px"> 就可以通过在流中读得关于Parcelable对象所属类的信息,找到Parcelable对象所属的类,<br style="line-height:25px"> 然后通过该类找到构造器CREATOR以便创建Parcelable对象(这里是BaseSavedState)</wbr></wbr>