Android Otto事件总线结合Fragment与AsyncTask的分享

来源:互联网 发布:贵州旅游不好知乎 编辑:程序博客网 时间:2024/05/28 18:45

  发现了一种能够减小不同组件间耦合度的框架: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:其实要会用且了解安卓里的这些基础的东西不难,终究还是要对理论知识和细节掌握。

0 0
原创粉丝点击