Android中传递对象的三种方法
Android知识、前端、后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过!
Android中,Activity和Fragment之间传递对象,可以通过将对象序列化并存入Bundle或者Intent中进行传递,也可以将对象转化为JSON字符串,进行传递。
序列化对象可以使用Java的Serializable的接口、Parcelable接口。转化成JSON字符串,可以使用Gson等库。
1.Serializable
Model
- public class Author implements Serializable{
 - private int id;
 - private String name;
 - //...
 - }
 
- public class Book implements Serializable{
 - private String title;
 - private Author author;
 - //...
 - }
 
传递数据
- Book book=new Book();
 - book.setTitle("Java编程思想");
 - Author author=new Author();
 - author.setId(1);
 - author.setName("Bruce Eckel");
 - book.setAuthor(author);
 - Intent intent=new Intent(this,SecondActivity.class);
 - intent.putExtra("book",book);
 - startActivity(intent);
 
接收数据
- Book book= (Book) getIntent().getSerializableExtra("book");
 - Log.d(TAG,"book title->"+book.getTitle());
 - Log.d(TAG,"book author name->"+book.getAuthor().getName());
 
2.转化为JSON字符串
Model
- public class Author{
 - private int id;
 - private String name;
 - //...
 - }
 - public class Book{
 - private String title;
 - private Author author;
 - //...
 - }
 
传递数据
- Book book=new Book();
 - book.setTitle("Java编程思想");
 - Author author=new Author();
 - author.setId(1);
 - author.setName("Bruce Eckel");
 - book.setAuthor(author);
 - Intent intent=new Intent(this,SecondActivity.class);
 - intent.putExtra("book",new Gson().toJson(book));
 - startActivity(intent);
 
接收数据
- String bookJson=getIntent().getStringExtra("book");
 - Book book=new Gson().fromJson(bookJson,Book.class);
 - Log.d(TAG,"book title->"+book.getTitle());
 - Log.d(TAG,"book author name->"+book.getAuthor().getName());
 
3.使用Parcelable
实现Parcelable接口需要实现两个方法
describeContents方法。内容接口描述,默认返回0就可以;
writeToParcel方法。将传递的数据打包到Parcel容器中。
除了要实现这两个方法还必须创建一个Parcelable.Creator接口的实例,用于读取Parcel容器中的数据
Model
- public class Author implements Parcelable{
 - private int id;
 - private String name;
 - //setter & getter...
 - @Override
 - public int describeContents() {
 - return 0;
 - }
 - @Override
 - public void writeToParcel(Parcel dest, int flags) {
 - //该方法将类的数据写入外部提供的Parcel中.即打包需要传递的数据到Parcel容器保存,
 - // 以便从parcel容器获取数据
 - dest.writeString(name);
 - dest.writeInt(id);
 - }
 - public static final Creator<Author> CREATOR=new Creator<Author>() {
 - @Override
 - public Author createFromParcel(Parcel source) {
 - //从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层。
 - Author author=new Author();
 - author.setName(source.readString());
 - author.setId(source.readInt());
 - return author;
 - }
 - @Override
 - public Author[] newArray(int size) {
 - //创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。方法是供外部类反序列化本类数组使用。
 - return new Author[size];
 - }
 - };
 - }
 
- public class Book implements Parcelable{
 - private String title;
 - private Author author;
 - //setter & getter...
 - @Override
 - public int describeContents() {
 - return 0;
 - }
 - @Override
 - public void writeToParcel(Parcel dest, int flags) {
 - dest.writeString(title);
 - dest.writeParcelable(author,flags);
 - }
 - public static final Creator<Book> CREATOR=new Creator<Book>() {
 - @Override
 - public Book createFromParcel(Parcel source) {
 - Book book=new Book();
 - book.setTitle(source.readString());
 - book.setAuthor(source.<Author>readParcelable(Author.class.getClassLoader()));
 - return book;
 - }
 - @Override
 - public Book[] newArray(int size) {
 - return new Book[0];
 - }
 - };
 - }
 
传递数据
- Book book=new Book();
 - book.setTitle("Java编程思想");
 - Author author=new Author();
 - author.setId(1);
 - author.setName("Bruce Eckel");
 - book.setAuthor(author);
 - Intent intent=new Intent(this,SecondActivity.class);
 - intent.putExtra("book",book);
 - startActivity(intent);
 
接收数据
- Book book=getIntent().getParcelableExtra("book");
 - Log.d(TAG,"book title->"+book.getTitle());
 - Log.d(TAG,"book author name->"+book.getAuthor().getName());
 
4.性能分析
经过测试,我们得到下图的效果

可以看出,通过转换为字符串的速度是最慢的。Seralizable次之,Parcelable比Seralizable快10倍。所以从性能上考 虑,我们必定优先选择Parcelable。但是Parcelable有大量重复的模板代码,如何简化这些操作,将是下面主要讲解的内容。
5.简化Parcel操作
如果你使用android Studio 可以通过安装android-parcelable-intellij-plugin插件,或者自己配置模板进行操作。
5.1 parceler
除了上面的操作,还有大量的第三方库来简化Parcelable操作。当然使用这些库也许会降低Parcelable的性能。Parceler就是这样一个库。
Parceler使用非常简单,在定义Model时用@Parcel进行注解,在传递数据的时候使用Parcels的wrap方法来包装成一个Parcelable对象。获取数据时用Parcels的unwrap方法来获取对象。
Model
- @Parcel
 - public class Author {
 - int id;
 - String name;
 - //setter & getter...
 - }
 
