• Android中数据的传递以及对象序列化


    Android中当两个Activity需要有信息交互的时候,可以使用Intent。具体来说:

    发送单一类型数据:

    发送方:
    String data = "Hello SecondActivity";
    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    intent.putExtra("extra_data", data);
    startActivity(intent); #在onClick中调用
    接收方:
    Intent  intent = getIntent();
    String data = intent.getStringExtra("extra_data");#可以在onCreate中读取

    除了putExtra("key", value)/getStringExtra("key")之外, 根据传递的value的类型还有很多对,比如:

    putExtra("key", intvalue)/getintExtra("key")
    putExtra("key", floatvalue)/getfloatExtra("key")
    putExtra("key", doublevalue)/getDoubleExtra("key")
    putExtra("key", bundlevalue)/getBundleExtra("key")

    ...

    发送多种数据类型的组合:

    也可以用Bundle把很多数据类型(包括嵌套Bundle)放到Bundle中一并发送:

    //sender
    Bundle b = new Bundle(); b.putInt("age", 2); b.putString("data", "hello"); intent.putExtras(b); startActivity(intent);
    //receiver
    Intent i = getIntent(); Bundle b = i.getExtras(); int age = b.getInt("age"); String data = b.getString("data");

    发送类对象:

    只有实现了Serializable或者Parcelable接口的类对象才可以实现序列化并可以通过Intent和Binder传递。

    方法1:Serializable

    Serializable是Java提供的序列化方法,优点是使用简单,一切由系统负责;缺点是速度稍慢。

    public class User implements Serializable{
        private String name;
        private Integer age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public User(String name, Integer age){
            this.name = name;
            this.age = age;
        }
    }
    //sender
    intent.putExtra("user", (Serializable) new User("JM", 30));

    //Receiver Intent i = getIntent(); User user = (User) i.getSerializableExtra("user"); textView.setText(String.format("name: %s, age: %s", user.getName(), user.getAge()));

    注:声明一个类为Serilizable时,可以一起指定serialVersionUID变量,类型为private static final long。

    这个变量的主要作用是保证类可以被正常序列化,比如当前类和序列化的类发生了某些变化,比如成员变量的数量,类型可能发生了改变,这个时候是无法正常反序列化的,会报如下错误,程序会Crash:

    Main; local class incompatible: stream classdesc serialVersionUID = ********

    方法2:Parcelable

    public class User implements Parcelable{
        private String name;
        private Integer age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public User(String name, Integer age){
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel parcel, int i) {
            //write all the fields that want to send
            parcel.writeString(getName());
            parcel.writeInt(getAge());
        }
    
        public static final Creator<User> CREATOR = new Creator<User>() {
            @Override
            public User createFromParcel(Parcel parcel) {
                return new User(parcel.readString(), parcel.readInt());
            }
    
            @Override
            public User[] newArray(int i) {
                return new User[i];
            }
        };
    }
    //Sender
                intent.putExtra("user", (Parcelable) new User("JM", 30));
                    startActivity(intent);
    //Receiver
            User user = (User) i.getParcelableExtra("user");
            textView.setText(String.format("name: %s, age: %s", user.getName(), user.getAge()));

    如果在User中有多个同类型字段,比如String,可以用Bundle来实现:

    @Override
        public void writeToParcel(Parcel parcel, int i) {
            //write all the fields that want to send
    //        parcel.writeString(getName());
    //        parcel.writeInt(getAge());
            Bundle b = new Bundle();
            b.putString("name", getName());
            b.putInt("age", getAge());
            parcel.writeBundle(b);
        }
    
        public static final Creator<User> CREATOR = new Creator<User>() {
            @Override
            public User createFromParcel(Parcel parcel) {
    //            return new User(parcel.readString(), parcel.readInt());
                Bundle b = parcel.readBundle();
                return new User(b.getString("name"), b.getInt("age"));
            }
    
            @Override
            public User[] newArray(int i) {
                return new User[i];
            }
        };


    系统中很多类是实现了Parcelble接口的类,他们都是可以直接序列化的,比如Intent、Bundle、Bitmpa的呢个,同时List和Map也可以序列化,前提是他们里面的每个元素都是可序列化的。

    Serializable是Java中的序列化接口,使用起来简单但是开销大,序列化和反序列化需要大量的I/O操作。而Parcelable是Android的序列化方式,因此更适合Android平台,缺点是使用稍微麻烦,但是效率高。

    Parcelable主要用于内存序列化。Serialzable主要用于序列化到存储设备或者序列化后通过网络传输。

    从别的Activity得到返回结果:

    启动端:

    startActivityForResult(intent, 0);

    0表示请求码,说明此次请求的意图是什么。

    接收端:

            Intent i = new Intent();
            i.putExtra("data", editText.getText().toString());
            setResult(RESULT_OK, i);
            finish();
  • 相关阅读:
    Linux用过的命令集合
    Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第十一集之安装FastDFS】
    Linux常见目录的作用
    Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第十集之Nginx反向代理原理】(有参考其他文章)
    Python socket编程之三:模拟数据库循环发布数据
    Python socket编程之二:【struct.pack】&【struct.unpack】
    Python socket编程之一:
    分时图设计
    统计一段时期内股票的涨幅情况
    iOS开发之手势识别汇总
  • 原文地址:https://www.cnblogs.com/dracohan/p/5984982.html
Copyright © 2020-2023  润新知