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() { } // 上面的单列方法如果不懂可以百度一下单列模式,这里不做过多介绍。第三步: 创建实体类,otto事件发布与接收是通过Object类型来处理的,类如你post(A对象),那边接收的类型必须是A对象,否则就不能接收到信息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); } }); } } }
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的研究的。如果上面有说错的地方,麻烦您一定要指出来,避免误导大家,也有利于本人学习,看在我的分享精神上,请多多指教,谢谢您了。