zoukankan      html  css  js  c++  java
  • android中的传值(5种)

    地址: https://blog.csdn.net/rely_on_yourself/article/details/81539986

    Android开发中,在不同模块(如Activity)间经常会有各种各样的数据需要相互传递,我把常用的几种 
    方法都收集到了一起。它们各有利弊,有各自的应用场景。 
    我现在把它们集中到一个例子中展示,在例子中每一个按纽代表了一种实现方法。

    效果图: 
    这里写图片描述

    Demo地址:https://download.csdn.net/download/rely_on_yourself/10595099

    1. 利用Intent对象携带简单数据

    利用Intent的Extra部分来存储我们想要传递的数据,可以传送String , int, long, char等一些基础类型,对复杂的对象就无能为力了。

    1.1 设置参数

                //传递些简单的参数
                 Intent intent1 = new Intent();
                 intent1.setClass(MainActivity.this,SimpleActivity.class);
    
                 //intent1.putExtra("usr", "lyx");
                 //intent1.putExtra("pwd", "123456");
                 //startActivity(intent1);
    
                 Bundle bundleSimple = new Bundle();
                 bundleSimple.putString("usr", "lyx");
                 bundleSimple.putString("pwd", "123456");
                 intent1.putExtras(bundleSimple);
    
                 startActivity(intent1);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.2接收参数

              //接收参数
    
               //Intent intent = getIntent();
               //String eml = intent.getStringExtra("usr");
               //String pwd = intent.getStringExtra("pwd");
    
               Bundle bundle = this.getIntent().getExtras();
               String eml = bundle.getString("usr");
               String pwd = bundle.getString("pwd");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这种情况下 , 有些童鞋喜欢直接用intent传递数据 , 不经过bundle来传递数据 . 其实这两种方式没有区别的 , 查看Intent 的源码就会发现 , 其实intent1.putExtra也是通过bundle来传递 . 具体的讲解可以参考这位童鞋的分享 , 我觉得挺清晰的 , 地址:https://www.cnblogs.com/jeffen/p/6835622.html

    2. 利用Intent对象携带如ArrayList之类复杂些的数据

    这种原理是和上面一种是一样的,只是要注意下。 在传参数前,要用新增加一个List将对象包起来。

    2.1 设置参数

            //传递复杂些的参数
            Map<String, Object> map = new HashMap<>();
            map.put("key1", "value1");
            map.put("key2", "value2");
            List<Map<String, Object>> list = new ArrayList<>();
            list.add(map);
    
            Intent intent = new Intent();
            intent.setClass(MainActivity.this,ComplexActivity.class);
            Bundle bundle = new Bundle();
            //须定义一个list用于在budnle中传递需要传递的ArrayList<Object>,这个是必须要的
            ArrayList bundlelist = new ArrayList();
            bundlelist.add(list);
            bundle.putParcelableArrayList("list",bundlelist);
            intent.putExtras(bundle);
            startActivity(intent);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.2 接收参数

        this.setTitle("复杂参数传递例子");
    
        //接收参数
         Bundle bundle = getIntent().getExtras();
         ArrayList list = bundle.getParcelableArrayList("list");
        //从List中将参数转回 List<Map<String, Object>>
         List<Map<String, Object>> lists= (List<Map<String, Object>>)list.get(0);
    
         String sResult = "";
           for (Map<String, Object> m : lists) {
               for (String k : m.keySet()) {
                   sResult += "
    " + k + " : " + m.get(k);
               }
           }
    
        TextView  tv = findViewById(R.id.tv);
        tv.setText(sResult);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3. 通过实现Serializable接口

    利用Java语言本身的特性,通过将数据序列化后,再将其传递出去。

    实体类:

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

    3.1设置参数

            //1.通过Serializable接口传参数的例子
            //HashMap<String,String> map2 = new HashMap<>();
            //map2.put("key1", "value1");
            //map2.put("key2", "value2");
            //Bundle bundleSerializable = new Bundle();
            //bundleSerializable.putSerializable("serializable", map2);
            //Intent intentSerializable = new Intent();
            //intentSerializable.putExtras(bundleSerializable);
            //intentSerializable.setClass(MainActivity.this,
            //SerializableActivity.class);
            //startActivity(intentSerializable);
    
            //2.通过Serializable接口传递实体类
            Person person = new Person();
            person.setAge(25);
            person.setName("lyx");
            Intent intent2 = new Intent(MainActivity.this, SerializableActivity.class);
            intent2.putExtra("serializable", person);
            startActivity(intent2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.2 接收参数

    this.setTitle("Serializable例子");
    
      //接收参数
    
      //1.接收集合
    // Bundle bundle = this.getIntent().getExtras();
    //如果传 LinkedHashMap,则bundle.getSerializable转换时会报ClassCastException,不知道什么原因
    //传HashMap倒没有问题。
    //HashMap<String, String> map = (HashMap<String, String>) bundle.getSerializable("serializable");
    //
    //String sResult = "map.size() =" + map.size();
    //
    //Iterator iter = map.entrySet().iterator();
    //  while (iter.hasNext()) {
    //  Map.Entry entry = (Map.Entry) iter.next();
    //   Object key = entry.getKey();
    //  Object value = entry.getValue();
    //  //System.out.println("key---->"+ (String)key);
    //  //System.out.println("value---->"+ (String)value);
    //
    //  sResult += "
     key----> " + (String) key;
    //  sResult += "
     value----> " + (String) value;
    //    }
    
      //2.接收实体类
      Person person = (Person) getIntent().getSerializableExtra("serializable");
      String sResult = "姓名:" + person.getName() + "--年龄:" + person.getAge();
    
      TextView tv = findViewById(R.id.tv);
      tv.setText(sResult);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    4. 通过实现Parcelable接口 
    这个是通过实现Parcelable接口,把要传的数据打包在里面,然后在接收端自己分解出来。这个是Android独有的,在其本身的源码中也用得很多,效率要比Serializable相对要好。 
    Parcelable方式实现的原理是将一个完整的对象进行分解 , 而分解后的每一部分都是Intent所支持的数据类型 , 这样也就实现传递对象的功能了 .

    Parcelable的实现方式 :

    public class Student implements Parcelable {
    
        private String name;
        private int age;
    
        public Student() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        protected Student(Parcel in) {
            name = in.readString();
            age = in.readInt();
        }
    
        public static final Creator<Student> CREATOR = new Creator<Student>() {
            @Override
            public Student createFromParcel(Parcel in) {
                return new Student(in);
            }
    
            @Override
            public Student[] newArray(int size) {
                return new Student[size];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeInt(age);
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    Parcelable的实现方式要稍微复杂一些 , 首先让Student类去实现了Parcelable接口 , 这样就必须重写describeContents()和writeToParcel()这两个方法 . 其中describeContents()方法可以直接返回0就可以了 , 而writeToParcel()方法中需要调用Parcel的writeXxx()方法 , 将Student类中的字段一一写出 . 注意 , 字符串数据就调用writeString()方法 , 整数数据就调用writeInt()方法 , 一次类推 . 
    除此之外 , 我们还必须在Student类中提供一个名为CREATOR的常量 , 这里创建了Parcelable.Creator接口的一个实现 , 并将泛型指定为Student . 接着需要重写createFromParcel()和newArray()这两个方法 . 在createFromParcel()方法中我们要去创建一个Student对象 , .而newArray()方法只需要new出一个Student数组 , 并传入size()作为数据的大小就可以了 .

    4.1 设置参数

    Student student = new Student();
    student.setAge(25);
    student.setName("lyx");
    Intent intent4 = new Intent(MainActivity.this, ParcelableActivity.class);
    intent4.putExtra("parcelable", student);
    startActivity(intent4);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2 接收参数

       this.setTitle("Parcelable例子");
    
       //接收参数
       Intent i = getIntent();
       Student student = i.getParcelableExtra("parcelable");
    
       TextView tv = findViewById(R.id.tv);
       tv.setText("姓名:" + student.getName() + "--年龄:" + student.getAge());
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5. 通过单例模式实现参数传递 
    单例模式的特点就是可以保证系统中一个类有且只有一个实例。这样很容易就能实现, 
    在A中设置参数,在B中直接访问了。这是几种方法中效率最高的。

    5.1 定义一个单实例的类

    //单例模式
    public class XclSingleton {
    
        //单例模式实例
        private static XclSingleton instance = null;
    
        //synchronized 用于线程安全,防止多线程同时创建实例
        public synchronized static XclSingleton getInstance() {
            if (instance == null) {
                instance = new XclSingleton();
            }
            return instance;
        }
    
        final HashMap<String, Object> mMap;
    
        public XclSingleton() {
            mMap = new HashMap<>();
        }
    
        public void put(String key, Object value) {
            mMap.put(key, value);
        }
    
        public Object get(String key) {
            return mMap.get(key);
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    5.2 设置参数

    //通过单例模式传参数的例子
     XclSingleton.getInstance().put("key1", "value1");
     XclSingleton.getInstance().put("key2", "value2");
    
     Intent intentSingleton = new Intent();
     intentSingleton.setClass(MainActivity.this,
             SingletonActivity.class);
     startActivity(intentSingleton);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.3 接收参数

      this.setTitle("单例模式例子");
    
            //接收参数
      HashMap<String, Object> map = XclSingleton.getInstance().mMap;
        String sResult = "map.size() =" + map.size();
    
        //遍历参数
        Iterator iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            sResult += "
     key----> " + (String) key;
            sResult += "
     value----> " + (String) value;
        }
    
        TextView tv = findViewById(R.id.tv);
        tv.setText(sResult);
  • 相关阅读:
    HDOJ 2095 find your present (2)
    HDOJ 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
    九度 1337 寻找最长合法括号序列
    九度 1357 疯狂地Jobdu序列
    HDOJ 1280 前m大的数
    九度 1343 城际公路网
    九度 1347 孤岛连通工程
    HDOJ 2151 Worm
    九度 1342 寻找最长合法括号序列II
    九度 1346 会员积分排序
  • 原文地址:https://www.cnblogs.com/mark5/p/12625367.html
Copyright © 2011-2022 走看看