Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带处理程序的侦听器-观察者设计模式_Java_Android_Android Asynctask_Observer Pattern_Android Handler - Fatal编程技术网

Java 带处理程序的侦听器-观察者设计模式

Java 带处理程序的侦听器-观察者设计模式,java,android,android-asynctask,observer-pattern,android-handler,Java,Android,Android Asynctask,Observer Pattern,Android Handler,我最近在处理一个我不知道如何回答的问题。 我为我想要执行的某个异步任务编写了一个代码示例。我在网上的某个地方读到,有人将AsyncTask和处理程序实现为内部类,我想稍微扩展一下,减少耦合,所以我为它们创建了单独的类,这样我就可以在多个活动中重用它们。 因为我必须对每个活动执行一些不同的UI操作,所以我决定让这些活动实现一个接口,这样我就可以用相同的方法对每个事件做出反应 我不明白的是,为什么我需要处理事件发生消息的handler对象?我不能使用listeners-observer模式吗?然后我

我最近在处理一个我不知道如何回答的问题。 我为我想要执行的某个异步任务编写了一个代码示例。我在网上的某个地方读到,有人将AsyncTask和处理程序实现为内部类,我想稍微扩展一下,减少耦合,所以我为它们创建了单独的类,这样我就可以在多个活动中重用它们。 因为我必须对每个活动执行一些不同的UI操作,所以我决定让这些活动实现一个接口,这样我就可以用相同的方法对每个事件做出反应

我不明白的是,为什么我需要处理事件发生消息的handler对象?我不能使用listeners-observer模式吗?然后我问了自己一个问题,但我无法理解网络上的答案,那就是我的listener-observer实现和我们从Android获得的handler对象之间有什么区别

下面是我的代码示例:

活动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
    }
}
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
    }
}
活动2:

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
    }
}
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();
}
异步任务执行:

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();
        }
    }

}

如果阅读代码太难,请告诉我,如果您不想阅读代码,请帮助我回答处理程序与使用观察者模式收听事件之间的区别是什么?对于同一个问题,它们的解决方案有很大不同吗?谢谢

处理程序是UI线程化组件。如果您想触摸某个UI,使用简单侦听器可能会导致
调用FromErrorThreadException

AsyncTask虽然有
onPreExecute
onPostExecute
onProgressUpdate
,但它们只是在UI线程上运行的方法
doInBackground
在单独的线程上运行

处理程序和使用观察者模式侦听事件之间有什么区别

不同之处在于,当您使用侦听器时,您会在同一线程上同步调用一个方法。当您使用
处理程序时
会将消息同步添加到
消息队列
,但它仅在队列中已存在的消息之后处理

例如,如果您正在使用UI处理程序,并且您已经在活动上调用了
finish()
,然后添加了消息,则消息将插入到
onStop()
onDestroy()
之后。你不能用一个聆听者来做到这一点

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

对于同一个问题,它们的解决方案有很大不同吗


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

处理程序
不是UI线程化组件。如果创建
处理程序
对象,它将使用当前所在的线程,也就是说,如果在后台线程上创建
处理程序
,它将使用后台线程。更多信息:使用相同的处理程序扩展类,如何对不同的活动执行任何类型的操作?我用可观察的模式做这件事的方法正确吗?我只是想阻止自己创建一个“getHandler”重复方法,在我想要处理来自处理程序的消息的每个活动中实例化一个新的处理程序?再次感谢您,您真的需要跨活动使用相同的
处理程序
对象吗?通常在每个活动中创建一个UI处理程序是可以的,它并不繁重。如果您想要相同的对象,那么可以在应用程序类中使用静态变量,也可以使用基本活动。这是安全的,因为处理程序将与UI线程关联。关于你的下一个问题,我不知道你是否做得对,因为它总是取决于用例。后台操作需要多长时间?您需要更新UI吗?如果系统决定终止你的应用程序,预期的行为是什么?太好了,我想我抓到你了。后台操作由用户处理,它类似于音乐播放器(代码示例中是MyModel),用户选择播放还是停止,播放时我需要接收某些消息。它死了,在顶部被摧毁。每当我收到消息时,我都需要用一些画布图形更新UI。也许在每个活动中创建处理程序并不重,我会考虑这个方法。对于音乐播放器等应用程序,通常使用
服务
组件。它允许您独立于UI运行操作,并提高应用程序进程优先级,以便在设备内存不足时有更多机会生存。考虑这个解决方案,也许它会更好地适应你的使用情况。谢谢。哦,好的,我会试着把它作为一个服务来运行,实际上它是一个节拍器播放器(所以我使用了AudioTrack),所以当我把它作为一个服务来运行时,我仍然可以使用处理程序作为服务和UI之间的消息传递平台,并利用消息队列?因为它是一个节拍器,所以我真的需要注意同步性,而我从处理程序得到的队列是一件很好的事情。