Android 数据的传递(Intent、Bundle、Serializable、Parcelable等)
第一步:在xml文件上界面布局
这边采用LinearLayour布局,添加6个按钮来实现界面的跳转和相关功能的实现,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:id="@+id/b1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Intent传递"/>
<Button
android:id="@+id/b2"
android:layout_width="match_parent"
android:textAllCaps="false"
android:layout_height="wrap_content"
android:text="Bundle传递"/>
<Button
android:id="@+id/b3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Serializable传递"/>
<Button
android:id="@+id/b4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Parcelable传递"/>
<Button
android:id="@+id/b10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Serializable传递数组"/>
<Button
android:id="@+id/b20"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Parcelable传递数组"/>
</LinearLayout>
界面截图:
第二步:在Mainactivity.java完成功能的实现
绑定id
第三步:创建6个xml文件和6个java文件,来实现不同传递过程的界面显示
第四步:实现功能
①、Intent数据传递
跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main2Activity))
MainActivity代码如下:
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
intent.putExtra("first","你好,世界!");
intent.putExtra("second",520);
intent.putExtra("third",new String[]{"亚洲","非洲"});
startActivity(intent);
}
});
Main2Activity代码如下:
Intent intent=getIntent();
String name=intent.getStringExtra("first");
int names=intent.getIntExtra("second",0);
String a[]=intent.getStringArrayExtra("third");
t1.setText(name);
tf.setText(names+"");
tz.setText(a[0]);
界面截图:
②、Bundle数据传递
跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main3Activity))
MainActivity代码如下:
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,Main3Activity.class);
Bundle bundle=new Bundle();
bundle.putInt("first",520);
bundle.putString("second","你好,世界!");
bundle.putStringArray("third",new String[]{"亚洲","非洲"});
intent.putExtras(bundle);
startActivity(intent);
}
});
Main3Activity代码如下:
Intent intent=getIntent();
Bundle bundle=intent.getExtras();
int a=bundle.getInt("first");
String b=bundle.getString("second");
String[] c=bundle.getStringArray("third");
t2.setText(a+"");
t3.setText(b);
t4.setText(c[1]);
界面截图:
③、Serializable数据传递
首先在AndroidStudio快捷生成Serializable的UID
在正常情况下,AS是默认关闭serialVersionUID生成提示的,我们需要打开setting,找到检测(Inspections选项),开启 Serializable class without serialVersionUID 检测即可,如下:
第二:新建一个User类
public class User
{
}
在该类中implements Serializable
public class User implements Serializable
{
}
鼠标放在类名上,Alt+Enter(Mac:cmd+Enter),快捷代码提示,生成serialVersionUID即可:
public class User implements Serializable {
private static final long serialVersionUID = 4198853028696633601L;
}
serialVersionUID有什么作用呢?实际上我们不声明serialVersionUID也是可以的,因为在序列化过程中会自动生成一个serialVersionUID来标识序列化对象。
既然如此,那我们还需不需要要指定呢?原因是serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的对象中serialVersionUID只有和当前类的serialVersionUID相同才能够正常被反序列化,也就是说序列化与反序列化的serialVersionUID必须相同才能够使序列化操作成功。
具体过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。报出如下UID错误:
Exception in thread "main" java.io.InvalidClassException: com.zejian.test.Client;
local class incompatible: stream classdesc serialVersionUID = -2083503801443301445,
local class serialVersionUID = -4083503801443301445
因此强烈建议指定serialVersionUID,这样的话即使微小的变化也不会导致crash的出现,如果不指定的话只要这个文件多一个空格,系统自动生成的UID就会截然不同的,反序列化也就会失败。
在该类中输入信息
public class User implements Serializable {
private static final long serialVersionUID = 4198853028696633601L;
public int id;
public int age;
public String name;
public User(int id,String name,int age)
{
this.id=id;
this.age=age;
this.name=name;
}
}
第三:返回(MainActivity)文件,在跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main4Activity))
MainActivity代码如下:
b3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
User user=new User(1,"周某某",20);
Intent intent=new Intent(MainActivity.this,Main4Activity.class);
Bundle bundle=new Bundle();
bundle.putSerializable("user",user);
intent.putExtras(bundle);
startActivity(intent);
}
});
Main4Activity代码如下:
User user=(User)this.getIntent().getSerializableExtra("user");
String Date=user.id+" "+user.name+" "+user.age+" ";
ts.setText(Date);
界面截图:
④、Parcelable数据传递
第一:AndroidStudio快捷生成Parcelable代码
打开Setting,找到plugin插件,然后搜索Parcelable插件,最后找到android Parcelable code generator 安装即可:
第二:重启android studio后,我们创建一个User1类,如下:
public class User1 {
public int id;
public int age;
public String name;
}
第三:然后使用刚刚安装的插件协助我们生成实现Parcelable接口的代码,window快捷键:Alt+Insert,Mac快捷键:cmd+n,如下:
代码如下:
package com.example.match8;
import android.os.Parcel;
import android.os.Parcelable;
public class User1 implements Parcelable {
public int id;
public int age;
public String name;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeInt(this.age);
dest.writeString(this.name);
}
public User1() {
}
protected User1(Parcel in) {
this.id = in.readInt();
this.age = in.readInt();
this.name = in.readString();
}
public static final Parcelable.Creator<User1> CREATOR = new Parcelable.Creator<User1>() {
@Override
public User1 createFromParcel(Parcel source) {
return new User1(source);
}
@Override
public User1[] newArray(int size) {
return new User1[size];
}
};
}
第四:在上面代码找到以下代码输入信息
public User1()
{
}
代码如下:
public User1(int id,String name,int age) {
this.id=id;
this.name=name;
this.age=age;
}
第五:返回(MainActivity)文件,在跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main5Activity))
MainActivity代码如下:
b4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
User1 user1 = new User1(1,"周某某",20);
Intent intent = new Intent(MainActivity.this,Main5Activity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("user1", user1);
intent.putExtras(bundle);
startActivity(intent);
}
});
Main5Activity代码如下:
User1 user1 = (User1) this.getIntent().getParcelableExtra("user1");
String strData =user1.id+" "+user1.name + " " + user1.age;
tx.setText(strData);
界面截图:
⑤、Serializable传递数组
第一:在跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main6Activity))
MainActivity代码如下:
b10.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
List<User> user2 = new ArrayList<User>();//定义一个列表存放数组
user2.add(new User(1,"张靓颖", 41));
user2.add(new User(2,"林俊杰", 38));
Intent intent = new Intent(MainActivity.this,Main6Activity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("user2",(Serializable) user2);
intent.putExtras(bundle);
startActivity(intent);
}
});
Main6Activity代码如下:
List<User> result=(List<User>)this.getIntent().getSerializableExtra("user2");
String strData="";
for(User u:result)
{
strData=strData+u.id+" "+u.name+" "+u.age+"\n";
}
sb.setText(strData);
界面截图:
⑥、Parcelable传递数组
第一:在跳转界面时发送数据(MainActivity)并在另一个界面显示该传递的数据((Main7Activity))
MainActivity代码如下:
b20.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
List<User1> user3=new ArrayList<User1>();//定义一个列表存放数组
user3.add(new User1(1,"黄渤",67));
user3.add(new User1(2,"徐峥",74));
Intent intent=new Intent(MainActivity.this,Main7Activity.class);
Bundle bundle=new Bundle();
bundle.putParcelableArrayList("user3",(ArrayList<? extends Parcelable>)user3);
intent.putExtras(bundle);
startActivity(intent);
}
});
Main7Activity代码如下:
List<User1> results=this.getIntent().getExtras().getParcelableArrayList("user3");
String Date="";
for(User1 u:results)
{
Date=Date+u.id+" "+u.name+" "+u.age+"\n";
}
sz.setText(Date);
界面截图:
总结
Serializable使用IO读写存储在硬盘上。序列化过程使用了反射技术,并且期间产生临时对象,优点代码少,在将对象序列化到存储设置中或将对象序列化后通过网络传输时建议选择Serializable。
Parcelable是直接在内存中读写,我们知道内存的读写速度肯定优于硬盘读写速度,所以Parcelable序列化方式性能上要优于Serializable方式很多。所以Android应用程序在内存间数据传输时推荐使用Parcelable,如activity间传输数据和AIDL数据传递。大多数情况下使用Serializable也是没什么问题的,但是针对Android应用程序在内存间数据传输还是建议大家使用Parcelable方式实现序列化,毕竟性能好很多,其实也没多麻烦。
Parcelable也不是不可以在网络中传输,只不过实现和操作过程过于麻烦并且为了防止android版本不同而导致Parcelable可能不同的情况,因此在序列化到存储设备或者网络传输方面还是尽量选择Serializable接口。
下面是本项目的源代码
https://download.csdn.net/download/Scxioi0/12911067