zoukankan      html  css  js  c++  java
  • Android activity间通讯几种方式

    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<Person> CREATOR = new Creator<Person>() {
            @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:使用这个模式的订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程来执行订阅函数。

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

    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 注册订阅者
        EventBus.getDefault().register(this);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销订阅者
        EventBus.getDefault().unregister(this);
    }    
    
    
    
    • 发布事件
    
    EventBus.getDefault().post(new MessageEvent("Post Event!"));
    
    
  • 相关阅读:
    微信小程序 使用async await
    CSS currentColor 变量的使用
    wn.run万能命令
    (13)浮动布局(控制盒模型在页面的什么位置 什么是清浮动)
    (0)前端总结(HTML + CSS + JQ)
    (12)页面的布局(浮动布局)
    (11)盒模型
    (10)背景图片操作
    (9)字体操作
    (8)伪类选择器和鼠标悬停动画效果
  • 原文地址:https://www.cnblogs.com/chenjy1225/p/9662510.html
Copyright © 2011-2022 走看看