原文地址:https://www.jianshu.com/p/1169dba99261

intent传递数据

为什么要和intent单独拿出来讲,因为Intent传递数据也是非常重要的

一、简单的传递数据

二、传递数组

bd.putStringArray("StringArray", new String[]{"呵呵","哈哈"}); //可把StringArray换成其他数据类型,比如int,float等等.. 

读取数组:

String[] str = bd.getStringArray("StringArray")

三、传递集合

1)List<基本数据类型或String>

intent.putStringArrayListExtra(name, value)
intent.putIntegerArrayListExtra(name, value)

读取集合:

intent.getStringArrayListExtra(name)
intent.getIntegerArrayListExtra(name)

2)List< Object>

将list强转成Serializable类型,然后传入(可用Bundle做媒介)

写入集合:

putExtras(key, (Serializable)list)

读取集合:

(List<Object>) getIntent().getSerializable(key)

PS:Object类需要实现Serializable接口

3)Map<String, Object>,或更复杂的

解决方法是:外层套个List

//传递复杂些的参数
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("key1", "value1"); map1.put("key2", "value2"); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); list.add(map1); Intent intent = new Intent(); intent.setClass(MainActivity.this,ComplexActivity.class); Bundle bundle = new Bundle(); //须定义一个list用于在budnle中传递需要传递的ArrayList<Object>,这个是必须要的 ArrayList bundlelist = new ArrayList(); bundlelist.add(list); bundle.putParcelableArrayList("list",bundlelist); intent.putExtras(bundle); startActivity(intent); 

四、Intent传递对象

传递对象的方式有两种:将对象转换为Json字符串或者通过Serializable,Parcelable序列化 不建议使用Android内置的抠脚Json解析器,可使用fastjson或者Gson第三方库!


1)将对象转换为Json字符串

Gson解析的例子:

Model:

public class Book{ private int id; private String title; //... } public class Author{ private int id; private String name; //... } 

写入数据:

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()); 

2)使用Serializable,Parcelable序列化对象

但是不知道你有没有发现,putExtra()方法中所支持的数据类型是有限的,虽然常用的一些数据类型它都会支持,但是当你想去传递一些自定义对象的时候就会发现无从下手。不用担心,下面我们就学习一下使用Intent 来传递对象的技巧。

方式一:Serializable 方式

Serializable 是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。至于序列化的方法也很简单,只需要让一个类去实现Serializable 这个接口就可以了。
比如说有一个Person 类,其中包含了name 和age 这两个字段,想要将它序列化就可以这样写:

public class Person implements Serializable{ 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; } } 

其中get、set 方法都是用于赋值和读取字段数据的,最重要的部分是在第一行。这里让Person 类去实现了Serializable 接口,这样所有的Person 对象就都是可序列化的了。

接下来在FirstActivity 中的写法非常简单:

Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("person_data", person); startActivity(intent); 

可以看到,这里我们创建了一个Person 的实例,然后就直接将它传入到putExtra()方法中了。由于Person 类实现了Serializable 接口,所以才可以这样写。

接下来在SecondActivity 中获取这个对象也很简单,写法如下:

Person person = (Person) getIntent().getSerializableExtra("person_data");
方式二:Parcelable

除了Serializable 之外,使用Parcelable 也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable 方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent 所支持的数据类型,这样也就实现传递对象的功能了。
下面我们来看一下Parcelable 的实现方式,修改Person 中的代码,如下所示:

