activity之间的数据传递
在前面已经实现了界面之间的跳转,然而实际开发中,界面跳转一般伴随着数据传递。那么安卓里面如何进行数据传递呢?这里还是需要用到Intent。
我们知道使用Intent对象,可以实现页面跳转,其实intent还可以携带任意数据。
上面这张图是Intent携带数据的方法的一部分包含了所有的基本类型。那么复合类型的数据如何传递呢?对象又如何传递呢?
一、复合类型的传递
从上面的图中,我们可以看到,除了基本类型外,intent还可以携带bundle和intent对象。那么bundle是个什么样的类呢?让我们看一看它的方法:
从上图可以知道,bundle主要是用来存储数据的,它是以键值对的形式存放数据,形式上有点像map。因此bundle可以用来存放多个基本数据,再将bundle用intent携带到另一个activity,即可达到传递复杂数据的目的。
起始activity中传值的代码:
public void sendArgs(View v){
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
//一、传递简单类型数据
//intent.putExtra("msg", "传递过来的数据是:welcome!");
//二、传递复杂类型的数据
Bundle bundle=new Bundle();
bundle.putString("name", "mike");
bundle.putInt("age", 19);
ArrayList<String> sList=new ArrayList<String>();
sList.add("1");
sList.add("2");
sList.add("3");
bundle.putStringArrayList("list", sList);
intent.putExtras(bundle);
startActivity(intent);
}
目的activity接受值的代码:
//接收简单类型数据
// Intent i=getIntent();//接收intent对象
// TextView tv=(TextView)findViewById(R.id.showMsgText);
// tv.setText(i.getStringExtra("msg"));
//接受复杂类型的数据
// Intent i=getIntent();
// Bundle data=i.getExtras();
// TextView tv=(TextView)findViewById(R.id.showMsgText);
// String str=String.format("name=%s;age=%s;list【1】=%s",data.getString("name"),data.getInt("age"),data.getStringArrayList("list"));
// tv.setText(str);
二、对象的传递
在程序中,我们经常用到对象,对象的传递也是比较常见的。在上面我们只是说了基本类类型以及由基本类型组成的复合类型的数据传递,那么当要传递的数据中含有对象时,是不是有什么特别的地方呢?答案是肯定的。传递的对象必须实现序列化接口android.os.Parcelable或java.io.Serializable。肯定有人会问:这两个接口有什么区别吗?为什么不用同一个呢?区别肯定是有的。java.io.Serializable是java提供的一个序列化接口,虽然也可以将对象序列化,但将对像序列化的操作交给了后台处理,我们使用时代码简单,但程序的执行效率低,这里就不做详细的说明。android.os.Parcelable是针对安卓系统提供的对象序列化的接口, 它里面含有两个方法public void writeToParcel(Parcel dest, int flags) 和public int describeContents(),使用时,我们需要实现这两个方法。因为针对每个不同的对象,我们是手动实现序列化的,依次程序执行效率会比较高。对象序列化代码如下:
package com.example.learningtext1_sendargs;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable{
private String name;
private int age;
private String id;
public User(String name, int age, String id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
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;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
Bundle bundle=new Bundle();
bundle.putString("name", getName());
bundle.putInt("age", getAge());
bundle.putString("id", getId());
dest.writeBundle(bundle);
}
public static final Creator<User> CREATOR =new Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
Bundle bundle=source.readBundle();
return new User(bundle.getString("name"),bundle.getInt("age"),bundle.getString("id"));
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
传递对象的代码如下:
//三、传递自定义数据类型(对象),对象必须序列化
User user=new User("小明", 18, "110");
intent.putExtra("user", user);
startActivity(intent);
接受对象的代码如下:
User user=(User)i.getParcelableExtra("user");
String str=String.format("name=%s;age=%s;id=%s",user.getName(),user.getAge(),user.getId());
tv.setText(str);
上面已经简单介绍了从当前activity到目的activity的传值问题,那么如何从目的activity返回值到当前activity呢?我们需要在当前activity中重写onActivityResult方法
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//通过requestCode和resultCode来判断用户的事件类型
showMsgText.setText("requestCode="+requestCode+",resultCode="+resultCode+","+data.getStringExtra("returnMsg"));
}
目的activity传递返回值的代码如下:setResult方法
backBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i=new Intent();
i.putExtra("returnMsg", returnText.getText().toString());
//i.putExtra("returnMsg", "returnText.getText().toString()");
SecondActivity.this.setResult(1, i);
finish();//结束当前的acticvity
}
});
注意,当需要返回值时,启动activity时,要用startActivityForResult(intent, 0);函数
源码见附件