mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 09:38:19 +00:00
Implement client restarting on Android
Restarting the client previously did not work, as the `shell_execute` function on Android uses `fork` which is not supported. Now, the client is restarted by using an Android intent to restart the main activity. This is triggered by sending a user-defined message from the native code to the SDL main activity thread.
This commit is contained in:
parent
804e87a979
commit
d4f47c2a55
|
@ -3,10 +3,13 @@ package org.ddnet.client;
|
|||
import android.app.NativeActivity;
|
||||
import org.libsdl.app.SDLActivity;
|
||||
import android.os.Bundle;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
|
||||
public class NativeMain extends SDLActivity {
|
||||
|
||||
private static final int COMMAND_RESTART_APP = SDLActivity.COMMAND_USER + 1;
|
||||
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[] {
|
||||
|
@ -19,4 +22,24 @@ public class NativeMain extends SDLActivity {
|
|||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
super.onCreate(SavedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onUnhandledMessage(int command, Object param) {
|
||||
if(command == COMMAND_RESTART_APP) {
|
||||
restartApp();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void restartApp() {
|
||||
Intent restartIntent =
|
||||
Intent.makeRestartActivityTask(
|
||||
getPackageManager().getLaunchIntentForPackage(
|
||||
getPackageName()
|
||||
).getComponent()
|
||||
);
|
||||
restartIntent.setPackage(getPackageName());
|
||||
startActivity(restartIntent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,3 +225,12 @@ const char *InitAndroid()
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// See NativeMain.java
|
||||
constexpr uint32_t COMMAND_USER = 0x8000;
|
||||
constexpr uint32_t COMMAND_RESTART_APP = COMMAND_USER + 1;
|
||||
|
||||
void RestartAndroidApp()
|
||||
{
|
||||
SDL_AndroidSendMessage(COMMAND_RESTART_APP, 0);
|
||||
}
|
||||
|
|
|
@ -20,4 +20,12 @@
|
|||
*/
|
||||
const char *InitAndroid();
|
||||
|
||||
/**
|
||||
* Sends an intent to the Android system to restart the app.
|
||||
*
|
||||
* This will restart the main activity in a new task. The current process
|
||||
* must immediately terminate after this function is called.
|
||||
*/
|
||||
void RestartAndroidApp();
|
||||
|
||||
#endif // ANDROID_ANDROID_MAIN_H
|
||||
|
|
|
@ -4594,11 +4594,13 @@ int main(int argc, const char **argv)
|
|||
pClient->Run();
|
||||
|
||||
const bool Restarting = pClient->State() == CClient::STATE_RESTARTING;
|
||||
#if !defined(CONF_PLATFORM_ANDROID)
|
||||
char aRestartBinaryPath[IO_MAX_PATH_LENGTH];
|
||||
if(Restarting)
|
||||
{
|
||||
pStorage->GetBinaryPath(PLAT_CLIENT_EXEC, aRestartBinaryPath, sizeof(aRestartBinaryPath));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<SWarning> vQuittingWarnings = pClient->QuittingWarnings();
|
||||
|
||||
|
@ -4611,7 +4613,11 @@ int main(int argc, const char **argv)
|
|||
|
||||
if(Restarting)
|
||||
{
|
||||
#if defined(CONF_PLATFORM_ANDROID)
|
||||
RestartAndroidApp();
|
||||
#else
|
||||
shell_execute(aRestartBinaryPath, EShellExecuteWindowState::FOREGROUND);
|
||||
#endif
|
||||
}
|
||||
|
||||
PerformFinalCleanup();
|
||||
|
|
Loading…
Reference in a new issue