发现了一种能够减小不同组件间耦合度的框架:Otto。非常好用。官方Demo做得很好,左边地图右边坐标的。我自己也写了个Demo,文中会提供Demo供大家学习。
Android Otto
如果你在Android程序开发的过程中想要不同的组件之间进行有效的通信可以使用Android Otto事件总线。通过Otto事件总线可以降低程序之间的耦合性。下面通过代码来详述Android Otto的使用步骤和注意点:
步骤
1.写一个单例的Bus类。
import com.squareup.otto.Bus;
public class AppBusContainer extends Bus {
private static AppBusContainer bus;
public static AppBusContainer getInstance() {
if (bus == null) {
bus = new AppBusContainer();
}
return bus;
}
public static void releaseBus() {
if (bus != null) {
bus = null;
}
}
}
2.声明发布者类,用到的注解如下代码:
public class MyAsyncTaskActivity extends Activity {
// static {
// System.loadLibrary("hello");
// System.loadLibrary("helloword");
// }
//
// public static native String sayHelloWord();
Button button;
ProgressBar progressBar;
TextView textView;
View view;
Bus bus;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button03);
progressBar = (ProgressBar) findViewById(R.id.progressBar02);
textView = (TextView) findViewById(R.id.textView01);
LayoutInflater factory = LayoutInflater.from(getApplicationContext());
view = factory.inflate(R.layout.dialog, null);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(
textView, progressBar);
asyncTask.execute(1000);
AppBusContainer.getInstance().post(new BusDataEvent("somebody alive"));
AppBusContainer.getInstance().post("somebody alive");
}
});
}
@Subscribe
public void showText(IntegersData num) {
AssetManager assetManager = getAssets();
InputStream is = null;
try {
is = assetManager.open("drawable/dialogicon.jpg");
} catch (IOException e) {
is = null;
e.printStackTrace();
}
// Bitmap bitmap = BitmapFactory.decodeStream(is);
if (is != null) {
//此处Builder(getApplicationContext)会出错致使崩溃
new AlertDialog.Builder(this)
.setTitle(getString(R.string.back_text))
.setMessage(getString(R.string.back_text))
.setIcon(new BitmapDrawable(getResources(), is))
.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("click ok", "click ok");
}
}).setNegativeButton("Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("click cancel", "click cancel");
}
}).show();
}
System.out.println(num.getNum());
}
@Override
protected void onResume() {
AppBusContainer.getInstance().register(this);
super.onResume();
}
@Override
protected void onPause() {
AppBusContainer.getInstance().unregister(this);
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
AppBusContainer.getInstance().releaseBus();
}
}
3.声明订阅者类
public class HellowordFragment extends Fragment {
LayoutInflater inflater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout, container);
}
@Override
public void onResume() {
super.onResume();
AppBusContainer.getInstance().register(this);
}
@Override
public void onStop() {
super.onStop();
AppBusContainer.releaseBus();
}
@Override
public void onPause() {
super.onPause();
AppBusContainer.getInstance().unregister(this);
}
/**
* 定义订阅者,Activity中发布的消息,在此处会接收到,在此之前需要先在程序中register,看 上面的onStart和onStop函数
*/
@Subscribe
public void setContents(BusDataEvent data) {
System.out.println("[111]data.getContent() =" + data.getContent());
}
@Subscribe
public void onBusData(String sss) {
AppBusContainer.getInstance().post(new IntegersData(1));
System.out.println("====" + sss);
}
}
注意点:
1.Bus.post方法不能传递基础数据类型的“事件”,并且其参数产生的方法可以不用@Produce进行注册,不过为了阅读性和其注解特有的作用,还是建议独立写一个带@Produce的方法,返回非空的“事件”,并在post方法中参数改为该方法。如:
@Produce
public BusDataEvent produceBusDataEvent() {
return new BusDataEvent(params);
}
...
AppBusContainer.getInstance().post(produceBusDataEvent());
2.Bus必须在发布者和订阅者组件中都进行注册且注销,否则事件不能够传递和被订阅者接收。
3.发布者可以成为订阅者,订阅者也可以成为发布者。即事件的传递是双向的,不过为了程序的结构,最好明确区分订阅者类和发布者类(单向)。
4.注解(有过J2EE经验的应该懂吧)订阅者的时候,其“方法名”可以随便写(只不过为了容易阅读我们会以“on+[事件名-Event]”的形式命名方法名),其参数同类型的订阅者会对对应的发布者进行相应。
5.订阅者方法中可以处理UI,相当于此方法是运行于主线程。
实际效果图
如上所示,事件总线的使用效果,以及事件的双向传递。
如上所示,在此例子中AsyncTask的执行,每点一次按钮生成一个新的AsyncTask。总体上看,对UI的处理是同步执行的,直到达到默认最大128个线程数的极限(还有缓冲队列能放10个线程)或者所有线程都执行完毕,否则线程处理UI是同步的,否则效果会是UI(ProgressBar和TextView2)状态的混乱。AsyncTask为UI线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。以上就是我要分享的东西了,至于Otto事件总线的学习,网上有很多,我这里只是讲了一些细节而已。
以下是我的Demo地址:
Otto_AsyncTask_Fragment_Demo
欢迎大家指正批评。
PS:其实要会用且了解安卓里的这些基础的东西不难,终究还是要对理论知识和细节掌握。