使用Handler

时间:2016-06-20 14:47:48

标签: java android android-asynctask observer-pattern android-handler

我最近在处理一个我不确定如何回答的问题。 我为一些我想要执行的AsyncTask写了一个代码示例。我在网上的某个地方读到有人已经将AsyncTask和Handler作为内部类实现了,我想稍微扩展一点并减少耦合,所以我为那些做了分离的类,所以我可以在多个Activity中重用它们。 因为我必须在每个Activity上做一些不同的UI事情,所以我决定让这些活动实现一个接口,这样我就可以用相同的方法对每个事件做出反应。

我不明白为什么我需要处理事件发生的消息传递的处理程序对象?我不能只使用听众观察者模式?然后我问自己并且无法理解网络上的答案的问题是我的监听器观察者实现和我们从Android获得的处理程序对象之间的区别。

这是我的代码示例:

活动1:

public class SomeActivity extends Activity implements MyListener{

    MyAsyncTask myTask;
    MyHandler handler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = new MyHandler();
        myTask = new MyAsyncTask(handler);
        // initilize the activity views etc...
    }

    @Override
    public void do1(){
        // DO UI THINGS FOR ACTIVITY 1 IN A CALLBACK TO DO1 EVENT
    }

    @Override
    public void do2(){
        // DO UI THINGS FOR ACTIVITY 1 IN A CALLBACK TO DO2 EVENT
    }
}

活动2:

public class OtherActivity extends Activity implements MyListener{

    MyAsyncTask myTask;
    MyHandler handler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = new MyHandler();
        myTask = new MyAsyncTask(handler);
        // initilize the activity views etc...
    }

    @Override
    public void do1(){
        // DO UI THINGS FOR ACTIVITY 2 IN A CALLBACK TO DO1 EVENT
    }

    @Override
    public void do2(){
        // DO UI THINGS FOR ACTIVITY 2 IN A CALLBACK TO DO2 EVENT
    }
}

监听器界面:

public interface MyListener{
    void do1();
    void do2();
}

AsyncTask实现:

public class MyAsyncTask extends AsyncTask<Void,Void,String>{
    private MyModel m;

    public MyAsyncTask(Handler h){
        m = new MyModel();
        m.setHandler(h);
    }

    protected String doInBackground(Void... params) {
        // do something in background with MyModel m
        return null;            
    }
}

处理程序实施:

public class MyHandler extends Handler {

    Vector<MyListener> listeners = new Vector<>();

    @Override
    public void handleMessage(Message msg) {
        switch(msg.what){
            case 1:
                // do something for case 1
                fireMethod1();
                break;
            case 2:
                // do something for case 2
                fireMethod2();
                break;
        } 
    }

    public void registerListener(MyListener l){
        listeners.add(l);
    }

    public void unregisterListener(MyListener l){
        listeners.remove(l);
    }

    private void fireMethod1(){
        for(MyListener l : listeners){
            l.do1();
        }
    }

    private void fireMethod2(){
        for(MyListener l : listeners){
            l.do2();
        }
    }

}

我创建的一些演示模型:

public class MyModel{

    private Handel h;

    public MyModel(){
        // at some point send message 1 or message 2 ...
    }

    public void setHandler(Handler h){
        this.h = h;
    }

    private void sendMessage1(){
        h.obtainMessage(1, null);
    }

    private void sendMessage2(){
        h.obtainMessage(2, null);
    }
}

如果难以阅读代码让我知道,如果您不想阅读代码,请帮助我回答 Handler与使用观察者模式监听事件有什么区别?对于同样的问题他们是不同的解决方案吗?谢谢!

2 个答案:

答案 0 :(得分:1)

  

Handler和用观察者模式监听事件有什么区别?

不同之处在于,当您使用侦听器时,可以在同一个线程上同步调用方法。当您使用Handler时,您同步向MessageQueue添加消息,但只有在队列中已有的消息之后才会处理它。

例如,如果您使用的是UI处理程序,并且您已在活动上调用finish(),然后添加了您的消息,则会在onStop()onDestroy()之后插入该消息。你无法通过听众实现这一目标。

处理程序的优点是您只需向队列添加消息,而不关心线程。您可以从后台线程轻松地向UI处理程序添加消息。如果您使用后台线程中的侦听器,它将在后台线程上同步调用。

  

对于同样的问题他们是不同的解决方案吗?

不,他们不是。我认为处理程序可以帮助你解耦对Android至关重要的Android组件。如果你使用监听器,你将只依赖强引用,在某些情况下是不可能的,因为你可能会泄漏内存。

答案 1 :(得分:0)

Handler是UI线程组件。如果要触摸某些UI,则使用简单侦听器可能会导致CalledFromWrongThreadException

AsyncTask虽然有onPreExecuteonPostExecuteonProgressUpdate,它们只是在UI线程上运行的方法。 doInBackground在单独的线程上运行