public class Person implements Parcelable { private String name; private int age; @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated method stub dest.writeString(name); dest.writeInt(age); } public static final Parcelable.Creator<Person> CREATOR=new Parcelable.Creator<Person>() { @Override public Person createFromParcel(Parcel source) { // TODO Auto-generated method stub Person person=new Person(); person.name=source.readString(); person.age=source.readInt(); return person; } @Override public Person[] newArray(int size) { // TODO Auto-generated method stub return new Person[size]; } }; } 

Parcelable 的实现方式要稍微复杂一些。可以看到,首先我们让Person 类去实现了Parcelable 接口,这样就必须重写describeContents()和writeToParcel()这两个方法。其中describeContents()方法直接返回0 就可以了,而writeToParcel()方法中我们需要调用Parcel的writeXxx()方法将Person 类中的字段一一写出。注意字符串型数据就调用writeString()方法,整型数据就调用writeInt()方法,以此类推。

除此之外,我们还必须在Person 类中提供一个名为CREATOR 的常量,这里创建了Parcelable.Creator 接口的一个实现,并将泛型指定为Person。接着需要重写createFromParcel()和newArray()这两个方法,在createFromParcel()方法中我们要去读取刚才写出的name 和age字段,并创建一个Person 对象进行返回,其中name 和age 都是调用Parcel 的readXxx()方法读取到的,注意这里读取的顺序一定要和刚才写出的顺序完全相同。而newArray()方法中的实现就简单多了,只需要new 出一个Person 数组,并使用方法中传入的size 作为数组大小就可以了。

接下来在FirstActivity 中我们仍然可以使用相同的代码来传递Person 对象,只不过在SecondActivity 中获取对象的时候需要稍加改动,如下所示:

Person person = (Person) getIntent().getParcelableExtra("person_data");

注意这里不再是调用getSerializableExtra()方法,而是调用getParcelableExtra()方法来获取传递过来的对象了,其他的地方都完全相同。这样我们就把使用Intent 来传递对象的两种实现方式都学习完了,对比一下,Serializable的方式较为简单,在这里强调一下,网上很多博客很多文章都说Parcelable要比Serializable效率要高,其实不然,在读取速度方面Serializable其实他要比Parcelable更快,具体我们可以看一下这篇文章
http://www.jianshu.com/p/fcc59fb523b6

五、Intent传递Bitmap

bitmap默认实现Parcelable接口,直接传递即可

Bitmap bitmap = null;
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap); intent.putExtra("bundle", bundle); 

六、定义全局数据,传递数据

如果是传递简单的数据,有这样的需求,Activity1 -> Activity2 -> Activity3 -> Activity4, 你想在Activity中传递某个数据到Activity4中,怎么破,一个个页面传么?

显然不科学是吧,如果你想某个数据可以在任何地方都能获取到,你就可以考虑使用 Application全局对象了!

关键部分代码:

第一步自定义Application类:
class MyApp extends Application { private String myState; public String getState(){ return myState; } public void setState(String s){ myState = s; } } 
第二步AndroidManifest.xml中声明:
<application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name"> 
第三步在需要的地方调用:
class Blah extends Activity { @Override public void onCreate(Bundle b){ ... MyApp appState = ((MyApp)getApplicationContext()); String state = appState.getState(); ... } } 

高逼格写法
:在任何位置都能获取到Application全局对象。

Applicaiton是系统的一个组件,他也有自己的一个生命周期,我们可以在onCraete里获得这个 Application对象。贴下修改后的代码吧!

class MyApp extends Application { private String myState; private static MyApp instance; public static MyApp getInstance(){ return instance; } public String getState(){ return myState; } public void setState(String s){ myState = s; } @Override public void onCreate(){ onCreate(); instance = this; } } 

然后在任意地方我们就可以直接调用:MyApp.getInstance()来获得Application的全局对象!

注意事项:
Application对象是存在于内存中的,也就有它可能会被系统杀死,比如这样的场景:
我们在Activity1中往application中存储了用户账号,然后在Activity2中获取到用户账号,并且显示!

如果我们点击home键,然后过了N久候,系统为了回收内存kill掉了我们的app。这个时候,我们重新 打开这个app,这个时候很神奇的,回到了Activity2的页面,但是如果这个时候你再去获取Application 里的用户账号,程序就会报NullPointerException,然后crash掉~
之所以会发生上述crash,是因为这个Application对象是全新创建的,可能你以为App是重新启动的, 其实并不是,仅仅是创建一个新的Application,然后启动上次用户离开时的Activity,从而创造App 并没有被杀死的假象!所以如果是比较重要的数据的话,建议你还是进行本地化,另外在使用数据的时候 要对变量的值进行非空检查!还有一点就是:不止是Application变量会这样,单例对象以及公共静态变量 也会这样~

七、单例模式传参

上面的Application就是基于单例的,单例模式的特点就是可以保证系统中一个类有且只有一个实例。 这样很容易就能实现,在A中设置参数,在B中直接访问了。这是几种方法中效率最高的。

范例代码:(代码来自于网上~)

①定义一个单例类:

public class XclSingleton { //单例模式实例 private static XclSingleton instance = null; //synchronized 用于线程安全,防止多线程同时创建实例 public synchronized static XclSingleton getInstance(){ if(instance == null){ instance = new XclSingleton(); } return instance; } final HashMap<String, Object> mMap; private XclSingleton() { mMap = new HashMap<String,Object>(); } public void put(String key,Object value){ mMap.put(key,value); } public Object get(String key) { return mMap.get(key); } } 

②设置参数:

XclSingleton.getInstance().put("key1", "value1");
XclSingleton.getInstance().put("key2", "value2"); 

作者:侯蛋蛋_
链接:https://www.jianshu.com/p/1169dba99261
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/kexing/p/8270667.html

【转】Android 之最新最全的Intent传递数据方法相关推荐

