android开发中,我们的Activity之间总避免不了进行数据的传递,几种传递方式大致如下,各有各的用处:
1、Intent携带简单的数据
Intent intent=new Intent();
Bundle bundle=new Bundle();
bundle.putString("username","Mary");
bundle.putInt("age",23);
intent.putExtras(bundle);
参数接收:
Bundle bundle=getIntent().getExtras();
String username=bundle.getString("username");
int age=bundle.getInt("age");
2、Intent携带例如ArrayList之类复杂的数据
注意:在传参数前,要用新增加一个List将对象包起来
初始化数据:
Map<String,String> map=new HashMap<String,String>();
map.put("aaa","hello");
map.put("bbb","world");
List<Map<String,String>> list=new ArrayList<Map<String,String>>();
list.add(map);
Intent intent=new Intent();
Bundle bundle=new Bundle();
//须定义一个list用于在bundle中传递需要传递的List<Object>,这个是必须要的
ArrayList bundleList=new ArrayList();
bundleList.add(list);
bundle.putParcelableArrayList("list",bundleList);
intent.putExtras(bundle);
参数接收:
Bundle bundle=getIntent().getExtras();
List bundleList=bundle.getParcelbleArrayList("list");
List<Map<String,String>> list=(List<Map<String,String>>)bundleList.get(0);
//遍历输出
3、通过实现Serializable接口传递参数
初始化数据:
Map<String,String> map=new HashMap<String,String>();
map.put("aaa","hello");
map.put("bbb","world");
Bundle bundle=new Bundle();
bundle.putSerializable("map",map);
Intent intent=new Intent();
intent.putExtras(bundle);
参数接收:
Bundle bundle=getIntent().getExtras();
//HashMap没问题
//LinkedHashMap,转换时会抛出ClassCastException,何解
Map<String,String> map=(Map<String,String>)bundle.getSerializable("map");
//遍历输出
4、通过实现Parcelable接口,把要传的数据打包在里面,然后在接收端自己分解出来。这个是Android独有的,在其本身的源码中也用得很多,效率要比Serializable相对要好。
Parcelable实现要点:需要实现三个东西
1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.声明如下:
writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc
2)describeContents方法。没搞懂有什么用,反正直接返回0也可以
3)静态的Parcelable.Creator接口,本接口有两个方法:
createFromParcel(Parcel in) 实现从in中创建出类的实例的功能
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
定义一个DataParcelable实现Parcelable接口,将要传输的数据定义在这个类里面:
package com.xin.activity;
import java.util.HashMap;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
public class DataParcelable implements Parcelable{
//定义要被传输的数据
public int age;
public String username;
public String password;
public Map<String,String> map=new HashMap<String,String>();
@Override
public int describeContents() {
return 0;
}
/**
* 类的数据写入外部提供的Parcel
*/
@Override
public void writeToParcel(Parcel out, int flags) {
//将数据映射到Parcel中去
out.writeInt(age);
out.writeString(username);
out.writeString(password);
out.writeMap(map);
}
public static final Parcelable.Creator<DataParcelable> CREATOR=new Parcelable.Creator<DataParcelable>() {
/**
* 创建出类的实例
*/
@SuppressWarnings("unchecked")
@Override
public DataParcelable createFromParcel(Parcel in) {
DataParcelable data=new DataParcelable();
//将映射在Parcel对象中的数据还原出来
//这里的顺序一定要和writeToParcel中定义的顺序一致才行
data.age=in.readInt();
data.username=in.readString();
data.password=in.readString();
data.map=in.readHashMap(HashMap.class.getClassLoader());
return data;
}
@Override
public DataParcelable[] newArray(int size) {
return new DataParcelable[size];
}
};
}
注意上面方法中createFromParcel读取的顺序要和writeToParcel写入的顺序一致才行,这样才能保证相同数据类型的数据能够按顺序被读取出来!里面是这样的一个设计机制
初始化DataParcelable数据并将其放到Intent对象中去:
Intent intent=new Intent(MainActivity.this,OtherActivity.class);
DataParcelable data=new DataParcelable();
data.age=23;
data.username="hello";
data.password="world";
data.map=new HashMap<String,String>();
data.map.put("aaa","123");
data.map.put("bbb","456");
intent.putExtra("data", data);
startActivity(intent);
读取DataParcelable中的数据:
Intent intent=getIntent();
DataParcelable data=intent.getParcelableExtra("data");
System.out.println("age="+data.age+",username="+data.username+",password="+data.password+",map="+data.map);
大家根据自己的需要和使用场景,选择自己的数据存储方式吧!!