------siwuxie095
传递值对象,即自定义的有数据类型的对象
1、首先 new 一个 class:User,用于创建自定义对象,同时右键 Generate
出 Constructor、setter 和 getter 方法(很简单,也可以手敲):
package com.siwuxie095.sendargs;
/** * Created by siwux on 2017/1/2. */
public class User { 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; }
public User(String name, int age) { this.name = name; this.age = age; } } |
2、在MainActivity.java中,如果直接加上
i.putExtra("user",new User("Bill",18)); |
就会报如下错误,即User的数据类型要么是 Parcelable(Android
平台用于序列化对象的接口),要么是 Serializable(Java语言内置
的用于序列化对象的接口):
3、二者的区别,分别实现一下即可知,先来实现 Serializable(与Parcelable
相比效率较低),在 User.java 中只做如下实现即可(所有序列化操作,系统
自动完成):
public class User implements Serializable |
4、MainActivity.java 和 TheAty.java,代码一览:
package com.siwuxie095.sendargs;
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
findViewById(R.id.btnStartAty).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //创建一个new Intent()实例,传入Context和Class类型的参数 //对应MainActivity.this 和 被启动的Activity的类定义 TheAty.class Intent i = new Intent(MainActivity.this,TheAty.class);
// //通过Intent对象,调用putExtra()方法,传参 // //这里传入String和String类型的参数,实际上就是键值对 // i.putExtra("data","你好 我是传递的参数");
// //传递数据包要用到Bundle,通过Bundle存入多种类型数据,传给第二个Activity // Bundle b=new Bundle(); // //b.putBundle(); 即Bundle也可以嵌入Bundle // b.putString("name","Jack"); // b.putInt("age",22); // //putExtras() 传入Bundle //// i.putExtras(b); // //除了通过putExtras()传,还能用下面的putExra() // i.putExtra("data",b);
i.putExtra("user",new User("Bill",18));
//传入i startActivity(i); } }); } } |
package com.siwuxie095.sendargs;
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView;
public class TheAty extends AppCompatActivity {
private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_the_aty);
//TheAty是通过MainActivity中的Intent启动,直接通过getIntent()方法 //获取与这个Activity相关的Intent Intent i=getIntent();
// //在第二个Activity 即TheAty 获取Bundle //// Bundle data=i.getExtras(); // Bundle data=i.getBundleExtra("data"); //要访问TextView,先在上面声明 //findViewById()的返回值在编译时只能查看到类型是View,而事实上是TextView类型 //需要强制类型转换 tv= (TextView) findViewById(R.id.tv);
// //调用setText()方法设置字符串,这里字符串通过Intent获取 // tv.setText(i.getStringExtra("data")); //需要做一个强制类型转换 User user= (User) i.getSerializableExtra("user"); //直接通过setText()方法传入字符串即可 tv.setText(String.format("User Info(name = %s, age = %d)",user.getName(),user.getAge()));
// //用到了String.format() // // 假如有一个不存在的数据 如namex // // 那么getString()有一个重载函数 可以设置默认值 // tv.setText(String.format("name = %s, age = %d, namex = %s",data.getString("name"),data.getInt("age"),data.getString("namex","Mary"))); } } |
5、运行一览:
6、再来实现 Parcelable,需要是实现两个方法,直接点击即可:
7、User.java,修改后:
package com.siwuxie095.sendargs;
import android.os.Parcel; import android.os.Parcelable;
import java.io.Serializable;
/** * Created by siwux on 2017/1/2. */
//public class User implements Serializable{ public class User implements Parcelable{ 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; }
public User(String name, int age) { this.name = name; this.age = age; }
//第一个方法不用管 @Override public int describeContents() { return 0; }
//向目标dest的Parcel里写数据 因为Parcelable没有全自动序列化机制 需要手动写 //将数据保存起来 方便传递给其他程序或Activity @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(getName()); dest.writeInt(getAge()); }
//还需创建一个Creator,泛型是User public static final Creator<User> CREATOR = new Creator<User>() { //createFromParcel() 通过一个Parcel来创建对象 @Override public User createFromParcel(Parcel source) { //直接返回一个new User() // User中如果数据过多,也可以打包成Bundle // 直接writeBundle() readBundle()即可 return new User(source.readString(),source.readInt()); }
@Override public User[] newArray(int size) { return new User[size]; } }; //注意这里还要加分号 } |
8、MainActivity.java 不变,TheAty.java只需接收时改为:
User user=i.getParcelableExtra("user"); |
TheAty.java:
package com.siwuxie095.sendargs;
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView;
public class TheAty extends AppCompatActivity {
private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_the_aty);
//TheAty是通过MainActivity中的Intent启动,直接通过getIntent()方法 //获取与这个Activity相关的Intent Intent i=getIntent();
// //在第二个Activity 即TheAty 获取Bundle //// Bundle data=i.getExtras(); // Bundle data=i.getBundleExtra("data"); //要访问TextView,先在上面声明 //findViewById()的返回值在编译时只能查看到类型是View,而事实上是TextView类型 //需要强制类型转换 tv= (TextView) findViewById(R.id.tv);
// //调用setText()方法设置字符串,这里字符串通过Intent获取 // tv.setText(i.getStringExtra("data")); // 需要做一个强制类型转换 // User user= (User) i.getSerializableExtra("user"); //不需要强制类型转换 User user=i.getParcelableExtra("user"); //直接通过setText()方法传入字符串即可 tv.setText(String.format("User Info(name = %s, age = %d)",user.getName(),user.getAge()));
// //用到了String.format() // // 假如有一个不存在的数据 如namex // // 那么getString()有一个重载函数 可以设置默认值 // tv.setText(String.format("name = %s, age = %d, namex = %s",data.getString("name"),data.getInt("age"),data.getString("namex","Mary"))); } } |
9、总结:Serializable 操作简单,序列化由系统自动完成,所以速度慢,
Parcelable 操作复杂,需要手写,但Android平台支持更好,速度快
【made by siwuxie095】