您的位置:首页 > 其它

Androd中浅析Otto框架(有点像广播,万能数据传递,并且触发)

2016-04-24 07:59 471 查看
OTTO是Square推出的基于Guava项目的Android支持库,otto是一个事件总线,用于应用程序的不同组件之间进行有效的通信。OTTO是基于Observer的设计模式。它有发布者,订阅者这两个主要对象。OTTO的最佳实践就是通过反射牺牲了微小的性能,同时极大的降低了程序的耦合度。

Otto 官网: http://square.github.io/otto/


Why和应用场景


1. Why

Otto框架的主要功能是帮助我们来降低多个组件通信之间的耦合度的(解耦)。


2. 应用场景

比如:由界面 A 跳转到界面 B ,然后点击 B 中的 button, 现在要更新 界面 A 的视图。再比如:界面有一个 界面 A,A 里面的有个 Fragment, 点击 Fragment 中的一个 button,跳转到界面 B, 点击界面 B的 button 要更新界面 A 的 Fragment 的视图,等等。

我们可以看出上面举例的两种场景,以前可以用startActivityForResult 和 interface 的方式实现的话,会比较麻烦,并且产生了很多的状态判断和逻辑判断,并且可能产生很多不必要的 bug, 代码量也比较大和繁琐,使用 otto 就可以能容易的避免这些问题。


基本用法


引入Otto

dependencies {
compile 'com.squareup:otto:1.3.8'
}


定义事件:

public class MessageEvent { /* Additional fields if needed */ }


订阅和取消订阅

bus.register(this);

bus.unregister(this);


发布:

bus.post(new MessageEvent());


注解

@Subscribe:这个在调用了register后有效,表示订阅了一个事件,并且方法的用 public 修饰的.方法名可以随意取,重点是参数,它是根据你的参数进行判断

@Produce注解告诉Bus该函数是一个事件产生者,产生的事件类型为该函数的返回值。


最后,proguard 需要做一些额外处理,防止混淆:

-keepattributes *Annotation*
-keepclassmembers class ** {
@com.squareup.otto.Subscribe public *;
@com.squareup.otto.Produce public *;
}


实际例子

MainActivity中

<span style="font-size:18px;">package android.test.com;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.squareup.otto.Bus;
import com.squareup.otto.Produce;

public class MainActivity extends Activity {
private Button btn;

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

/**
* 绑定fragment
*/
private void myBindFragment() {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, TestFragment.getInstance());
transaction.commit();

}

/**
* 初始化控件
*/
private void initView() {
btn = (Button) findViewById(R.id.btn);

}

/**
* 点击事件
*/
private void myOnclick() {
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//              发送订阅
AppBus.getInstance().post(new BusEventData("wo shi zhh"));
}
});

}

//    /**
//     * 订阅
//     */
//    @Override
//    protected void onResume() {
//        super.onResume();
//        AppBus.getInstance().register(this);
//    }
//
//    /**
//     * 取消订阅
//     */
//    @Override
//    protected void onPause() {
//        super.onPause();
//        AppBus.getInstance().unregister(this);
//    }
// 系统自动调用
//  @Produce
//  public BusEventData produceFragmentData() {
//      return new BusEventData("This data com from activity");
//  }
}
</span>


TestFragment中

<span style="font-size:18px;"><pre style="font-family: 宋体; font-size: 12pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java">package android.test.com;

import android.app.Fragment;
import android.os.Bundle;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

import com.squareup.otto.Subscribe;

/**
* Created by Administrator on 2016/4/24.
*/
public class TestFragment extends Fragment {
private EditText mContentET;

public static TestFragment getInstance() {
TestFragment fragment = new TestFragment();
return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
mContentET = (EditText) view.findViewById(R.id.content);
return view;
}

@Override
public void onStart() {
super.onStart();
//注册到bus事件总线中
AppBus.getInstance().register(this);
}

@Override
public void onStop() {
super.onStop();
//      取消注册
AppBus.getInstance().unregister(this);
}

/**
* 定义订阅者,Activity中发布的消息,在此处会接收到,在此之前需要先在程序中register,看
* 上面的onStart和onStop函数
* 这个注解一定要有,表示订阅了BusEventData,
* 并且方法的用 public 修饰的.方法名可以随意取,
* 重点是参数,它是根据你的参数进行判断来自于哪个发送的事件
*/
@Subscribe
public void MessageEvent(BusEventData data) {
mContentET.setText(data.getContent());
}

}</span>





AppBus中

<span style="font-size:18px;">public class AppBus extends Bus {
private static AppBus bus;

public static AppBus getInstance() {
if (bus == null) {
bus = new AppBus();
}
return bus;
}
}</span>


实体类BusEventData

<span style="font-size:18px;">public class BusEventData {
public String content;

public BusEventData(String content) {
this.content = content;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}
}</span>
布局

activity_main.xml

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="btn"
/>

</LinearLayout>
</span>


fragment_test.xml

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<EditText
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout></span>

源码下载:

http://download.csdn.net/detail/zhaihaohao1/9500648

otto-1.3.8.jar下载

http://download.csdn.net/detail/zhaihaohao1/9500768
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: