【问题标题】:BusProvider Not Returning to @SubscribeBusProvider 未返回 @Subscribe
【发布时间】:2017-01-01 21:20:14
【问题描述】:

我在 Android 上使用 BusProvider 来处理执行 AsynTask 后返回到主线程的回传。当 Async 任务完成并成功时,它会注册 Post 并返回到 MAIN 线程以显示警报对话框。但是,当它失败时,我希望它返回到主线程中的相同方法并显示一条关于失败原因的消息。在这种情况下,它正在注册,所以它可以像“此电子邮件已被使用”一样简单。

这似乎对我不起作用,它永远不会回到主线程。

在我使用 BusProvider 的异步任务中,我将在失败时发回此消息:

 @Override
        public void failure(RetrofitError error) {
            BusProvider.getInstance().post(new SignupTask.ErrorEvent(new String(((TypedByteArray) error.getResponse().getBody()).getBytes())));
        }

然后将其传递到ErrorEvent类中:

public class ErrorEvent {

    public String message;

    public ErrorEvent(String message) {
        this.message = ResponseParser(message);
    }

    public String ResponseParser(String response){
        //Handle JSON parsing here of response, need message + the array stack to display to the user what is exactly wrong
        return response;
    }

}

还有一些工作要做,但在我解析信息之前,我想暂时将响应传回。

响应不为空,我在调试时检查了这一点。一旦它返回到 BusProvider.getInstance().post(...) 它就永远不会返回到主线程并点击我的@Subscribe

@订阅:

@Subscribe
public void onSignUpSuccess(SignupResponse event) {
    loading.dismiss();

    if(!BuildConfig.DEBUG_MODE) {
        Log.i(TAG, "!BuildConfig.DEBUG_MODE : " + AnswersAnalytics.SIGN_UP_PATIENT);
        Answers.getInstance().logCustom(new CustomEvent(AnswersAnalytics.SIGN_UP));
    }
    AlertDialog alertDialog = new AlertDialog.Builder(SignupActivity.this).create();
    alertDialog.setTitle("Thank you");
    alertDialog.setMessage(event.getMsg());
    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    killSignup();
                }
            });
    alertDialog.show();
}

我想使用同样的@Subscribe 来处理错误并显示它。

非常感谢任何帮助!

【问题讨论】:

    标签: java android multithreading android-asynctask otto


    【解决方案1】:

    您不能将事件从另一个线程发布到 UI 线程。您可以为此使用Handler

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            synchronized (this) {
                BusProvider.get().post(msg.obj);
            }
        }
    };
    
    private void post(Object message) {
        Message msg = mHandler.obtainMessage(0);
        msg.obj = message;
        mHandler.sendMessage(msg);
    }
    
    @Override
    public void failure(RetrofitError error) {
        this.post(new SignupTask.ErrorEvent(new String(((TypedByteArray) error.getResponse().getBody()).getBytes())));
    }
    

    【讨论】:

    • 我已经尝试过了,但我仍然没有进入父视图来删除 spinner.dismiss()。它在 AsyncTask 的父活动中的主线程上
    • 您是否尝试调试Bus.post 方法?它只是通过反射调用订阅的方法,没有魔法。只需检查它如何在您的项目中已经工作的方法中通过 otto 类,并将它们与您当前的非工作方法进行比较。既不是您的班级没有注册(或从另一辆巴士注册),也不是您从另一个线程调用它。您还可以在堆叠post 处理程序期间检查内存使用情况,如果您的内存上升,则表示有问题,如果它在同一级别或被GC 清除,您只是搞砸了注册。
    • 当我从服务器成功返回时,当前的订阅方法工作正常,只是在失败时不起作用。它甚至没有到达我在订阅方法中放置的断点
    • 你可以尝试一步步走向成功的方法。我的意思是,如果一种方法有效,而另一种方法不仅能找到它们之间的区别。首先尝试在failure 中发布SignupTask.Success 而不是SignupTask.ErrorEvent,检查是否调用了您活动的订阅成功事件。然后尝试通过postsuccess 调用onSignUpSuccess
    • 我对您要求我尝试的内容感到困惑,当我成功发布帖子时会调用 onSignUpSuccess。我无法将 SignupTask.ErrorEvent 更改为 Success,因为它正在处理来自服务器的错误...将其更改为成功会做什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2022-01-05
    • 2020-12-21
    • 2018-05-24
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多