乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android中的序列化機(jī)制

       jiffes 2019-02-12

      當(dāng)我們在調(diào)用遠(yuǎn)程方法時,需要在進(jìn)程間傳遞參數(shù)以及返回結(jié)果。這種類似的處理方式,需要把數(shù)據(jù)與進(jìn)程相關(guān)性去除,變成一種中間形式,然后按統(tǒng)一的接口進(jìn)行讀寫操作。這樣的機(jī)制,一般在高級編程語言里都被稱為序列化。


      在Android世界里處理數(shù)據(jù)的序列化操作的,使用了一種Parcel類,而能夠處理數(shù)據(jù)序列能力,則是實(shí)現(xiàn)Parcelable接口來實(shí)現(xiàn)。于是,當(dāng)我們需要在進(jìn)程間傳輸一個對象,則實(shí)現(xiàn)這一對象的類必須實(shí)現(xiàn)Parcelable接口里定義的相應(yīng)屬性或方法,而在使用這一對象時,則可以使用一個Parcel引用來處理傳輸時的基本操作。


      ParcelSerialize很類似,只是它是在內(nèi)存中完成的序列化和反序列化,利用的是連續(xù)的內(nèi)存空間,因此會更加高效。


      1. Parcelable接口

      Interface for classes whose instances can be written to and restored from a Parcel。 Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface。


      2.實(shí)現(xiàn)Parcelable就是為了進(jìn)行序列化,那么,為什么要序列化?
      1)永久性保存對象,保存對象的字節(jié)序列到本地文件中;
      2)通過序列化對象在網(wǎng)絡(luò)中傳遞對象;
      3)通過序列化在進(jìn)程間傳遞對象。


      3.實(shí)現(xiàn)序列化的方法
      Android中實(shí)現(xiàn)序列化有兩個選擇:一是實(shí)現(xiàn)Serializable接口(是JavaSE本身就支持的),一是實(shí)現(xiàn)Parcelable接口(是Android特有功能,效率比實(shí)現(xiàn)Serializable接口高效,可用于Intent數(shù)據(jù)傳遞,也可以用于進(jìn)程間通信(IPC))。實(shí)現(xiàn)Serializable接口非常簡單,聲明一下就可以了,而實(shí)現(xiàn)Parcelable接口稍微復(fù)雜一些,但效率更高,推薦用這種方法提高性能。
      注:Android中Intent傳遞對象有兩種方法:一是Bundle.putSerializable(Key,Object),另一種是Bundle.putParcelable(Key,Object)。當(dāng)然這些Object是有一定的條件的,前者是實(shí)現(xiàn)了Serializable接口,而后者是實(shí)現(xiàn)了Parcelable接口。


      4.選擇序列化方法的原則
      1)在使用內(nèi)存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable。
      2)Serializable在序列化的時候會產(chǎn)生大量的臨時變量,從而引起頻繁的GC。
      3)Parcelable不能使用在要將數(shù)據(jù)存儲在磁盤上的情況,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn),但此時還是建議使用Serializable 。


      5.應(yīng)用場景

      需要在多個部件(Activity或Service)之間通過Intent傳遞一些數(shù)據(jù),簡單類型(如:數(shù)字、字符串)的可以直接放入Intent。復(fù)雜類型必須實(shí)現(xiàn)Parcelable接口。


      6.Serializable實(shí)現(xiàn)與Parcelabel實(shí)現(xiàn)的區(qū)別
      1)Serializable的實(shí)現(xiàn),只需要implements  Serializable 即可。這只是給對象打了一個標(biāo)記,系統(tǒng)會自動將其序列化。
      2)Parcelabel的實(shí)現(xiàn),不僅需要implements  Parcelabel,還需要在類中添加一個靜態(tài)成員變量CREATOR,這個變量需要實(shí)現(xiàn) Parcelable.Creator 接口。

      1)創(chuàng)建Person類,實(shí)現(xiàn)Serializable:

      1. public class Person implements Serializable
      2. {
      3. private static final long serialVersionUID = -7060210544600464481L;
      4. private String name;
      5. private int age;
      6. public String getName()
      7. {
      8. return name;
      9. }
      10. public void setName(String name)
      11. {
      12. this.name = name;
      13. }
      14. public int getAge()
      15. {
      16. return age;
      17. }
      18. public void setAge(int age)
      19. {
      20. this.age = age;
      21. }
      22. }

      2)創(chuàng)建Book類,實(shí)現(xiàn)Parcelable:

      1. public class Book implements Parcelable
      2. {
      3. private String bookName;
      4. private String author;
      5. private int publishDate;
      6. public Book()
      7. {
      8. }
      9. public String getBookName()
      10. {
      11. return bookName;
      12. }
      13. public void setBookName(String bookName)
      14. {
      15. this.bookName = bookName;
      16. }
      17. public String getAuthor()
      18. {
      19. return author;
      20. }
      21. public void setAuthor(String author)
      22. {
      23. this.author = author;
      24. }
      25. public int getPublishDate()
      26. {
      27. return publishDate;
      28. }
      29. public void setPublishDate(int publishDate)
      30. {
      31. this.publishDate = publishDate;
      32. }
      33. @Override
      34. public int describeContents()
      35. {
      36. return 0;
      37. }
      38. @Override
      39. public void writeToParcel(Parcel out, int flags)
      40. {
      41. out.writeString(bookName);
      42. out.writeString(author);
      43. out.writeInt(publishDate);
      44. }
      45. public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>()
      46. {
      47. @Override
      48. public Book[] newArray(int size)
      49. {
      50. return new Book[size];
      51. }
      52. @Override
      53. public Book createFromParcel(Parcel in)
      54. {
      55. return new Book(in);
      56. }
      57. };
      58. public Book(Parcel in)
      59. {
      60. bookName = in.readString();
      61. author = in.readString();
      62. publishDate = in.readInt();
      63. }
      64. }


      1、describeContents(),Parcelabl所需要的接口方法之一,必須實(shí)現(xiàn)。這一方法作用很簡單,就是通過返回的整形來描述這一Parcel是起什么作用的,通過這一整形每個bit來描述其類型,一般會返回0。
      2、writeToParcel(),Parcelabl所需要的接口方法之二,必須實(shí)現(xiàn)。writeToParcel()方法的作用是發(fā)送,就是將類所需要傳輸?shù)膶傩詫懙絇arcel里,被用來提供發(fā)送功能的Parcel,會作為第一個參數(shù)傳入,于是在這個方法里都是使用writeInt()、writeLong()寫入到Parcel里。這一方法的第二參數(shù)是一個flag值,可以用來指定這樣的發(fā)送是單向還是雙向的,可以與aidl的in、out、inout三種限定符匹配。
      3、CREATOR對象,Parcelable接口所需要的第三項(xiàng),必須提供實(shí)現(xiàn),但這是一個是接口對象。正如我們看到的,這一CREATOR對象,是使用模板類Parcelable.Creator,套用到TaskInfo來得到的,Parcelable.Creator<TaskInfo>。這個CREATOR對象在很大程度上是一個工廠(Factory)類,用于遠(yuǎn)程對象在接收端的創(chuàng)建。從某種意義上來說,writeToParcel()與CREATOR是一一對應(yīng)的,發(fā)送端進(jìn)程通過writeToParcel(),使用一個Parcel對象將中間結(jié)果保存起來,而接收端進(jìn)程則會使用CREATOR對象把作為Parcel對象的中間對象再恢復(fù)出來,通過類的初始化方法以這個Parcel對象為基礎(chǔ)來創(chuàng)建新對象。后續(xù)的4-6,則是完成這個CREATOR對象的實(shí)現(xiàn)。
      4、createFromParcel(),這是ParcelableCreator<T>模板類所必須實(shí)現(xiàn)的接口方法,提供從Parcel轉(zhuǎn)義出新的對象的能力。接收端來接收傳輸過來的Parcel對象時,便會以這一個接口方法來取得對象。我們這里直接調(diào)用基于Parcel 的類的初始化方法,然后將創(chuàng)建的對象返回。
      5、newArray(),這是ParcelableCreator<T>模板類所必須實(shí)現(xiàn)的另一個接口方法,但這一方法用于創(chuàng)建多個這種實(shí)現(xiàn)了Parcelable接口的類。通過這一方法,CREATOR對象不光能創(chuàng)建單個對象,也能返回多個創(chuàng)建好的空對象,但多個對象不能以某個Parcel對象為基礎(chǔ)創(chuàng)建,于是會使用默認(rèn)的類創(chuàng)始化方法。
      6、實(shí)現(xiàn)具體的以Parcel為參照的初始化方法,這并非必須,我們也可以在createFromParcel()里直接根據(jù)Parcel的值賦值到對象來實(shí)現(xiàn),但這樣實(shí)現(xiàn)則更清晰。這一方法,基本上與writeToParcel()是成對的,以什么順序?qū)ο髮傩詫懭隤arcel,則在createFromParcel()會就會以同樣的順序?qū)ο髮傩詮腜arcel里讀出來,使用Parcel的readInt()、readLong()等方法來完成。


      7.應(yīng)用實(shí)例

      就應(yīng)用程序而言,最常見使用Parcel類的場景就是在Activity間傳遞數(shù)據(jù)。沒錯,在Activity間使用Intent傳遞數(shù)據(jù)的時候,可以通過Parcelable機(jī)制傳遞復(fù)雜的對象。

       在下面的程序中,MyColor用于保存一個顏色值,MainActivity在用戶點(diǎn)擊屏幕時將MyColor對象設(shè)成紅色,傳遞到SubActivity中,此時SubActivity的TextView顯示為紅色的背景;當(dāng)點(diǎn)擊SubActivity時,將顏色值改為綠色,返回MainActivity,期望的是MainActivity的TextView顯示綠色背景。
      MyColor類的實(shí)現(xiàn)代碼:

      1. package com.test;
      2. import android.graphics.Color;
      3. import android.os.Parcel;
      4. import android.os.Parcelable;
      5. public class MyColor implements Parcelable {
      6. private int color=Color.BLACK;
      7. MyColor(){
      8. color=Color.BLACK;
      9. }
      10. MyColor(Parcel in){
      11. color=in.readInt();
      12. }
      13. public int getColor(){
      14. return color;
      15. }
      16. public void setColor(int color){
      17. this.color=color;
      18. }
      19. @Override
      20. public int describeContents() {
      21. return 0;
      22. }
      23. @Override
      24. public void writeToParcel(Parcel dest, int flags) {
      25. dest.writeInt(color);
      26. }
      27. public static final Parcelable.Creator<MyColor> CREATOR
      28. = new Parcelable.Creator<MyColor>() {
      29. public MyColor createFromParcel(Parcel in) {
      30. return new MyColor(in);
      31. }
      32. public MyColor[] newArray(int size) {
      33. return new MyColor[size];
      34. }
      35. };
      36. }

      MainActivity的代碼:

      1. package com.test;
      2. import android.app.Activity;
      3. import android.content.Intent;
      4. import android.graphics.Color;
      5. import android.os.Bundle;
      6. import android.view.MotionEvent;
      7. public class MainActivity extends Activity {
      8. private final int SUB_ACTIVITY=0;
      9. private MyColor color=new MyColor();
      10. @Override
      11. public void onCreate(Bundle savedInstanceState) {
      12. super.onCreate(savedInstanceState);
      13. setContentView(R.layout.main);
      14. }
      15. @Override
      16. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      17. super.onActivityResult(requestCode, resultCode, data);
      18. if (requestCode==SUB_ACTIVITY){
      19. if (resultCode==RESULT_OK){
      20. if (data.hasExtra("MyColor")){
      21. color=data.getParcelableExtra("MyColor"); //<span style="font-size: 14px; white-space: pre;">反序列化后是一個新的MyColor對象</span>
      22. findViewById(R.id.text).setBackgroundColor(color.getColor());
      23. }
      24. }
      25. }
      26. }
      27. @Override
      28. public boolean onTouchEvent(MotionEvent event){
      29. if (event.getAction()==MotionEvent.ACTION_UP){
      30. Intent intent=new Intent();
      31. intent.setClass(this, SubActivity.class);
      32. color.setColor(Color.RED);
      33. intent.putExtra("MyColor", color);
      34. startActivityForResult(intent,SUB_ACTIVITY);
      35. }
      36. return super.onTouchEvent(event);
      37. }
      38. }

      SubActivity的代碼:

      1. package com.test;
      2. import android.app.Activity;
      3. import android.content.Intent;
      4. import android.graphics.Color;
      5. import android.os.Bundle;
      6. import android.view.MotionEvent;
      7. import android.widget.TextView;
      8. public class SubActivity extends Activity {
      9. private MyColor color;
      10. @Override
      11. public void onCreate(Bundle savedInstanceState) {
      12. super.onCreate(savedInstanceState);
      13. setContentView(R.layout.main);
      14. ((TextView)findViewById(R.id.text)).setText("SubActivity");
      15. Intent intent=getIntent();
      16. if (intent!=null){
      17. if (intent.hasExtra("MyColor")){
      18. color=intent.getParcelableExtra("MyColor");
      19. findViewById(R.id.text).setBackgroundColor(color.getColor());
      20. }
      21. }
      22. }
      23. @Override
      24. public boolean onTouchEvent(MotionEvent event){
      25. if (event.getAction()==MotionEvent.ACTION_UP){
      26. Intent intent=new Intent();
      27. if (color!=null){
      28. color.setColor(Color.GREEN);
      29. intent.putExtra("MyColor", color);
      30. }
      31. setResult(RESULT_OK,intent);
      32. finish();
      33. }
      34. return super.onTouchEvent(event);
      35. }
      36. }

      在MainActivity的onActivityResult()中,有一句color=data.getParcelableExtra("MyColor"),這說明的是反序列化后是一個新的MyColor對象,因此要想使用這個對象,我們做了這個賦值語句。

      如果數(shù)據(jù)本身是IBinder類型,那么反序列化的結(jié)果就是原對象,而不是新建的對象,很顯然,如果是這樣的話,在反序列化后在MainActivity中就不再需要color=data.getParcelableExtra("MyColor")這句了。因此,換一種MyColor的實(shí)現(xiàn)方法,令其中的int color成員變量使用IBinder類型的成員變量來表示。


      新建一個BinderData類繼承自Binder,代碼如下:

      1. package com.test;
      2. import android.os.Binder;
      3. public class BinderData extends Binder {
      4. public int color;
      5. }

      修改MyColor的代碼如下:

      1. package com.test;
      2. import android.graphics.Color;
      3. import android.os.Parcel;
      4. import android.os.Parcelable;
      5. public class MyColor implements Parcelable {
      6. private BinderData data=new BinderData();
      7. MyColor(){
      8. data.color=Color.BLACK;
      9. }
      10. MyColor(Parcel in){
      11. data=(BinderData) in.readValue(BinderData.class.getClassLoader());
      12. }
      13. public int getColor(){
      14. return data.color;
      15. }
      16. public void setColor(int color){
      17. data.color=color;
      18. }
      19. @Override
      20. public int describeContents() {
      21. return 0;
      22. }
      23. @Override
      24. public void writeToParcel(Parcel dest, int flags) {
      25. dest.writeValue(data);
      26. }
      27. public static final Parcelable.Creator<MyColor> CREATOR
      28. = new Parcelable.Creator<MyColor>() {
      29. public MyColor createFromParcel(Parcel in) {
      30. return new MyColor(in);
      31. }
      32. public MyColor[] newArray(int size) {
      33. return new MyColor[size];
      34. }
      35. };
      36. }

      去掉MainActivity的onActivityResult()中的color=data.getParcelableExtra("MyColor")一句,變成:

      1. @Override
      2. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      3. super.onActivityResult(requestCode, resultCode, data);
      4. if (requestCode==SUB_ACTIVITY){
      5. if (resultCode==RESULT_OK){
      6. if (data.hasExtra("MyColor")){
      7. findViewById(R.id.text).setBackgroundColor(color.getColor());
      8. }
      9. }
      10. }
      11. }


        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多