在onPause之后OnClickListener解雇? [英] OnClickListener fired after onPause?

查看:204
本文介绍了在onPause之后OnClickListener解雇?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我工作的项目使用取景presenter抽象。 这里是所有的主要类的简化版本。

The project that I'm working uses a view-presenter abstraction. Here is a simplified version of all the main classes.

摘要活动(线presenter例如,有景)

The abstract activity (wire Presenter instance, with View)

public abstract class MvpActivity<Presenter extends MvpPresenter>
        extends ActionBarActivity {

  protected Presenter mPresenter;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mPresenter = getPresenterInstance();
  }

  @Override protected void onResume() {
    super.onResume();
    mPresenter.onResume(this);
  }

  @Override protected void onPause() {
    mPresenter.onPause();
    super.onPause();
  }
}

视图界面

public interface MyView {
  void redirect();
}

视图实施

public class MyActivity
        extends MvpActivity<MyPresenter>
        implements MyView {

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_view);

    Button myButton = (Button)findViewById(R.id.my_button);

    myButton.setOnClickListener(v -> mPresenter.onButtonPressed());
  }

  @Override protected MyPresenter getPresenterInstance() {
    return new MyPresenter();
  }

  @Override void redirect(){
    startActivity(new Intent(this, MyOtherActivity.class));
  }

摘要presenter

The abstract presenter

public abstract class MvpPresenter<ViewType> {

  private ViewType mView;

  public void onResume(ViewType view) {
    mView = view;
  }

  public void onPause() {
    mView = null;
  }

  protected ViewType getView() {
    if (mView == null) {
      throw new IllegalStateException("Presenter view is null");
    }
    return mView;
  }
}

而presenter实施

And the presenter implementation

public class MyPresenter extends MvpPresenter<MyView> {

  @Override public void onResume(MyView myView){
    super.onResume(myView);
    Log.("MyPresenter", "Presenter resumed");
  }

  @Override public void onPause(){
    super.onPause()
    Log.("MyPresenter", "Presenter paused");
  }

  public void onButtonPressed(){
    getView().redirect();
  }
}

这个问题上来为。IllegalStateException异常:presenter观点是空触发getView()重定向(); 我的presenter.onButton pressed()方法调用时。

The issue comes up as an "IllegalStateException: Presenter view is null" triggered by getView().redirect(); when called from the MyPresenter.onButtonPressed() method.

这没有任何意义,我,仿佛听者被解雇的观点应始终不为空。该视图只设置为空,如果 MVP presenter.onPause()执行这是只有正在从称为MvpActivity.onPause() 。我不希望收到任何单击事件发生这种情况后,让我丢失在这里吗?

This doesn't make any sense to me, as the view should always be not null if the listener is fired. The view is only set to null if the MvpPresenter.onPause() is executed which is only being called from MvpActivity.onPause(). I wouldn't expect to receive any click events after this happens, so what am I missing here?

可悲的是,我无法通过手动测试的应用程序重现此问题。该报告是由Crashlytics进入。

Sadly, I can not reproduce this issue by manually testing the application. The reports are coming in from Crashlytics.

注:retrolambda正在使用的按钮点击监听器

Note: retrolambda is in use for the button click listener

推荐答案

简短的回答:不这样做

不幸的是,你依赖事件的顺序是不确定的。活动的生命周期事件和窗口事件是两回事,即使它们往往密切相关。你会得到的onPause()当活动被暂停的任何理由。但视图触摸事件不会脱钩,直到查看的窗口失去焦点。

Unfortunately, you're relying on an order of events that is undefined. Activity lifecycle events and Window events are two different things, even though they're often closely related. You'll get onPause() when the activity is paused for any reason. But the View touch events aren't unhooked until the View's window loses focus.

这是很常见的一个活动暂停权当它的窗口失去焦点 - 例如,当屏幕被锁定或当另一个活动启动。但正如你所看到的,你可以暂停没有焦点的变化和重点的变化没有停顿。即使当两个事件同时发生,有时间的窄窗口时的onPause()被调用但窗口输入处理程序仍然有效。

It's very common for an activity to pause right when its window loses focus--for instance, when the screen is locked or when another activity is launched. But as you've seen, you can get pauses without a focus change and focus changes without a pause. Even when the two events occur together, there's a narrow window of time when onPause() has been called but the window input handlers are still active.

对于任何不确定的行为,你看到实际效果将操作系统版本和硬件类型而有所不同。

As with any undefined behavior, the actual results you see will vary by OS version and hardware type.

如果你需要确保你不会在onPause后获得查看邮件,你应该解开你的处理程序中的onPause。

If you need to make sure that you don't receive View messages after onPause, you should unhook your handlers in onPause.

这篇关于在onPause之后OnClickListener解雇?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