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 += "\r\n" + 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 += "\r\n key----> " + (String) key;
//  sResult += "\r\n 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 += "\r\n key----> " + (String) key;
        sResult += "\r\n value----> " + (String) value;
    }

    TextView tv = findViewById(R.id.tv);
    tv.setText(sResult);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM