ca88编程伊夫ntBus使用安详严整

作者:ca88编程
1、基本框架搭建

莫不我们从三个Activity跳转到第三个Activity的程序应该都会写,这里先微微把七个Activity跳转的代码建起来。前面再增多伊芙ntBus相关的代码。

MainActivity布局(activity_main.xml)

<LinearLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android: android:layout_width="match_parent" android:layout_height="wrap_content" android:text="btn_bty"/> <TextView android: android:layout_width="wrap_content" android:layout_height="match_parent"/> </LinearLayout> 

新建叁个Activity,SecondActivity构造(activity_second.xml)

<LinearLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.harvic.try_eventbus_1.SecondActivity" > <Button android: android:layout_width="match_parent" android:layout_height="wrap_content" android:text="First Event"/> </LinearLayout> 

MainActivity.java (点击btn跳转到第二个Activity)

public class MainActivity extends Activity { Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn =  findViewById(R.id.btn_try); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick { // TODO Auto-generated method stub Intent intent = new Intent(getApplicationContext(), SecondActivity.class); startActivity; } }); } } 

到这,基本框架就搭完了,上边起首按步骤使用EventBus了。

这两天在合营社做一个周边于手提式有线电话机工厂格局的二个品类,用来检查评定别的各样App是或不是平常办事,所以供给是拼命三郎的轻量级,因为是检查评定别的App的干活,所以总体项目都以新闻之间的频频相互作用。在档期的顺序中留存非常多Fragment和Fragment之间的音讯相互,早前一贯在用广播来实现不过广播使用起来相比麻烦且效用不高。在同事的建议下学习了EventBus,在这里做一下就学记录,侵害权益请告诉一定及时去除。

转发请标记出处:
正文来源【赵彦军的博客】

1、下载EventBus的类库

源码:

Log如下:
D/MAIN: mainD/POSTING: mainD/ASYNC: pool-1-thread-1D/BACKGROUND: pool-1-thread-2

从日记打字与印刷结果能够看看,若是在UI线程中发表事件,则线程模型为POSTING的事件管理函数也实行在UI线程,与发表事件的线程一致。线程模型为ASYNC的事件管理函数推行在名字称为pool-1-thread-1的新的线程中。而MAIN的事件管理函数实行在UI线程,BACKGROUND的年月管理函数实行在名字称为pool-1-thread-2的新的线程中。

2.我们在子线程发送一条新闻看看Log情形

button.setOnClickListener(new View.OnClickListener() { @Override public void onClick { new Thread(new Runnable() { @Override public void run() { Log.d("post", Thread.currentThread().getName; EventBus.getDefault().post(new MessageEvent("NewMesage")); } }).start;

Log如下:

D/post: Thread-153D/BACKGROUND: Thread-153D/POSTING: Thread-153D/MAIN: mainD/ASYNC: pool-1-thread-1

从日记打字与印刷结果轻巧看出,假诺在子线程中揭露事件,则线程模型为POSTING的事件管理函数也实行在子线程,与发表事件的线程一致。BACKGROUND事件模型也与揭橥事件在同一线程试行。ASYNC则在二个称呼pool-1-thread-1的新线程中推行。MAIN依旧在UI线程中实行。

黏性事件和大家的粘性广播很左近,正是在发送事件过后再订阅该事件也能吸收接纳该事件。

EventBus源码深入分析

  • Subscribe 接口源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

能够看出默许的线程模型是ThreadMode.POSTING ;暗中同意黏性事件为false,也正是私下认可不开启黏性事件;暗中认可的优选级为0

  • EventBus 类部分源码
  static volatile EventBus defaultInstance;

   /** Convenience singleton for apps using a process-wide EventBus instance. */
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

getDefault(卡塔尔(قطر‎ 是三个单例形式 , 唯有三个实例对象。

  • ThreadMode 类源码
public enum ThreadMode {

    /**
     * Subscriber will be called in the same thread, which is posting the event. This is the default. Event delivery
     * implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for
     * simple tasks that are known to complete is a very short time without requiring the main thread. Event handlers
     * using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
     */

    POSTING,

    /**
     * Subscriber will be called in Android's main thread (sometimes referred to as UI thread). If the posting thread is
     * the main thread, event handler methods will be called directly. Event handlers using this mode must return
     * quickly to avoid blocking the main thread.
     */

    MAIN,

    /**
     * Subscriber will be called in a background thread. If posting thread is not the main thread, event handler methods
     * will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single
     * background thread, that will deliver all its events sequentially. Event handlers using this mode should try to
     * return quickly to avoid blocking the background thread.
     */

    BACKGROUND,

    /**
     * Event handler methods are called in a separate thread. This is always independent from the posting thread and the
     * main thread. Posting events never wait for event handler methods using this mode. Event handler methods should
     * use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number
     * of long running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus
     * uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.
     */

    ASYNC
}

本条类是枚举类,定义了线程模型中的几系列型。

3.线程模型
全部代码

何以加多信赖

  • 在module的build.gredle 文件中的dependencies标签中加多

    compile 'org.greenrobot:eventbus:3.0.0'

例如

 apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.3"

    defaultConfig {
        applicationId "com.eventbus.app"
        minSdkVersion 14
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.1'

    compile 'org.greenrobot:eventbus:3.0.0'
}
2、新建叁个音信事件类Message伊夫nt
public class MessageEvent {private String message;public MessageEvent(String message) { this.message = message;}public String getMessage() { return message;}} 

其一类一点也不细略,布局时传进去三个字符串,然后能够由此getMessage(卡塔尔国获抽出来。

在要选拔音讯的分界面注册事件(别忘记在onDestory
EventBus.getDefault().register(MainActivity.this);

何以采纳

  • 注册事件

    EventBus.getDefault().register( this );

  • 撤销注册

    EventBus.getDefault().unregister( this );

  • 发送数据

    EventBus.getDefault(State of Qatar.post( "作者发射了"卡塔尔(قطر‎;

由此可以预知小例子:使用伊夫ntBus传递简单字符串

package com.eventbus.app;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册
        EventBus.getDefault().register( this );


        findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EventBus.getDefault().post( "我发射了");
            }
        });
    }

    /**
     *  自定义一个方法 hello() ,用来接收事件。
     *  方法名字可以随便写
     * @return
     */

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void hello ( String event){
        /* Do something */
        Toast.makeText( this , event , Toast.LENGTH_SHORT).show();
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();

        //取消注册 , 防止Activity内存泄漏
        EventBus.getDefault().unregister( this );
    }
}

效果图
ca88编程 1

1.概述
登记粘性事件
EventBus.getDefault().register(MainActivity.this);

黏性事件

而外上边讲的平日事件外,EventBus还帮衬发送黏性事件。何为黏性事件呢?简单讲,便是在发送事件之后再订阅该事件也能接受该事件,跟黏性广播肖似。具体用法如下:

  • 注册

    EventBus.getDefault().register( this );

  • 事件选择

    @Subscribe(threadMode = ThreadMode.MAIN , sticky = true )
    public void onMessageEventMainThread(String event) {
    Log.e( "event MainThread", "消息: " event " thread: " > Thread.currentThread().getName());
    }

  • 撤除注册

    EventBus.getDefault().unregister( this ) ;

  • 发送事件

    EventBus.getDefault(卡塔尔国.postSticky( "笔者发射了"卡塔尔;

小例子:在MainActivity发送事件,在Activity2里登记何况吸纳事件

MainActivity源码

package com.eventbus.app;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import org.greenrobot.eventbus.EventBus;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d( "event 发射数据线程 : " , Thread.currentThread().getName() ) ;
                EventBus.getDefault().postSticky( "我发射了");

                startActivity( new Intent( MainActivity.this , Activity2.class ));
            }
        });
    }
}

Activity2源码

package com.eventbus.app;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class Activity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_2);
        //注册
        EventBus.getDefault().register( this );
    }

    @Subscribe(threadMode = ThreadMode.MAIN  , sticky =  true )
    public void onMessageEventMainThread(String event) {
        Log.e( "event MainThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册 , 防止Activity内存泄漏
        EventBus.getDefault().unregister( this ) ;
    }
}

那就是粘性事件,能够摄取订阅早先发送的音信。不过它不能不收到最新的壹次信息,举个例子说在未订阅此前早就发送了多条黏性音讯了,然后再订阅只好收取这两天的一条新闻。

2.实战
  • 1.主导框架搭建
  • 2.新建多个类First伊芙nt
  • 3.在要接过消息的页面注册伊芙ntBus
  • 4.发送音讯
  • 5.选取音信
撤消注册( 相仿于动态播放的消释注册)
EventBus.getDefault().post(new MessageEvent; 

总体的流程正是这么,注意:事件管理函数的访谈权限必得为public,不然会报非常。

上面我将示例代码描述一下:

线程模型

在收受事件消息的措施中,可以因而注解的艺术设置线程模型,伊夫ntBus内置了4中线程模型,分别是ThreadMode.POSTINGThreadMode.MAINThreadMode.BACKGROUNDThreadMode.ASYNC

比如:

 @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEventPostThread(String event) {
        Log.e( "event PostThread", "消息: "   event   "  thread: "   Thread.currentThread().getName()  );
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEventMainThread(String event) {
        Log.e( "event MainThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageEventBackgroundThread(String event) {
        Log.e( "event BackgroundThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageEventAsync(String event) {
        Log.e( "event Async",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }
  • PostThread:如若应用事件管理函数钦命了线程模型为PostThread,那么该事件在哪个线程发布出去的,事件管理函数就能够在此个线程中运维,也正是说发表事件和选用事件在同三个线程。在线程模型为PostThread的事件处理函数中尽量防止实践耗费时间操作,因为它会阻塞事件的传递,甚至有相当的大大概会唤起AN奥迪Q7。

  • MainThread:如若使用事件管理函数钦定了线程模型为MainThread,那么无论是事件是在哪个线程中发布出来的,该事件管理函数都会在UI线程中执行。该方式能够用来更新UI,可是不可能管理耗费时间操作。

  • BackgroundThread:如若运用事件管理函数钦点了线程模型为BackgroundThread,那么只要事件是在UI线程中发表出去的,那么该事件管理函数就能在新的线程中运作,要是事件本来就是子线程中发表出来的,那么该事件管理函数直接在发布事件的线程中施行。在那件事件管理函数中明确命令幸免开展UI更新操作。

  • Async:如若利用事件管理函数钦命了线程模型为Async,那么无论是事件在哪个线程发表,该事件管理函数都会在新建的子线程中进行。相像,那件事件管理函数中防止开展UI更新操作。

小例子1: 在子线程发送数据

package com.eventbus.app;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册
        EventBus.getDefault().register( this );

        findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d( "event 发射数据线程 : " , Thread.currentThread().getName() ) ;
                        EventBus.getDefault().post( "我发射了");
                    }
                }).start() ;
            }
        });
    }


    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEventPostThread(String event) {
        Log.e( "event PostThread", "消息: "   event   "  thread: "   Thread.currentThread().getName()  );
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEventMainThread(String event) {
        Log.e( "event MainThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageEventBackgroundThread(String event) {
        Log.e( "event BackgroundThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageEventAsync(String event) {
        Log.e( "event Async",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();

        //取消注册 , 防止Activity内存泄漏
        EventBus.getDefault().unregister( this );
    }
}

运作结果:

D/event 发射数据线程 :: Thread-109
E/event BackgroundThread: 音信: 小编发射了 thread: Thread-109
E/event PostThread: 消息: 作者发射了 thread: Thread-109
E/event Async: 新闻: 作者发射了 thread: pool-1-thread-2
E/event MainThread: 消息: 作者发射了 thread: main

小例子2: 在主线程发送数据

package com.eventbus.app;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册
        EventBus.getDefault().register( this );

        findViewById( R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d( "event 发射数据线程 : " , Thread.currentThread().getName() ) ;
                EventBus.getDefault().post( "我发射了");
            }
        });
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEventPostThread(String event) {
        Log.e( "event PostThread", "消息: "   event   "  thread: "   Thread.currentThread().getName()  );
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEventMainThread(String event) {
        Log.e( "event MainThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageEventBackgroundThread(String event) {
        Log.e( "event BackgroundThread",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageEventAsync(String event) {
        Log.e( "event Async",  "消息: "   event   "  thread: "   Thread.currentThread().getName());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();

        //取消注册 , 防止Activity内存泄漏
        EventBus.getDefault().unregister( this );
    }
}

运作结果:

D/event 发射数据线程 :: main
E/event MainThread: 新闻: 笔者发射了 thread: main
E/event PostThread: 新闻: 小编发射了 thread: main
E/event Async: 音讯: 我发射了 thread: pool-1-thread-3
E/event BackgroundThread: 音信: 小编发射了 thread: pool-1-thread-4

EventBus使用详整——伊芙ntBus拓宽内容

新建一个SecondActivity(second.xml)
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:andro android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25sp" android:text="This is SecondaAtivity's message"/> <Button android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Message"/></LinearLayout>

参谋资料

【EventBus 3.0的用法安详严整】
【伊夫ntBus使用详细明白】
【TencentBugly干货】老手教您“飙”EventBus3】

一.概述

当叁个Android应用效用更加多的时候,保障应用的一一部分之间非常快的通讯将变得更为劳顿。所感觉了消除这几个难点,伊夫ntBus应时而生!伊芙ntBus是一款针对Android优化的揭露/订阅事件总线。重要意义是顶替Intent,Handler,布罗兹Cast在Fragment,Activity,Service,线程之间传递音讯.优点是开拓小,代码更温婉,它简化了组件之间的通讯,使大家的应用程序特别简明、通讯特别便捷。我们来看伊夫ntBus的信息传递图:

ca88编程 2伊夫ntBus的新闻传递图

出殡音信
EventBus.getDefault().post(new MessageEvent; 

前言

  • EventBus框架

    EventBus是三个通用的叫法,比方谷歌出品的Guava,Guava是一个大幅度的库,伊芙ntBus只是它附带的一个小功用,因而实际项目中运用并超级少。用的最多的是greenrobot/EventBus,这一个库的长处是接口简洁,集成方便,不过约束了艺术名,不协助评释。另四个库square/otto修正自 Guava ,用的人也不菲。所以明天大家斟酌的对象是greenrobot的EventBus.

  • EventBus 简介

    1、伊芙ntBus3.0.0 是最新的本子。
    2、伊芙ntBus 是Android 公布/订阅事件总线,可简化 Activities, Fragments, Threads, Services 等零器件间的音讯传递。
    3、可取代 Intent, Handler, 布罗兹Cast ,接口等古板方案,更加快,代码越来越小,50K 左右的 jar 包,代码更华贵,通透到底解耦。

github地址:

EventBus原理图

ca88编程 3

5、接受音讯

收纳音信时,大家运用EventBus中最常用的ThreadMode.MAIN线程格局来接过新闻,具体怎么用那一个,我们下篇再讲,这里先给我们一个起来认知,要先能把伊夫ntBus用起来先。 在MainActivity中声称八个集体的加注释的章程,参数正是我们友好定义的类:

在接纳Event实例后,大家将个中辅导的新闻抽取,一方面Toast出去,一方面传到TextView中;

@Subscribe(threadMode = ThreadMode.MAIN)public void onEventMainThread(MessageEvent event) { String msg = "onEventMainThread收到了消息:"   event.getMessage(); Log.d("EventBus", msg); tv.setText; Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } 

完整的MainActiviy代码如下:

public class MainActivity extends AppCompatActivity {Button mBtn;TextView mTv;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register;//注册EventBus mBtn =  findViewById(R.id.main_btn); mTv =  findViewById(R.id.main_tv); mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick { Intent intent = new Intent(); intent.setClass(getApplicationContext(),SecondActivity.class); startActivity; } });}@Subscribe(threadMode = ThreadMode.MAIN)public void onEventMainThread(MessageEvent event) { String msg = "onEventMainThread收到了消息:"   event.getMessage(); Log.d("EventBus", msg); mTv.setText; Toast.makeText(this, msg, Toast.LENGTH_LONG).show();}@Overrideprotected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister;}}
在急需抽取信息的页面注册事件(相符于动态注册广播)
EventBus.getDefault().register;

本文由ca88发布,转载请注明来源

关键词: ca88网址 详解 Andro EventBus 手机开发