Resolve issue where the Godot app remains stuck when resuming.

This was caused by the fact that a new instance of Godot was created at resume while a previous instance already existed.
The previous instance would then go through its cleanup lifecycle, and would thus attempt to close the entire app, leading to the system to restart the app, thus starting the cycle anew.
The fix involves reusing the previous instance of Godot if one is available instead of creating a new one, as well as giving control to the host activity for how the process should be terminated.
This commit is contained in:
Fredia Huya-Kouadio 2021-08-12 12:01:28 -07:00
parent 1cd10461ca
commit 874aa1708f
3 changed files with 40 additions and 9 deletions

View file

@ -32,11 +32,12 @@ package org.godotengine.godot;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.util.Log;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
/**
@ -46,6 +47,8 @@ import androidx.fragment.app.FragmentActivity;
* within an Android app.
*/
public abstract class FullScreenGodotApp extends FragmentActivity implements GodotHost {
private static final String TAG = FullScreenGodotApp.class.getSimpleName();
@Nullable
private Godot godotFragment;
@ -53,12 +56,33 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.godot_app_layout);
godotFragment = initGodotInstance();
if (godotFragment == null) {
throw new IllegalStateException("Godot instance must be non-null.");
}
getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss();
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.godot_fragment_container);
if (currentFragment instanceof Godot) {
Log.v(TAG, "Reusing existing Godot fragment instance.");
godotFragment = (Godot)currentFragment;
} else {
Log.v(TAG, "Creating new Godot fragment instance.");
godotFragment = initGodotInstance();
if (godotFragment == null) {
throw new IllegalStateException("Godot instance must be non-null.");
}
getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss();
}
}
@Override
public void onDestroy() {
super.onDestroy();
onGodotForceQuit(godotFragment);
}
@Override
public final void onGodotForceQuit(Godot instance) {
if (instance == godotFragment) {
System.exit(0);
}
}
@Override

View file

@ -762,8 +762,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
super.onDestroy();
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
// native Godot components that is started in Godot#onVideoInit.
forceQuit();
}
@ -960,7 +958,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
private void forceQuit() {
System.exit(0);
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
// native Godot components that is started in Godot#onVideoInit.
if (godotHost != null) {
godotHost.onGodotForceQuit(this);
}
}
private boolean obbIsCorrupted(String f, String main_pack_md5) {

View file

@ -53,4 +53,9 @@ public interface GodotHost {
* Invoked on the render thread when the Godot main loop has started.
*/
default void onGodotMainLoopStarted() {}
/**
* Invoked on the UI thread as the last step of the Godot instance clean up phase.
*/
default void onGodotForceQuit(Godot instance) {}
}