草庐IT

android - OnClickListener 在 onPause 之后触发?

coder 2023-11-30 原文

我正在工作的项目使用 View 呈现器抽象。 这是所有主要类的简化版本。

抽象 Activity (连接 Presenter 实例,带 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();
  }
}

View 界面

public interface MyView {
  void redirect();
}

View 实现

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

摘要提交者

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

和演示者实现

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

MyPresenter 调用时,"IllegalStateException: Presenter view is null"getView().redirect(); 触发。 onButtonPressed() 方法。

这对我来说没有任何意义,因为如果监听器被解雇, View 应该始终不为空。如果执行仅从 MvpActivity.onPause() 调用的 MvpPresenter.onPause(),则 View 仅设置为 null。发生这种情况后我不希望收到任何点击事件,那么我在这里错过了什么?

遗憾的是,我无法通过手动测试应用程序来重现此问题。这些报告来自 Crashlytics。

注意:retrolambda 用于按钮点击监听器

2017 年 10 月 7 日更新

解决此问题的一些方法:

- https://developer.android.com/reference/android/view/View.html#cancelPendingInputEvents()

- https://github.com/JakeWharton/butterknife/blob/master/butterknife/src/main/java/butterknife/internal/DebouncingOnClickListener.java

最佳答案

简短回答:不要那样做。

不幸的是,您依赖于未定义的事件顺序。 Activity 生命周期事件和 Window 事件是两个不同的事物,尽管它们通常密切相关。当 Activity 因任何原因暂停时,您将获得 onPause() 。但是在 View 的窗口失去焦点之前, View 触摸事件不会解除。

一个 Activity 在其窗口失去焦点时暂停是很常见的——例如,当屏幕被锁定或另一个 Activity 启动时。但是正如您所见,您可以在没有焦点改变的情况下获得暂停,并且可以在没有暂停的情况下获得焦点改变。即使两个事件同时发生,调用 onPause() 但窗口输入处理程序仍处于 Activity 状态的时间窗口很窄。

与任何未定义的行为一样,您看到的实际结果将因操作系统版本和硬件类型而异。

如果您需要确保在 onPause 之后不会收到 View 消息,您应该在 onPause 中取消 Hook 您的处理程序。

关于android - OnClickListener 在 onPause 之后触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31432014/

有关android - OnClickListener 在 onPause 之后触发?的更多相关文章

  1. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  2. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  3. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  6. ruby-on-rails - Ruby method_added 回调不触发包括模块 - 2

    我想写一点“Deprecate-It”库并经常使用“method_added”回调。但是现在我注意到在包含模块时不会触发此回调。是否有任何回调或变通方法,以便在某些内容包含到自身时通知类“Foobar”?用于演示的小Demo:#IncludingModulswon'ttriggermethod_addedcallbackmoduleInvisibleMethoddefinvisible"Youwon'tgetacallbackfromme"endendclassFoobardefself.method_added(m)puts"InstanceMethod:'#{m}'addedto'

  7. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  8. ruby - 为什么触发器运算符包含第二个条件? - 2

    以下代码使用了触发器运算符。(1..10).each{|x|print"#{x},"ifx==3..x==5}为什么结果是3,4,5?我觉得应该是3,4。如教程中所述,此表达式在x==3时为真,并一直为真,直到x==5。如果“5”的计算结果为false,如何打印它?谁能为我澄清一下? 最佳答案 来自“TheRubyProgrammingLanguage”的重要链接是:4.6.9.1Booleanflip-flopsWhenthe..and...operatorsareusedinaconditional,suchasanifstat

  9. Ruby URI - 如何在 URL 之后获取完整路径 - 2

    给定以下内容,如何获取URL的完整路径uri=URI("http://foo.com/posts?id=30&limit=5#time=1305298413")我只想要posts?id=30&limit=5#time=1305298413我试过uri.path并返回/posts和ui.query返回'id=30&limit=5' 最佳答案 您要找的方法是request_uriuri.request_uri=>"/posts?id=30&limit=5"如果需要,您可以使用任何您想要删除前导/的方法。编辑:要获取#符号后的部分,请使用

  10. ruby - 在 gem --version 之后运行时获取 "isn' t a Gem::Specification(改为 NilClass) - 2

    $gem--version[/home/rohit/.rvm/gems/ruby-1.9.3-p125@qnrDashboard/specifications/net-ssh-2.5.2.gemspec]isn'taGem::Specification(NilClassinstead).[/home/rohit/.rvm/gems/ruby-1.9.3-p125@qnrDashboard/specifications/net-sftp-2.0.5.gemspec]isn'taGem::Specification(NilClassinstead).[/home/rohit/.rvm/ge

随机推荐