Android 停止在父级调用 onPause class
Android stop onPause from being called in parent class
在我的应用程序中,我有一个子项 class,它扩展了 支持库 class,在 中调用了 SearchFragment
Leanback 支持库。我需要扩展此 class 但不幸的是,父级 (SearchFragment
) class 的 onPause()
有一个我无法使用的方法。
每次我离开 activity 父 class 运行 时 onPause()
调用我不想要的方法。
有什么方法可以扩展 SearchFragment
class 但不允许它 运行 自己的 onPause()
?
这是我无法更改的父 class 中的 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;
}
}
此外,我这样做的原因是因为这是 Android TV > Fire TV 端口。 Fire TV 没有语音识别器。
onPause
是 activity 生命周期的一部分,不容忽视,但您可以采取一些技巧来做到这一点。它要求您修改 releaseRecognizer()
方法的行为。
代码可以修改如下:
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
}
这样您可以确保 releaseRecognizer
不会 运行 代码两次。
如 android documents 中所述,在 onpause()
中释放系统资源是一种很好的做法。
我认为你应该在 onResume()
中再次获得它 .. As
@Override
public void onResume() {
super.onResume();
acquireRecognizer();
}
@Override
public void onPause() {
super.onPause();
releaseRecognizer();
}
或者您应该在 onStop()
或 onDestroy()
中发布识别器。通过这种方式,它将保持识别器直到 activity 还活着。
@Override
protected void onStop() {
super.onStop();
releaseRecognizer();
}
因为 onPause()
在具有 public
可访问性的父 SearchFragment
class 的方法之一中,您可以简单地在子 [=21 中覆盖它=]es 而不是调用 super.onPause()
。这不会将该方法传播到父 class,因此不会调用臭名昭著的 releaseRecognizer()
。
但是,您需要注意实现与 SearchFragment
的其他生命周期方法正确绑定的业务逻辑,以免系统资源被滥用。因此,您需要根据您的用例逻辑修改重写代码,以便最终调用 onPause()
。
在我看来,您可以按照其他答案中的建议覆盖 SearchFragment onPause,但是通过删除 super.onPause() 您将面临一些问题。因此,一种安全的解决方案是编写您自己的 SearchFragment class(复制该 class 中的所有代码并创建您自己的 class)现在在此 class 中删除您执行的方法不想在 onPause() 方法中调用。通过这种方式,您不会删除 super 调用,因此这种方法是安全的。
使用 Proguard assumenosideeffects
选项消除对 SearchFragment 中的 releaseRecognizer() 方法的调用。这将要求您在启用 Proguard 的情况下编译代码,但由于相关代码是在某种特定情况下调用的,因此您可能仅在发布版本中使用 Proguard。
请注意,您必须启用优化(dontoptimize
选项 不得设置 ),因为通过 assumenosideeffects
剥离对方法的调用在技术上是一个 "optimization".
确保使用 中的建议将 Proguard 操作限制为您想要 "optimize" 的特定 类(在您的情况下 — android.support.v17.leanback.app.SearchFragment).
这是在不修改 SearchFragment 源代码的情况下解决您的问题的唯一方法。转念一想,你可能最好只是将必要的 类 复制到你的项目中,或者在最坏的情况下——将整个 Leanback 支持库作为 Gradle 子模块插入并直接修改必要的方法(很有可能,除了这个问题,Fire TV 还有其他问题。
在我的应用程序中,我有一个子项 class,它扩展了 支持库 class,在 中调用了 SearchFragment
Leanback 支持库。我需要扩展此 class 但不幸的是,父级 (SearchFragment
) class 的 onPause()
有一个我无法使用的方法。
每次我离开 activity 父 class 运行 时 onPause()
调用我不想要的方法。
有什么方法可以扩展 SearchFragment
class 但不允许它 运行 自己的 onPause()
?
这是我无法更改的父 class 中的 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;
}
}
此外,我这样做的原因是因为这是 Android TV > Fire TV 端口。 Fire TV 没有语音识别器。
onPause
是 activity 生命周期的一部分,不容忽视,但您可以采取一些技巧来做到这一点。它要求您修改 releaseRecognizer()
方法的行为。
代码可以修改如下:
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
}
这样您可以确保 releaseRecognizer
不会 运行 代码两次。
如 android documents 中所述,在 onpause()
中释放系统资源是一种很好的做法。
我认为你应该在 onResume()
中再次获得它 .. As
@Override
public void onResume() {
super.onResume();
acquireRecognizer();
}
@Override
public void onPause() {
super.onPause();
releaseRecognizer();
}
或者您应该在 onStop()
或 onDestroy()
中发布识别器。通过这种方式,它将保持识别器直到 activity 还活着。
@Override
protected void onStop() {
super.onStop();
releaseRecognizer();
}
因为 onPause()
在具有 public
可访问性的父 SearchFragment
class 的方法之一中,您可以简单地在子 [=21 中覆盖它=]es 而不是调用 super.onPause()
。这不会将该方法传播到父 class,因此不会调用臭名昭著的 releaseRecognizer()
。
但是,您需要注意实现与 SearchFragment
的其他生命周期方法正确绑定的业务逻辑,以免系统资源被滥用。因此,您需要根据您的用例逻辑修改重写代码,以便最终调用 onPause()
。
在我看来,您可以按照其他答案中的建议覆盖 SearchFragment onPause,但是通过删除 super.onPause() 您将面临一些问题。因此,一种安全的解决方案是编写您自己的 SearchFragment class(复制该 class 中的所有代码并创建您自己的 class)现在在此 class 中删除您执行的方法不想在 onPause() 方法中调用。通过这种方式,您不会删除 super 调用,因此这种方法是安全的。
使用 Proguard assumenosideeffects
选项消除对 SearchFragment 中的 releaseRecognizer() 方法的调用。这将要求您在启用 Proguard 的情况下编译代码,但由于相关代码是在某种特定情况下调用的,因此您可能仅在发布版本中使用 Proguard。
请注意,您必须启用优化(dontoptimize
选项 不得设置 ),因为通过 assumenosideeffects
剥离对方法的调用在技术上是一个 "optimization".
确保使用
这是在不修改 SearchFragment 源代码的情况下解决您的问题的唯一方法。转念一想,你可能最好只是将必要的 类 复制到你的项目中,或者在最坏的情况下——将整个 Leanback 支持库作为 Gradle 子模块插入并直接修改必要的方法(很有可能,除了这个问题,Fire TV 还有其他问题。