博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android activity间通讯几种方式
阅读量:5101 次
发布时间:2019-06-13

本文共 4838 字,大约阅读时间需要 16 分钟。

Activity 通讯

Bundle

我们可以通过将数据封装在Bundle对象中 ,然后在Intent跳转的时候携带Bundle对象

bundle 本质上是使用 arrayMap实现的

Bundle bundle = new Bundle();bundle.putString("name", "chenjy");bundle.putInt("age", 18);Intent intent = new Intent(MainActivity.this, SecondActivity.class);intent.putExtras(bundle);startActivity(intent);

用上述方法可以传递基本数据类型和String类型的数据,如果传递的是对象就需要进行序列化。

Serializable 和 Parcelable

SerializableParcelable是两个序列化接口,如果使用BundleIntent之间传递对象需要先进行序列化。

  • 序列化的目的

1.通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的.因此序列化的目的是将对象数据转换成字节流的形式

2.将对象数据在进程之间进行传递(Activity之间传递对象数据时,需要在当前的Activity中对对象数据进行序列化操作.在另一个Activity中需要进行反序列化操作讲数据取出)

3.Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长(即每个对象都在JVM中)但在现实应用中,就可能要停止JVM运行,但有要保存某些指定的对象,并在将来重新读取被保存的对象。这是Java对象序列化就能够实现该功能。(可选择入数据库、或文件的形式保存)

4.序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化.

Serializable

Serializable是由Java提供的序列化接口,它是一个空接口。

Person:

public class Person implements Serializable {    private String name;    private int age;    public Person() {}    public void setName(String name){        this.name = name;    }    public void setAge(int age){        this.age = age;    }    public String getName(){        return name;    }    public int getAge(){        return age;    }}

MainActivity:

Person person = new Person();                person.setName("chenjy");                person.setAge(18);                Bundle bundle = new Bundle();                bundle.putSerializable("person",person);                Intent intent = new Intent(MainActivity.this, SecondActivity.class);                intent.putExtras(bundle);                startActivity(intent);

SecondAcitvity:

Person person = (Person)getIntent().getSerializableExtra("person");

这种序列化是通过反射机制从而削弱了性能,这种机制也创建了大量的临时对象从而引起GC频繁回收调用资源。

Parcelable

Parcelable是由Android提供的序列化接口,google做了大量的优化

Person:

public class Person implements Parcelable {    private String name;    private int age;    public Person() {}    protected Person(Parcel in) {        name = in.readString();        age = in.readInt();    }    public void setName(String name){        this.name = name;    }    public void setAge(int age){        this.age = age;    }    public String getName(){        return name;    }    public int getAge(){        return age;    }    public static final Creator
CREATOR = new Creator
() { @Override public Person createFromParcel(Parcel in) { Person person = new Person(); person.name = in.readString(); person.age = in.readInt(); return person; } @Override public Person[] newArray(int size) { return new Person[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); }}

运用真实的序列化处理代替反射,大量的引入代码但是速度会远快于Serializable

所以优先选择Parcelable

arrayMap 1)

arrayMapHashMap的替代品,因为手机的内存很宝贵,如果内存使用不当很容易引起OOM.arrayMap就是通过牺牲时间来换取空间的方式。

arrayMap 使用两个数组来保存 key 和value的数据。arrayMapkey使用二分法排序。在增、删、改使用的是二分查找法,查找效率比传统hashmap 会慢很多。在增、删元素以后会对空间进行调整,所以不适合数据量较大的场景。

arrayMap类似的还有SparseArray

类静态变量

可以通过public static定义Activity的静态变量然后在其他Activity使用类名.变量名传递

Application

可以通过在Application 中的全局静态变量来实现

EventBus

但是当传输的数据量较大的时候Parcelable虽然很便捷,但是会出现异常TransactionTooLargeException。只时候就需要用到插件EventBus

EventBus 使用的是发布 订阅者模型,发布者通过EventBus发布事件,订阅者通过EventBus订阅事件。当发布者发布事件时,订阅该事件的订阅者的事件处理方法将被调用。

  • 定义事件
public class MessageEvent {    private String message;    public MessageEvent(String message) {        this.message = message;    }    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }}
  • 订阅事件

使用@Subscribe注解来定义订阅者方法,方法名可以是任意合法的方法名,参数类型为订阅事件的类型

@Subscribe(threadMode = ThreadMode.MAIN)public void onMessageEvent(MessageEvent event) {    ...}

@Subscribe(threadMode = ThreadMode.MAIN)中使用了ThreadMode.MAIN这个模式,表示该函数在主线程即UI线程中执行

EventBus总共有四种线程模式,分别是:

ThreadMode.MAIN:表示无论事件是在哪个线程发布出来的,该事件订阅方法onEvent都会在UI线程中执行,这个在Android中是非常有用的,因为在Android中只能在UI线程中更新UI,所有在此模式下的方法是不能执行耗时操作的。

ThreadMode.POSTING:表示事件在哪个线程中发布出来的,事件订阅函数onEvent就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。

ThreadMode.BACKGROUND:表示如果事件在UI线程中发布出来的,那么订阅函数onEvent就会在子线程中运行,如果事件本来就是在子线程中发布出来的,那么订阅函数直接在该子线程中执行。

ThreadMode.AYSNC:使用这个模式的订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程来执行订阅函数。

订阅者还需要在总线上注册,并在不需要时在总线上注销

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    // 注册订阅者    EventBus.getDefault().register(this);}@Overrideprotected void onDestroy() {    super.onDestroy();    // 注销订阅者    EventBus.getDefault().unregister(this);}
  • 发布事件
EventBus.getDefault().post(new MessageEvent("Post Event!"));

转载于:https://www.cnblogs.com/chenjy1225/p/9662510.html

你可能感兴趣的文章
struts2与spring整合问题,访问struts2链接时,spring会负责创建Action
查看>>
CentOS 6.8 编译安装MySQL5.5.32
查看>>
Kafka的配置文件详细描述
查看>>
【转】设计模式六大原则(1):单一职责原则
查看>>
iOS 绝对值方法
查看>>
linux crontab
查看>>
你应该知道的Linux历史
查看>>
ssh 认证指定端口
查看>>
[译] 在Web API 2 中实现带JSON的Patch请求
查看>>
ModelAndView详解
查看>>
no such file or directory : 'users/shikx/xxx/xxx/Appirater.m'
查看>>
EXTJS4自学手册——EXT基本方法、属性(mixins多继承、statics、require)
查看>>
接口测试总结
查看>>
hdu 1114 Piggy-Bank
查看>>
如何制作并更改项目icon文件
查看>>
设计模式:迭代器模式(Iterator)
查看>>
cmd批处理常用符号详解
查看>>
关于给构造函数传达参数方法
查看>>
mysql忘记密码时如何修改root用户密码
查看>>
python基础知识(day3)
查看>>