常见的Android数据传递方法汇总
一、Intent与Bundle
1、Activty与Activity
1.1、传递简单数据
(1) 传单个值(以String类型为例)
- 发送数据
Intent intent = new Intent(A.this, B.class);intent.putExtra("key", value);startActivity(intent);
- 接收数据
// 获取数据的方法需要根据传递的数据类型而定Intent reIntent = getIntent();String tempStr = reIntent.getStringExtra("key");
(2)传多个值
- 发送数据
Intent intent = new Intent(A.this, B.class);Bundle bd = new Bundle();bd.putString("name", "张三");bd.putInt("age", 23);intent.putExtras(bd);startActivity(intent);
- 接收数据
Intent reIntent = getIntent();Bundle reBd = reIntent.getExtras();String name = reBd.getString("name");int age = reBd.getInt("age");
1.2、传递复杂数据
- 数组
(1)纯Intent
- 传递数据
Intent intent = new Intent(A.this, B.class);intent.putExtra("arrName", new String[]{"张三", "李四", "王五"});startActivity(intent);
- 接收数据
Intent reIntent = getIntent();reIntent.getStringArrayExtra("arrName");
(2)Intent和Bundle
- 传递数据
Intent intent = new Intent(A.this, B.class);Bundle bd = new Bundle();bd.putStringArray("arrName", new String[]{"张三", "李四", "王五"});intent.putExtras(bd);startActivity(intent);
- 接收数据
Intent reIntent = getIntent();Bundle reBd = reIntent.getExtras();reBd.getStringArray("arrName");
- 集合
(1)List<基本数据类型或String、Integer>
单用Intent或Intent与Bundle结合都可以
- 发送数据
ArrayList<String> strList = new ArrayList<>();stringList.add("张三");stringList.add("李四");Intent listIntent = new Intent(A.this, B.claaa);listIntent.putStringArrayListExtra("strList", strList);startActivity(listIntent);
- 接收数据
Intent reIntent = getIntent();reIntent.getStringArrayListExtra("strList");
(2)List<自定义对象>
- 首先自定义对象要实现Serializable接口
import java.io.Serializable;public class Student implements Serializable {private String name;private int age;private String sex;private String grade;private String school;public Student(String name, int age, String sex, String grade, String school) {this.name = name;this.age = age;this.sex = sex;this.grade = grade;this.school = school;}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 getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getGrade() {return grade;}public void setGrade(String grade) {this.grade = grade;}public String getSchool() {return school;}public void setSchool(String school) {this.school = school;}
}
- 发送数据
Intent intent = new Intent(A.this, B.class);List<Student> studentList = new ArrayList<>();studentList.add(new Student("张三", 25, "男", "大三", "广州大学"));studentList.add(new Student("李四", 24, "男", "大二", "贵州大学"));studentList.add(new Student("李红", 27, "男", "大四", "清华大学"));studentList.add(new Student("王五", 23, "男", "大一", "北京大学"));intent.putExtra("studentList", (Serializable) studentList);startActivity(intent);
- 接收数据
Intent reIntent = getIntent();List<Student> reStudentList = (List<Student>) reIntent.getSerializableExtra("studentList");
- 对象
(1)使用Serializable序列化对象;
- 序列化对象
import java.io.Serializable;/*** 学生*/
public class Student implements Serializable {private String name;private int age;private String sex;private String grade;private String school;public Student(String name, int age, String sex, String grade, String school) {this.name = name;this.age = age;this.sex = sex;this.grade = grade;this.school = school;}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 getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getGrade() {return grade;}public void setGrade(String grade) {this.grade = grade;}public String getSchool() {return school;}public void setSchool(String school) {this.school = school;}
}
- 发送数据
Intent intent = new Intent(A.this, B.class);Student stu1 = new Student("张三", 25, "男", "大三", "广州大学");intent.putExtra("stu1", stu1);startActivity(intent);
- 接收数据
Intent reIntent = getIntent();Student stu1 = (Student) reIntent.getSerializableExtra("stu1");
(2)使用Parcelable序列化对象;
- 序列化对象
import android.os.Parcel;
import android.os.Parcelable;/*** 课程*/
public class Course implements Parcelable {private String courseName;private String courseType;public Course() {}public Course(String courseName, String courseType) {this.courseName = courseName;this.courseType = courseType;}public String getCourseName() {return courseName;}public void setCourseName(String courseName) {this.courseName = courseName;}public String getCourseType() {return courseType;}public void setCourseType(String courseType) {this.courseType = courseType;}@Overridepublic int describeContents() {// 内容描述,返回0就可以return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {// 将Course对象转化成Parcel,// dest是目标Parcel,// flags标志object是如何被写的。// 0或者PARCELABLE_WRITE_RETURN_VALUEdest.writeString(courseName);dest.writeString(courseType);}public static final Creator<Course> CREATOR = new Creator<Course>() {@Overridepublic Course createFromParcel(Parcel in) {// 将Parcel映射成Course对象Course mCourse = new Course();// 同种数据类型,顺序为先进先出mCourse.courseName = in.readString();mCourse.courseType = in.readString();return mCourse;}@Overridepublic Course[] newArray(int size) {return new Course[size];}};
}
- 发送数据
Intent intent = new Intent(A.this, B.class);Course course = new Course("语文", "文科");intent.putExtra("course", course);startActivity(intent);
- 接收数据
Intent reIntent = getIntent();Course mCourse = reIntent.getParcelableExtra("course");
(3)使用Gson将对象转化为Json格式再传递。
- 导入依赖包
//添加Gson依赖implementation 'com.google.code.gson:gson:2.8.8'
- 定义对象
public class Book {private String bookName;private String bookAuthor;public Book(String bookName, String bookAuthor) {this.bookName = bookName;this.bookAuthor = bookAuthor;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getBookAuthor() {return bookAuthor;}public void setBookAuthor(String bookAuthor) {this.bookAuthor = bookAuthor;}
}
- 发送数据
Intent intent = new Intent(A.this, B.class);Book book = new Book("西游记", "吴承恩");intent.putExtra("book", new Gson().toJson(book));startActivity(intent);
- 接收数据
Intent reIntent = getIntent();String bookJson = reIntent.getStringExtra("book");Book mBook = new Gson().fromJson(bookJson, Book.class);
2、Activity与Fragment
2.1、Activity传递数据给Fragment
1、通过构造函数传递
- step1:在RightFragment.java中重载构造函数
private String mData;public RightFragment(String data) {mData = data;}
- step2:在MainActivityFour.java中创建Fragment实例的同时,通过构造函数将数据传递过去
RightFragment rightFragment = new RightFragment("GetDataFromMainTwo");FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fl_right, rightFragment, "rightFragment");transaction.commit();
2、通过setArguments()传递
- step1:在MainActivityFour.java初始化Fragment时,使用setArgments传递数据
RightFragment rightFragment = new RightFragment();Bundle bundle = new Bundle();bundle.putString("main_data", "GetDataFromMainThree");rightFragment.setArguments(bundle);FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fl_right, rightFragment, "rightFragment");transaction.commit();
- step2:在RightFragment.java中获取数据
@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);if (isAdded()) {String getData = "";Bundle bundle = getArguments();if (bundle != null)getData = getArguments().getString("main_data");tvShowContent.setText(getData);}}
3、Fragment中定义方法再调用
- step1:在RightFragment.java中定义一个接收数据的方法
public void setData(String dataMsg) {tvShowContent.setText(dataMsg);}
- step2:在MianActivityFour.java中发送数据
rightFragment.setData("GetDataFromMain");
2.2、Fragment传递数据给Activity
通过接口回调获取数据
- step1:在RightFragment.java中定义一个接口以及设置接口的方法
public onDataTransmissionListener mListener;public interface onDataTransmissionListener {public void dataTransmission(String data);}public void setOnDataTransmissionListener(onDataTransmissionListener mListener) {this.mListener = mListener;}
- step2:在RightFragment.java中通过接口传递数据
if (mListener != null) {mListener.dataTransmission(btnTextTwo.getText().toString());}
- step3:在MianActivityFour.java中设置Fragment并监听RightFragment.java的接口
RightFragment rightFragment = new RightFragment();FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fl_right, rightFragment, "rightFragment");transaction.commit();rightFragment.setOnDataTransmissionListener(new RightFragment.onDataTransmissionListener() {@Overridepublic void dataTransmission(String data) {String fgData = data; //获取Fragment传过来的内容}});
3、Fragment与Fragment
先创建一个简单的布局
<?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"tools:context=".MainActivityFour"android:orientation="horizontal"><FrameLayoutandroid:id="@+id/fl_left"android:layout_width="0dp"android:layout_weight="1"android:layout_height="match_parent"/><FrameLayoutandroid:id="@+id/fl_right"android:layout_width="0dp"android:layout_weight="2"android:layout_height="match_parent"/></LinearLayout>
3.1、获取Fragment的id或Tag
核心代码如下,
- step1:在MainActivityFour.java中设置Fragment
LeftFragment leftFragment = new LeftFragment();RightFragment rightFragment = new RightFragment();FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fl_left, leftFragment, "leftFragment");transaction.replace(R.id.fl_right, rightFragment, "rightFragment");transaction.commit();
- step2:在RightFragment.java中定义一个接收数据的方法
public void setData(String dataMsg) {tvShowContent.setText(dataMsg);}
- step3:在LeftFragment.java中根据FragmentID或FragmentTag获取RightFragment对象
RightFragment rightFragment = (RightFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.fl_right);rightFragment.setData(btnTextOne.getText().toString());
或
RightFragment rightFragment = (RightFragment) getActivity().getSupportFragmentManager().findFragmentByTag("rightFragment");rightFragment.setData(btnTextOne.getText().toString());
3.2、接口回调
- step1:在LeftFragment.java中定义一个接口以及设置接口的方法
public onDataTransmissionListener mListener;public interface onDataTransmissionListener {public void dataTransmission(String data);}public void setOnDataTransmissionListener(onDataTransmissionListener mListener) {this.mListener = mListener;}
- step2:在LeftFragment.java中通过接口传递数据
if (mListener != null) {mListener.dataTransmission(btnTextTwo.getText().toString());}
- step3:在RightFragment.java中定义一个接收数据的方法
public void setData(String dataMsg) {tvShowContent.setText(dataMsg);}
- step4:在MianActivityFour.java中设置Fragment并监听LeftFragment.java的接口
LeftFragment leftFragment = new LeftFragment();RightFragment rightFragment = new RightFragment();FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fl_left, leftFragment, "leftFragment");transaction.replace(R.id.fl_right, rightFragment, "rightFragment");transaction.commit();leftFragment.setOnDataTransmissionListener(new LeftFragment.onDataTransmissionListener() {@Overridepublic void dataTransmission(String data) {rightFragment.setData(data);}});
二、EventBus
上述Activity与Activity、Activity与Fragment以及Frament与Fragment之间的通信,都可以使用EventBus实现,具体步骤如下:
1、在app目录下的build.gradle文件中添加eventbus依赖;
implementation 'org.greenrobot:eventbus:3.0.0'
2、创建EventBus信息传递类;
public class EventInit {private String name;private String age;private String sex;private String grade;private String school;public EventInit(String name, String age, String sex, String grade, String school) {this.name = name;this.age = age;this.sex = sex;this.grade = grade;this.school = school;}public String getAllValue() {return "name: " + name+ "\nage: " + age+ "\nsex: " + sex+ "\ngrade: " + grade+ "\nschool: " + school;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getGrade() {return grade;}public void setGrade(String grade) {this.grade = grade;}public String getSchool() {return school;}public void setSchool(String school) {this.school = school;}
}
3、在发送消息的Activty或Fragment中使用下面代码;
EventBus.getDefault().post(new EventInit(name, age, sex, grade, school));
4、在接收数据的Activity或Fragment中注册和注销EventBus,并接收消息;
一般建议:
(1)在onStart()中注册EventBus.
@Overrideprotected void onStart() {super.onStart();//注册EventBus 接收数据if (!EventBus.getDefault().isRegistered(this)) {EventBus.getDefault().register(this);}}
(2)在onDestroy()中注销EventBus.
@Overrideprotected void onDestroy() {super.onDestroy();//注销事件接收EventBus.getDefault().unregister(this);}
(3)定义接收消息的方法
// 接收消息(post)@Subscribe(threadMode = ThreadMode.MAIN)public void onEventInit(EventInit eventInit) {try {String allValue = eventInit.getAllValue();//更改TextView内容tvReceiveText.setText(allValue);} catch (Exception e) {e.printStackTrace();}}
5、运行程序后,可能会出现如下问题;
(1)在Run窗口可以看到下面的提示,但并不会报错;
EventBus : No subscribers registered for event class
(2)以上问题是由于EventBus不适合向一个不存在于activity栈中的activity发送消息,这样是失败的,fragment同理。
例如:
情况1:一个activity 还没有生成,就post,肯定报这样的错;
情况2:一个activity曾经生成了,但是不在activity栈中了,也是收不到消息的
情况3:生命周期的问题。如果是在onStop()方法中注销了EventBus,而在特殊情况下恰好调用了接收消息的Activty或Fragment中的onStop()方法,这也就出现了上述的问题。
6、解决方法;
(1)依旧使用上述的post方式发送消息,不过需要加上延时操作,如下:
//延时发送数据new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}EventBus.getDefault().post(new EventInit(name, age, sex, grade, school));}}).start();
(2)或者使用postSticky方式替换post方式发送消息,如下:
//使用粘性事件EventBus.getDefault().postSticky(new EventInit(name, age, sex, grade, school));
在接收消息的Activity或Fragment中定义接收消息的方法:
// 接收消息(postStick)
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)public void onEventInitTwo(EventInit eventInit) {try {String allValue = eventInit.getAllValue();//更改TextView内容tvReceiveText.setText(allValue);} catch (Exception e) {e.printStackTrace();}}
(3)post与postSticky相比,若post事件没有被订阅,则该事件会被流传,即作废;而postSicky是将完整的事件放到内存中,待EventBus注册时再从内存中获取该事件,然后包装成一个新的post事件进行发布,由于此时EventBus注册已执行完毕,所以postSticky事件可以正常使用。
常见的Android数据传递方法汇总相关推荐
- 【好文推荐】Activity之间的数据传递方法汇总
在Activity间传递的数据一般比较简单,但是有时候实际开发中也会传一些比较复杂的数据,本节一起来学习更多Activity间数据的传递方法. 1.通过 Intent 传递 我们在进行 Activit ...
- Android零基础入门第83节:Activity间数据传递方法汇总
2019独角兽企业重金招聘Python工程师标准>>> 在Activity间传递的数据一般比较简单,但是有时候实际开发中也会传一些比较复杂的数据,本节一起来学习更多Activity间 ...
- Activity之间的数据传递方法汇总系列教学
近日一好友去阿里面试,面试失败了,分享了一个他最不擅长的算法面试题.题目是这样的. 题目:给定一个二叉搜索树(BST),找到树中第 K 小的节点. 出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深 ...
- php发邮件有时很卡,phpmailer发邮件常见的问题及解决方法汇总
phpmailer发邮件常见的问题及解决方法汇总 发布于 2014-11-22 14:50:36 | 808 次阅读 | 评论: 0 | 来源: 网友投递 PHPMailer 发送电子邮件的PHP函数 ...
- 用友T+数据备份与恢复方法汇总
用友T+数据备份与恢复方法汇总 前言:由于不可预知的原因(计算机病毒.硬件损坏.人为原因等等),造成用友数据丢失或者损坏,所以定时定期对用友数据进行备份,可以备份到本机硬盘,同时也建议再备份到移动硬盘 ...
- 二、深度学习数据增强方法汇总
深度学习模型训练数据增强方法汇总 一.随机裁剪 二.RGB-->BGR通道互换 三.仿射变换(缩放) 三.随机旋转 四.对比度调整 五.随机抠图 六.bound box 中心点随机抠图 七.随机 ...
- vue组件穿方法_vue组件中的数据传递方法
Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递.组件之间传递数据大致分为三种情况: 父组件向子组件传递数据,通过 props ...
- Python Pandas 列数据筛选方法汇总
Pandas 列数据筛选方法汇总 数据准备: 一.筛选得到指定的列 1.1 根据 label 选择特定的几列 1.2 选择单列的两种方式 1.3 通过正则表达式选择列 二.同时对 行 和 列 进行筛选 ...
- Android Http请求方法汇总
Android Http请求方法汇总 这篇文章主要实现了在Android中使用JDK的HttpURLConnection和Apache的HttpClient访问网络资源,服务端采用python+fla ...
最新文章
- suse linux 备份,suse linux利用scp实现自动远程备份
- [Spark][翻译]Spark 架构: Shuffle过程分析
- Android自定义动态壁纸,Android自定义动态壁纸开发详解
- OpenCV创建3D直方图
- CSS基础学习 18.CSS多列
- LeetCode 285. 二叉搜索树中的顺序后继(中序遍历)
- Django makemigration No changes detected
- window.open打开页面并传值,window. location.search遍历获取到的请求链接中的所有参数
- 如何将内网ip映射到外网
- matlab快速实现线性规划求解
- html表格自动变色,让考勤表实现自动变色
- java通过freemarker导出包含富文本图片的word文档
- 哈登独得40分保罗复出 火箭主场103:98复仇魔术
- 地理数据库GeoNames,并导入Mysql
- 心血漏洞(OpenSSL升级)
- Invalid name supplied, making object name syntactically valid. New object name is Seurat..ProjectDim
- 从零开始社区之路,手把手教你开源自己的Python包
- 个人征信已开放,互联网巨头如何行动
- python flask简单使用
- 【统计方法】基于熵值法的面板数据指标权重计算