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

本文介绍了一种用于降低Android组件间耦合度的框架——Otto。通过实例详细讲解了Otto事件总线的使用方法及注意事项,包括创建单例Bus类、声明发布者和订阅者类等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值