简体   繁体   English

Android停止在父类中调用onPause

[英]Android stop onPause from being called in parent class

In my app I have a child class that extends a support library class called SearchFragment in the leanback support library . 在我的应用程序中,我有一个子类,该子类扩展了leanback支持库中名为SearchFragment支持库类。 I need to extend this class but unfortunately the onPause() of the parent ( SearchFragment ) class has a method I cannot use. 我需要扩展此类,但不幸的是,父类( SearchFragment )的onPause()具有无法使用的方法。

Every time I leave the activity the parent class runs the onPause() which calls the method I don't want. 每次我离开活动时,父类都会运行onPause() ,该方法调用我不需要的方法。

Is there a way I can extend the SearchFragment class but not allow it to run its own onPause() ? 有没有一种方法可以扩展SearchFragment类,但不允许其运行自己的onPause()

Here is the onPause() method in the parent class that I cannot alter. 这是父类中无法更改的onPause()方法。

android.support.v17.leanback.app.SearchFragment

@Override
public void onPause() {
    releaseRecognizer(); //Need to stop this from calling
    super.onPause();
}

private void releaseRecognizer() {
    if (null != mSpeechRecognizer) {
        mSearchBar.setSpeechRecognizer(null);
        mSpeechRecognizer.destroy();
        mSpeechRecognizer = null;
    }
}

Also, the reason I am doing this is because this is an Android TV > Fire TV port. 另外,我这样做的原因是因为这是Android TV> Fire TV端口。 Fire TV does not have a speechRecognizer. 消防电视没有语音识别器。

onPause is a part of activity life cycle and cannot be ignored but you can do some hacks to do it. onPause是活动生命周期的一部分,不能忽略,但是您可以做一些修改。 It requires you to modify the behavior of your releaseRecognizer() method. 它要求您修改releaseRecognizer()方法的行为。

The code can be changed as follows: 可以如下更改代码:

boolean isReleased;

public void releaseRecognizer() {
   if(isReleased) {
      return;
   }
   ...
   //your code go here
   ...
   isReleased = true;
}

//Somewhere else where you acquire the recognizer again you just set it to false:

public void acquireRecognizer(){

   ...
   isReleased = false
}

This way you make sure releaseRecognizer doesn't run the code twice. 这样,您可以确保releaseRecognizer不会两次运行代码。

Since, onPause() in one of the methods of the parent SearchFragment class with public accessibility, you can simply override it in you sub-classes and not call super.onPause() . 由于onPause()在具有public可访问性的父SearchFragment类的方法之一中,因此您可以在子类中简单地覆盖它,而不用调用super.onPause() This will not propagate the method to the parent class and hence infamous releaseRecognizer() will not be called. 这不会将方法传播到父类,因此不会调用臭名昭著的releaseRecognizer()

However, you need to take care that you implement your business logic that is properly tied up with other lifecycle methods of the SearchFragment so that system resources are not abused. 但是,您需要注意实现与SearchFragment其他生命周期方法正确捆绑的业务逻辑,以免滥用系统资源。 So, you need modify overridden code as per your your use-case logic so that you eventually call onPause() after all. 因此,您需要根据用例逻辑修改覆盖的代码,以便最终最终调用onPause()

Use Proguard assumenosideeffects option to annihilate the call to releaseRecognizer() method inside SearchFragment. 使用Proguard assumenosideeffects选项可以消除SearchFragment中对releaseRecognizer()方法的调用。 This will require you to compile your code with Proguard enabled, but since the code in question is invoked in somewhat specific scenario, you may get away with using Proguard in release builds only. 这将要求您在启用Proguard的情况下编译代码,但是由于有问题的代码是在某些特定情况下调用的,因此您可能只能在发行版本中使用Proguard。

Note, that you have to enable optimizations (the dontoptimize option must not be set), because stripping calls to methods via assumenosideeffects is technically an "optimization". 请注意,您必须启用优化( 不得设置dontoptimize选项),因为从技术上说,通过assumenosideeffects剥离对方法的调用是“优化”。

Make sure to use suggestions in this answer to limit Proguard actions to specific classes you want to "optimize" (in your case — to android.support.v17.leanback.app.SearchFragment). 确保在此答案中使用建议,以将Proguard操作限制为您要“优化”的特定类(在您的情况下为android.support.v17.leanback.app.SearchFragment)。


This is the only way to cope with your problem without modifying the source code of SearchFragment. 这是解决您的问题而不修改SearchFragment源代码的唯一方法。 On second thought, you may be better off simply copying necessary classes to your project or in the worst case — plugging entire leanback support library as Gradle submodule and modyfying necessary methods directly (there is a good chance, that Fire TV has other issues with it besides this one). 再三考虑,您可能会简单地将必要的类复制到项目中,或者在最坏的情况下更好–将整个leanback支持库作为Gradle子模块插入并直接修改必要的方法(很有可能,Fire TV还有其他问题)除了这个)。

As mention in the android documents it's good practice to release system resources in onpause() . android文档中提到的,在onpause()释放系统资源是onpause()很好的做法。
I think you should have aquire it again in onResume() .. As 我认为您应该在onResume()再次获取它。

@Override
public void onResume() {
super.onResume();
acquireRecognizer();
}

@Override
public void onPause() {
super.onPause();
releaseRecognizer();
}

Or perhaps you should release the recognizer in onStop() or in onDestroy() . 或者,您应该在onStop()onDestroy()释放识别器。 In this way it will keep the recognizer untill the activity is alive. 这样,它将使识别器保持活动状态。

@Override
protected void onStop() {
super.onStop();
releaseRecognizer();
}

In my view, you can override SearchFragment onPause as suggested here in other answers but by removing super.onPause() you will face some problems. 在我看来,您可以按照其他答案中此处建议的方法覆盖SearchFragment onPause,但是通过删除super.onPause()会遇到一些问题。 So one safe solution can be to write your own SearchFragment class (copy all code from that class and crate your own class) Now in this class remove the method you do not want to call within onPause() method. 因此,一种安全的解决方案是编写您自己的SearchFragment类(复制该类中的所有代码并创建您自己的类),现在在该类中删除您不想在onPause()方法中调用的方法。 By this way you are not removing super call, so this approach will be safe. 这样,您就不会删除超级呼叫,因此这种方法将是安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM