安卓Android Intent 传递对象objet

作者: Reinelili | 来源:发表于2019-04-03 17:41 被阅读7次

    安卓开发中,最常遇到的问题之一——不同的activity之间传值或者传递对象。

    1 传值

    通常,传递值(字符串,数字等)比较简单。

    我们去粗取精,挑重点讲:

     btn_next_activity.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            Intent myIntent = new Intent(MainActivity.this, Activity2.class);
            myIntent.putExtra("data", selectedString);
            startActivity(myIntent);
          }
    });
    

    通过这段对应按钮的跳转监听可以看到,只需要在跳转时,让intent绑定数据, putExtra使用键值对:

                    myIntent.putExtra("data", selectedString);
    

    然后在接收的Activity/目标Activity中接受一下这个传过来的值:

            //通过Activity.getIntent()获取当前页面接收到的Intent。
            Intent intent =getIntent();
            //getXxxExtra方法获取Intent传递过来的数据
            String data_selected_string =intent.getStringExtra("data");
    

    我们就把传过来的值放在 data_selected_string里面了,想要怎么操作就随便了~


    2 传递对象

    但如果要传递一个对象(包含的信息更复杂),需要先将它序列化Serializable 或者 打包Parcelable.

    • 类实现 Serializable,Java 提供的序列化的接口
    • 类实现 Parcelable,Android提供的在移动端的序列化接口,效率更高

    Serializable (简单)

    这俩差不多,首先我们挑简单的来实现,使用Serializable。我们按步骤说:

    1. 在要传递的对象的类上加上 implements Serializable (或 Parcelable):
    public class Planet implements Serializable {
        private String nom;
        private double distance_ua;
        private double rayon_km;
        private double masse;
    ...
    
    2. 在要Intent传递传递时使用Serializable序列化对象 :
     btn_next_activity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent myIntent = new Intent(MainActivity.this, Activity3.class);
                    myIntent.putExtra("Choose planet:", (Serializable) selectedPlanet);
    //                myIntent.putExtra("data", (Parcelable) selectedPlanet);
    
                    startActivity(myIntent);
                }
            });
    
    3. 在目标Activity接收(使用intent.getSerializableExtra):
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_3);
    
            Intent intent = getIntent();
    
            Planet selectedPlanet = (Planet) intent.getSerializableExtra("Choose planet:");
    //        Planet selectedPlanet = intent.getParcelableExtra("Choose planet:");
    

    恭喜!这就OK啦!


    Parcelable (效率高)

    Parcelable 稍微复杂一点,需要写包,读包。不过实际写起来,也比较简单:

    1. 在要传递的对象的类上加上 implements Parcelable, 代码会提示引入相关的方法 :
    public class Planet implements Parcelable {
        private String nom;
        private double distance_ua;
        private double rayon_km;
        private double masse;
    
        public Planet(String nom, double distance_ua, double rayon_km, double masse) {
            this.nom = nom;
            this.distance_ua = distance_ua;
            this.rayon_km = rayon_km;
            this.masse = masse;
        }
    
        protected Planet(Parcel in) {
            nom = in.readString();
            distance_ua = in.readDouble();
            rayon_km = in.readDouble();
            masse = in.readDouble();
        }
    
        public static final Creator<Planet> CREATOR = new Creator<Planet>() {
            @Override
            public Planet createFromParcel(Parcel in) {
                return new Planet(in);
            }
    
            @Override
            public Planet[] newArray(int size) {
                return new Planet[size];
            }
        };
    
     //... 中间有一些 getter() setter()方法略
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(nom);
            dest.writeDouble(distance_ua);
            dest.writeDouble(rayon_km);
            dest.writeDouble(masse);
        }
    }
    
    2. 在要Intent传递传递时使用Parcelable序列化对象 :

    和前面Serializable没有太大区别

            btnGo4.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent myIntent = new Intent(MainActivity.this, Activity4.class);
                    myIntent.putExtra("data", selectedPlanet);
    
                    startActivity(myIntent);
                }
            });
    
    3. 在目标Activity接收(使用intent.getSerializableExtra):

    和前面Serializable没有太大区别

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_4);
    
            Intent intent = getIntent();
    
    //        Planet2 selectedPlanet = (Planet2) intent.getSerializableExtra("Choose planet:");
            Planet selectedPlanet = intent.getParcelableExtra("data");
    
            txtView_selected_planet2 = findViewById(R.id.txt_selected_planet_2);
            txtView_selected_planet2.setText(selectedPlanet.getNom()+
                    "\n"+selectedPlanet.getDistance_ua()+
                    "\n"+selectedPlanet.getRayon_km()+
                    "\n"+selectedPlanet.getMasse());
        }
    

    3. Serializable / Parcelable 作用、区别、效率对比及选择

    3.1 作用
    Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。
    从上面的设计上我们就可以看出优劣了。

    3.2 效率及选择
    Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

    3.3 编程实现
    对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。而Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义,而序列化的这些操作完全由底层实现 (实际上,简单的传递,使用默认即可,不必重写,重写是根据自己的需要定制,提供了更多的选择性)


    参考:
    https://juejin.im/entry/58abec895c497d005f72b9f3
    https://blog.csdn.net/yzzst/article/details/26255611 (对比)

    相关文章

      网友评论

        本文标题:安卓Android Intent 传递对象objet

        本文链接:https://www.haomeiwen.com/subject/tunzbqtx.html