- @Parcel
 - public class Book {
 - String title;
 - Author author;
 - //setter & getter
 - }
 
传递对象
- Book book=new Book();
 - book.setTitle("Java编程思想");
 - Author author=new Author();
 - author.setId(1);
 - author.setName("Bruce Eckel");
 - book.setAuthor(author);
 - Intent intent=new Intent(this,SecondActivity.class);
 - intent.putExtra("book", Parcels.wrap(book));
 - startActivity(intent);
 
接收对象
- Book book= Parcels.unwrap(getIntent().getParcelableExtra("book"));
 - Log.d(TAG,"book title->"+book.getTitle());
 - Log.d(TAG,"book author name->"+book.getAuthor().getName());
 
除了Parceler之外,还有如auto-parcel,ParcelableCodeGenerator,ParcelableGenerator等第三方库,这里我将不进行讲解,有兴趣的朋友,可以自行研究。
Android中传递对象的三种方法的更多相关文章
- mfc 在VC的两个对话框类中传递参数的三种方法
		
弄了好久,今天终于把在VC中的对话框类之间传递参数的问题解决了,很开心,记录如下: 1. 我所建立的工程是一个基于MFC对话框的应用程序,一共有三个对话框,第一个对话框为主对话框,所对应的类为CTMD ...
 - URL转Drawable之 Android中获取网络图片的三种方法
		
转载自: http://doinone.iteye.com/blog/1074283 Android中获取网络图片是一件耗时的操作,如果直接获取有可能会出现应用程序无响应(ANR:Applicatio ...
 - Android中全屏 取消标题栏,TabHost中设置NoTitleBar的三种方法(转)
		
Android中全屏 取消标题栏,TabHost中设置NoTitleBar的三种方法http://www.cnblogs.com/zdz8207/archive/2013/02/27/android- ...
 - android中解析文件的三种方式
		
android中解析文件的三种方式 好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...
 - jQuery中detach&&remove&&empty三种方法的区别
		
jQuery中empty&&remove&&detach三种方法的区别 empty():移除指定元素内部的所有内容,但不包括它本身 remove():移除指定元素内部的 ...
 - Hibernate中Java对象的三种状态
		
Hibernate中Java对象的三种 ...
 - javascript生成对象的三种方法
		
/** js生成对象的三种方法*/ // 1.通过new Object,然后添加属性 示例如下: var people1 = new Object(); people1.name = 'xiaohai ...
 - Openerp 中打开 URL 的三种 方法
		
来自:http://shine-it.net/index.php/topic,8013.0.html 最近总结了,Openerp 中打开 URL 的三种 方法: 一.在form view 添加 < ...
 - mysql 中添加索引的三种方法
		
原文:http://www.andyqian.com/2016/04/06/database/mysqleindex/ 在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以 ...
 
随机推荐
- centos下升级python
			
1. wget http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tgz 2.解压之后 tar -xzvf Python-3.3.0.tgz 3 ...
 - uva12099 The Bookcase
			
这道题超经典.dp和优化都值得看一看.因为i+1只和i有关,用滚动数组节省空间暑假第一次做感觉很困难,现在看就清晰了很多 #include<cstdio> #include<cstr ...
 - Lampiao(dirtycow)脏牛漏洞复现
			
nmap扫描内网80端口发现目标主机 nmap -sP -p 80 192.168.31.0/24 扫描发现目标主机开放22端口.并且 1898端口开放http服务 御剑扫描目录并访问之后发现存 ...
 - 和为S
			
2518 和为S 2 秒 262,144 KB 10 分 2 级题 小b有一个01序列A,她想知道A有多少个非空连续子序列和为S. 你能帮帮她吗? 收起 输入 第一行输入一个数n,表示A的长度 ...
 - centos7下LVM挂载和扩容
			
说明:此操作在centos7下进行,如果是centos6发行版,需要注意格式化LV的文件系统类型(centos7.0开始默认文件系统是xfs,centos6是ext4).最后一步写入系统的类型,其中文 ...
 - python编码的初识
			
用途:  密码本:二进制 与 文字的对应关系 ASCII:  最早的密码本:二进制与 英文字母,数字,特殊字符的对应关系 格式: 01100001 a 01100010 b 字节数:  英文1个 ...
 - fossil 使用
			
~$ fossil updateCannot figure out who you are! Consider using the --usercommand line option, setting ...
 - pytorch系列 -- 9 pytorch nn.init 中实现的初始化函数 uniform, normal, const, Xavier, He initialization
			
本文内容:1. Xavier 初始化2. nn.init 中各种初始化函数3. He 初始化 torch.init https://pytorch.org/docs/stable/nn.html#to ...
 - luogu P1866 编号
			
题目描述 太郎有N只兔子,现在为了方便识别它们,太郎要给他们编号.兔子们向太郎表达了它们对号码的喜好,每个兔子i想要一个整数,介于1和Maxnumber[i]之间(包括1和Maxnumber[i]). ...
 - STL源码分析-iterator(迭代器)
			
1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...