简体   繁体   中英

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 . I need to extend this class but unfortunately the onPause() of the parent ( SearchFragment ) class has a method I cannot use.

Every time I leave the activity the parent class runs the onPause() which calls the method I don't want.

Is there a way I can extend the SearchFragment class but not allow it to run its own onPause() ?

Here is the onPause() method in the parent class that I cannot alter.

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. 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. It requires you to modify the behavior of your releaseRecognizer() method.

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.

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() . This will not propagate the method to the parent class and hence infamous releaseRecognizer() will not be called.

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. So, you need modify overridden code as per your your use-case logic so that you eventually call onPause() after all.

Use Proguard assumenosideeffects option to annihilate the call to releaseRecognizer() method inside SearchFragment. 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.

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".

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).


This is the only way to cope with your problem without modifying the source code of 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).

As mention in the android documents it's good practice to release system resources in onpause() .
I think you should have aquire it again in onResume() .. As

@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() . 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. 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. By this way you are not removing super call, so this approach will be safe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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