  1. Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...

  2. android intent传递数据

    说到intent传递数据,其实我是经常用到,不过之前用的都是简单的传递String,int,boolean的简单数据.昨天,我需要传递一个自定义的实体类时,发现自己不会,所以在网上搜索了一些资料,自己 ...

  3. Android之Intent传递数据

    1.Android中的Intent对象中包含了多个putXXX()方法(如putExtra()方法)用来插入不同类型的额外数据,也包含了多个getXXX()方法(如getStringExtra().g ...

  4. android中intent放数据类型,Android Intent传递数据底层分析详细介绍

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...

  5. Android学习之利用Intent传递数据

    你能通过这篇文章学习到什么? 1. 利用intent在两个activity之间传递数据 2. 利用intent在两个activity之间传递数据包 3. 利用intent获取到返回数据 很多人在刚开始 ...

  6. Intent传递数据时,可以传递哪些类型数据

    Intent传递数据时,下列的数据类型哪些可以被传递(abcd)(多选) A.Serializable  B.charsequence C.Parcelable  D.Bundle 除了上面的还能传递 ...

  7. Intent传递数据的方法

    Intent传递数据的方法 一.传递的数据是基本类型的 二.传递的数据是对象 使用intent的putExtra()方法,可以将要传递的数据附加到Intent对象,然后使用Intent对象进行数据传递 ...

  8. Intent传递数据全解

    概述 之前的博文也有介绍,查看-->用户界面开发基础 这里单独抽取出来,更加详细的记录一下,其实主要是API的使用. Intent传递简单数据 可以以直接通过调用Intent的putExtra( ...

  9. Android 开发中使用Intent传递数据的方法

    Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short ...

最新文章

  1. Wpf体系结构的学习
  2. CodeForces - 1334D Minimum Euler Cycle(构造+模拟)
  3. 常见音视频格式(转载)
  4. Linux的iovec、readv和writev
  5. 如果你正在使用CocoaPods,你的.gitignore会有什么?
  6. JavaScript中函数的上下文——this
  7. 最新消息,网易公司内部开始使用昵称!学阿里?
  8. Linux下多线程调试以及查看信息
  9. linux补丁服务,Linux补丁程序管理_补丁工具 _ ManageEngine Desktop Central
  10. 网管人员必备的常用命
  11. 遥感水文前景_遥感水文
  12. protobuf和json的对比
  13. 【信管1.1】信息系统与信息化
  14. IPv4 至 IPv6改造过渡方案
  15. 《军团要塞2》绘画渲染
  16. 众筹源码 php,助创cms众筹源码系统v1.0
  17. Web全栈架构师(三)——NodeJS+持久化学习笔记(2)
  18. php错误测试,对 PHP 错误进行测试
  19. Particle for alexa smart home skill (4)
  20. 基于Vue实现一个简易的小程序框架,浅谈kafka | 每日掘金第 194 期

热门文章

  1. PyQt5 技术篇-scrollArea不显示滚动条解决方法,Qt Designer不显示滚动条,滚动条的显示和隐藏
  2. Python知识点笔记-条件选择、循环和函数
  3. 用C语言实现控制台模拟显示时
  4. CTFshow php特性 web98
  5. python编译安装pyaudio
  6. hdu4549 M斐波那契数列
  7. xpath如何得到【爬虫】
  8. LCS(最长公共子串)系列问题
  9. Qt实现拖动一个lineEdit同时拖动mainwindow
  10. 13.7 线程生命周期状态图、线程常用的方法。