Parcel分析

1、Parcel是什么     

      Parcel可以理解为一个存放读取数据的容器,Parcel翻译过来就是“打包”的意思,其实就是包装了我们需要传输的数据,然后在Binder中传输,也就是用于跨进程数据传输。假如有进程A、B需要通信,在进程A中用Parcel将需要传输的非默认值和唯一标识打包(序列化),再把这个包传输给B进程,B进程通过这个包的唯一标识将会重新创建一个一模一样的类对象(反序列化),以达到通信的目的。

      Parcel对于基本类型(int ,long,double,short等)是可以直接进行打包或读取的,但是自定义的类,必须在实现了Parcelable后才能进行打包。

2、Parcelable

      Parcelabel和Java的Serializable的作用类似,是为Android我们的一个标准化的序列化接口。简单来说,就是想对象转换为可以传输的二进制流(二进制序列)的过程,这样我们就可以通过序列化,转换为可以在网络传输或者保存到本地的流(序列),从而进行数据的传输,反序列化就是从二进制流(序列)转换为对象的过程。如果我们自定义的类想要用Parcel打包,则必须要实现Parcelable的接口。我们可以这么理解Parcelable,它是一个使自定义类对象具有序列化能力的接口,凡是实现了该接口的类都可以被Parcel。

    

常用方法介绍:

            obtain()                          获得一个新的parcel ,相当于new一个对象

            dataSize()                      得到当前parcel对象的实际存储空间

            dataCapacity()               得到当前parcel对象的已分配的存储空间, >=dataSize()值  (以空间换时间)

            dataPostion()                 获得当前parcel对象的偏移量(类似于文件流指针的偏移量)

            setDataPosition()           设置偏移量

            recyle()                           清空、回收parcel对象的内存

            writeInt(int)                     写入一个整数

            writeFloat(float)              写入一个浮点数

            writeDouble(double)       写入一个双精度数

            writeString(string)           写入一个字符串

         当然,还有更多的writeXXX()方法,与之对应的就是readXXX(),具体方法请参阅SDK。

          其中几个值得注意的方法为:

             writeException()        在Parcel队头写入一个异常

             writeException()        Parcel队头写入“无异常“

             readException()        在Parcel队头读取,若读取值为异常,则抛出该异常;否则,程序正常运行。


3、Parcelable应用实例

目的:实现两个不同进程的Activity互相通信。

1、创建一个Book类,包含了Name、Author、Pagination三个成员变量。添加成员变量的getter和setter,并让该类实现Parcelable接口。

public class Book implements Parcelable {

    private String name,author;
    private int pagination;

    public Book() {
    }

    public int getPagination() {
        return pagination;
    }

    public void setPagination(int pagination) {
        this.pagination = pagination;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getName() {

        return name;
    }

    public String getAuthor() {
        return author;
    }

2、重写Parcelable的writeToParcel()方法。将Book类的成员变量序列化,添加到Parcel中。

@Override
public void writeToParcel(Parcel parcel, int i) {

   parcel.writeString(name);
   parcel.writeString(author);
   parcel.writeInt(pagination);
}

3、 实例化静态内部对象CREATOR实现接口Parcelable.Creator(CREATOR名称不能改动)用来反序列化,将Parcel对象还原为原始的Book对象。

public static final Creator<Book> CREATOR = new Creator<Book>() {
    @Override
    public Book createFromParcel(Parcel in) {
        return new Book(in);
    }

    @Override
    public Book[] newArray(int size) {
        return new Book[size];
    }
};

@Override
public int describeContents() {
    return 0;
}

4、添加一个带参数Parcel的构造方法。

protected Book(Parcel in) {
    this.author=in.readString();
    this.name=in.readString();
    this.pagination=in.readInt();
}

5、在MainActivity中添加一个按钮,点击按钮就可发送一个实现了Parcelable接口的Book对象给SecondActivity。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button sendMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();


    }

    private void initView() {

        sendMessage=findViewById(R.id.sendMessage);
        sendMessage.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
         if(view.getId()==R.id.sendMessage){

          /*   User user=new User();
             user.setName("Jasper");
             user.setGender("Female");
             user.setAge(20);*/
          Book book=new Book();
          book.setAuthor("Henry");
          book.setName("海边的黑猫");
          book.setPagination(232);



             Intent intent=new Intent(this,SecondActivity.class);
             Bundle bundle=new Bundle();
             bundle.putParcelable("Book",book);
             intent.putExtras(bundle);
/*
             User user2=  intent.getExtras().getParcelable("User");
             Log.i("TAG","orName:"+user2.getName());
             Log.i("TAG","orGender:"+user2.getGender());
             Log.i("TAG","orAge:"+user2.getAge());*/
             startActivity(intent);

         }
    }
}

6、在SecondActivity中把MainActivity传过来的Book对象中的数据显示出来。

public class SecondActivity extends AppCompatActivity {

    private TextView showName,showAuthor,showPagination;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);

        initView();


       Intent intent=getIntent();
      Bundle bundle=intent.getExtras();
      Book book=bundle.getParcelable("Book");
       /* Log.i("TAG","Name:"+book.getName());
        Log.i("TAG","Gender:"+book.getAuthor());*/
       // Log.i("TAG","Age:"+user.getAge());
       showName.setText(book.getName());
        showAuthor.setText(book.getAuthor());
        showPagination.setText(String.valueOf(book.getPagination()));

    }

    private void initView() {

        showName=findViewById(R.id.showName);
        showAuthor=findViewById(R.id.showAuthor);
        showPagination=findViewById(R.id.showPagination);
    }


}

7、为了证实它能跨进程传输数据,把其中一个Activity的进程手动设置一下。

 <activity android:name=".SecondActivity"
           android:process="com.HenryText.cn">

</activity>

最后效果图:




参考:https://blog.csdn.net/qq_34757587/article/details/52005089

           https://blog.csdn.net/qinjuning/article/details/6785517

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