Android事件总线otto学习笔记

      otto是Square推出的库,主要用于Android不同组件之间的通信,类如可以通过一个Activity修改另外一个Activity里面的数据。

      otto类似于广播,但广播是进程级别的(可能有错,我自己的理解)。otto是线程级别的,也需这里的概念有问题,但主要我们要会使用它,下面就让我来介绍一下otto的使用步骤吧


第一步: 加载jar包

      compile 'com.squareup:otto:1.3.8'

第二步: 创建Bus类,应为Bus最好是单列,而且在主线程与工作线程间post会出现一定问题,所以我重写了一下post方法

public class MainThreadBus extends Bus {
    private static MainThreadBus bus = new MainThreadBus();

    public static MainThreadBus getInstance() {
        return bus;
    }

    private MainThreadBus() {
    }                                                                                                                                                         // 上面的单列方法如果不懂可以百度一下单列模式,这里不做过多介绍。                                                                                                                                                                                                                                                   
    private final Handler mHandler = new Handler(Looper.getMainLooper());                                                                                     //其实这里相当于重写post方法,但在runnable线程中不能再通过super调用Bus里面的post方法,所以重新命名
public void myPost(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            Log.i("otto","--主线程");
            bus.post(event);
        } else {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Log.i("otto","--非主线程");
                    bus.post(event);
                }
            });
        }
    }
}
第三步: 创建实体类,otto事件发布与接收是通过Object类型来处理的,类如你post(A对象),那边接收的类型必须是A对象,否则就不能接收到信息

public class UserEvent {

    public int id;
    public String name;
    public String desc;

    public UserEvent(int id, String name, String desc) {
        this.id = id;
        this.name = name;
        this.desc = desc;
    }
第四步:在要接收信息的Activity中注册Bus

public class OttoActivity extends AppCompatActivity {
    private TextView showTv;

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

        showTv = (TextView)findViewById(R.id.show_tv);
        showTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(OttoActivity.this,Otto2Activity.class));
            }
        });
    }

    @Subscribe
    public void onMyEvent(UserEvent user){    //如果发送的是UserEvent对象则会接收到信息,否则不会
        if(user == null || isFinishing()){
            return;
        }
        Log.i("otto","--id:"+user.id + "--name:" + user.name);
    }

    @Subscribe                //这个注释otto会自动去寻找,必须加,下面的方法名可以随便取,无实际意义
    public void onMyEvent(String str){        //如果发送的是String类型则会接收到信息,否则不会
        if(str == null || isFinishing()){
            return;
        }
        Log.i("otto","--String:"+ str);
    }

    @Override
    protected void onStart() {               // 在onStart里面注册Bus事件
        super.onStart();
        Log.i("otto","--onStart");
        MainThreadBus.getInstance().register(this);
    }

    @Override
    protected void onStop() {   // 一般情况下跳转Activity后会执行onStop事件,这样Bus事件就被注销掉了,而在其它                                                                            // 生命周期里面也不能很好的达到注销效果,因此这里必须做第五步处理,必须
        super.onStop();
        Log.i("otto","--onStop");
        MainThreadBus.getInstance().unregister(this);
    }
}
第五步:把要跳转到的Activity背景换成透明的,也就是要post信息的Activity,这样前一个Activity则不会执行onStop方法。

     首先新建主题

<style name="transparencyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
</style>

      然后Mainifest里面注册Activity的时候加上这个主题

<activity android:name=".activity.otto.Otto2Activity"
    android:theme="@style/transparencyTheme"/>

第六步:发送信息给Activity

public class Otto2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.otto_2_activity);
        Button triggerBt = (Button)findViewById(R.id.trigger_bt);

        triggerBt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {    //注意这里是新起了个线程
                    @Override
                    public void run() {                                                                                                                   
                        //由于post的是UserEvent对象,所以会自动寻找有@Subscribe注释的方法且参数是UserEvent对象的
                        MainThreadBus.getInstance().myPost(new UserEvent(1,"xuebin","好人"));   
                    }
                }).start();
            }
        });

        triggerBt.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
               //由于post的是String类型,所以会自动寻找有@Subscribe注释的方法且参数是String的
                MainThreadBus.getInstance().myPost("你个坏人。。。");
                return true;
            }
        });
    }
}
       下面是单击和长按打印的结果


     这里回看第二步就明白了为什么要自己创建一个myPost方法了。


这里基本应用到了otto来处理不同组件(线程)之间的通信问题了,虽然看起来很基础,但很实用。同时我也会继续加深对otto的研究的。如果上面有说错的地方,麻烦您一定要指出来,避免误导大家,也有利于本人学习,看在我的分享精神上,请多多指教,谢谢您了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值