Come posso "riavviare" a livello di programmazione un'app Android?


231

In primo luogo, so che non si dovrebbe davvero uccidere / riavviare un'applicazione su Android. Nel mio caso d'uso desidero ripristinare le impostazioni di fabbrica della mia applicazione in un caso specifico in cui un server invia informazioni specifiche al client.

L'utente può accedere al server solo con UNA istanza dell'applicazione (ovvero non sono consentiti più dispositivi). Se un'altra istanza ottiene quel blocco "connesso", tutte le altre istanze di quell'utente devono eliminare i propri dati (ripristino delle impostazioni di fabbrica), per mantenere la coerenza.

È possibile ottenere forzatamente il blocco, poiché l'utente potrebbe eliminare l'app e reinstallarla, il che comporterebbe un diverso ID istanza e l'utente non sarebbe più in grado di liberare il blocco. Pertanto è possibile ottenere forzatamente il blocco.

A causa di quella possibilità-forza, dobbiamo sempre verificare in un'istanza concreta che abbia il lucchetto. Questo viene fatto su (quasi) ogni richiesta al server. Il server potrebbe inviare un "ID blocco errato". Se viene rilevato, l'applicazione client deve eliminare tutto.


Quello era il caso d'uso.

Ho una ActivityA che avvia la ActivityL di accesso o la ActivityB principale dell'app in base a un valore sharedPrefs. Dopo aver avviato L o B, si chiude in modo che solo L o B siano in esecuzione. Quindi nel caso in cui l'utente abbia già effettuato l'accesso B ora è in esecuzione.

B inizia C. C chiama startServiceper IntentServiceD. Ciò si traduce in questo stack:

(A)> B> C> D

Dal metodo onHandleIntent di D un evento viene inviato a un ResultReceiver R.

R ora gestisce quell'evento fornendo all'utente una finestra di dialogo in cui può scegliere di ripristinare le impostazioni di fabbrica dell'applicazione (eliminare il database, sharedPrefs, ecc.)

Dopo il ripristino delle impostazioni di fabbrica, voglio riavviare l'applicazione (per chiudere tutte le attività) e riavviare solo A, che avvia quindi il login ActivityL e termina:

(A)> L

Il metodo onClick della finestra di dialogo è simile al seguente:

@Override
public void onClick(DialogInterface dialog, int which) {

    // Will call onCancelListener
    MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
    Intent i = new Intent(MyApp.getContext(), A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MyApp.getContext().startActivity(i);
}

E questa è la MyAppclasse:

public class MyApp extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }

    public static void factoryReset() {
        // ...
    }
}

Il problema è che se uso FLAG_ACTIVITY_NEW_TASKle attività B e C sono ancora in esecuzione. Se premo il pulsante Indietro sull'accesso Activityvedo C, ma voglio tornare alla schermata principale.

Se non imposto FLAG_ACTIVITY_NEW_TASKil messaggio di errore, ottengo:

07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

Non posso usare le Attività ' Context, perché la ServiceIntentD potrebbe anche essere chiamata da un'attività in background che viene avviata da AlarmManager.

Quindi, come potrei risolverlo nello stack di attività diventando (A)> L?

Risposte:


284

È possibile utilizzare PendingIntentper configurare l'avvio dell'avvio dell'attività in futuro e quindi chiudere l'applicazione

Intent mStartActivity = new Intent(context, StartActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);

5
Ha funzionato perfettamente per me! Ho appena usato android.os.Process.killProcess (android.os.Process.myPid ()); over System.exit ();
FDIM,

29
Sui dispositivi 4.3 e 4.4 (Tutto quello che ho testato) questo sembra uccidere l'attività corrente e quindi lanciarne uno nuovo sopra quello vecchio. Sono 2 attività in profondità (principale -> prefs). Premendo indietro mi porta alla vecchia app, una schermata indietro.
Mgamerz,

5
Nel mio caso, System.exit (0) non ha funzionato durante il rollback di una transazione. Invece ho usato activity.finish (); e funziona benissimo.
unificare

6
@Qulin, Ragazzi! Non puoi essere serio! Questo esempio è più simile alla direzione che all'esempio della vita reale. Devi modificare questo frammento con il nome dell'attività iniziale, l'ID intento e la meccanica di uscita, qualunque cosa tu voglia. Non copiarlo alla cieca, incollalo.
Oleg Koshkin,

19
Questo non funziona più con Android Q a causa di nuove restrizioni alle attività in background developer.android.com/preview/privacy/…
Marco Righini

103

Puoi semplicemente chiamare:

public static void triggerRebirth(Context context, Intent nextIntent) {
    Intent intent = new Intent(context, YourClass.class);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(KEY_RESTART_INTENT, nextIntent);
    context.startActivity(intent);
    if (context instanceof Activity) {
      ((Activity) context).finish();
    }

    Runtime.getRuntime().exit(0);
}

Che viene utilizzato nella libreria ProcessPhoenix


Come alternativa:

Ecco una versione leggermente migliorata della risposta di @Oleg Koshkin.

Se vuoi davvero riavviare la tua attività incluso un kill del processo corrente, prova a seguire il codice. Mettilo in una HelperClass o dove ti serve.

public static void doRestart(Context c) {
        try {
            //check if the context is given
            if (c != null) {
                //fetch the packagemanager so we can get the default launch activity 
                // (you can replace this intent with any other activity if you want
                PackageManager pm = c.getPackageManager();
                //check if we got the PackageManager
                if (pm != null) {
                    //create the intent with the default start activity for your application
                    Intent mStartActivity = pm.getLaunchIntentForPackage(
                            c.getPackageName()
                    );
                    if (mStartActivity != null) {
                        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        //create a pending intent so the application is restarted after System.exit(0) was called. 
                        // We use an AlarmManager to call this intent in 100ms
                        int mPendingIntentId = 223344;
                        PendingIntent mPendingIntent = PendingIntent
                                .getActivity(c, mPendingIntentId, mStartActivity,
                                        PendingIntent.FLAG_CANCEL_CURRENT);
                        AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
                        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
                        //kill the application
                        System.exit(0);
                    } else {
                        Log.e(TAG, "Was not able to restart application, mStartActivity null");
                    }
                } else {
                    Log.e(TAG, "Was not able to restart application, PM null");
                }
            } else {
                Log.e(TAG, "Was not able to restart application, Context null");
            }
        } catch (Exception ex) {
            Log.e(TAG, "Was not able to restart application");
        }
    }

Questo reinizializzerà anche le classi jni e tutte le istanze statiche.


1
Questa soluzione è buona, ma ritarderà per alcuni secondi fino a quando non riavvierà l'applicazione, anche se hai ridotto i 100 Millis. Tuttavia, questa libreria ProcessPhoenix di Jack Wharton lo fa meglio e rapidamente, ma non vale la pena aggiungere una libreria solo per questa funzione all'interno dell'app.
progetto

@blueware Ho aggiornato la mia risposta e aggiunto il codice utilizzato all'interno di ProcessPhonix
mikepenz

@mikepenz, questo ragazzo "Ilya_Gazman" ha fatto molto meglio e senza usare una libreria del genere.
progetto

3
@blueware - Tranne che la soluzione di Ilya non riavvierà il processo, quindi i dati statici o le librerie NDK caricate non verranno reinizializzati correttamente.
Ted Hopp,

Alcuni dispositivi Huawei e Samsung hanno delle restrizioni AlarmManagere si comportano male se si utilizza questa soluzione. Qualche approccio migliore?
progetto

69

Jake Wharton ha recentemente pubblicato la sua libreria ProcessPhoenix , che lo fa in modo affidabile. Fondamentalmente devi solo chiamare:

ProcessPhoenix.triggerRebirth(context);

La libreria terminerà automaticamente l'attività di chiamata, interromperà il processo dell'applicazione e riavvierà successivamente l'attività dell'applicazione predefinita.


Questo sembra funzionare, ma ho un arresto anomalo (che viene segnalato). Non sono sicuro che sia l'ideale.
BK-

1
Non ho mai avuto problemi con la lib, ma sentiti libero di segnalare un bug su github.com/JakeWharton/ProcessPhoenix/issues
TBieniek

Argh, ritiro il mio commento perché non ho guardato il messaggio abbastanza da vicino. Mi mancava un filtro intento sulla mia attività di avvio predefinita. Potrebbe valere la pena notare i filtri di intento esatti richiesti.
BK-

1
Questa è finora la soluzione migliore.
yongsunCN,

1
@Shambhu devi aggiungere il tag <category android:name="android.intent.category.DEFAULT" />alla tua attività predefinita <intent-filter> nel manifest dell'app.
Muhammed Refaat,

57

Ho leggermente modificato la risposta Ilya_Gazman per utilizzare nuove API (IntentCompat è obsoleto a partire dall'API 26). Runtime.getRuntime (). Exit (0) sembra essere migliore di System.exit (0).

 public static void triggerRebirth(Context context) {
    PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
    ComponentName componentName = intent.getComponent();
    Intent mainIntent = Intent.makeRestartActivityTask(componentName);
    context.startActivity(mainIntent);
    Runtime.getRuntime().exit(0);
}

8
Direttamente dalla documentazione : " La chiamata System.exit(n) è effettivamente equivalente alla chiamata: Runtime.getRuntime().exit(n) ". Internamente, System.exit()si gira e chiama Runtime.getRuntime().exit(). Non c'è niente di "meglio" nell'uno o nell'altro (a meno che non ci si preoccupi di quanto si digita o di un ulteriore livello di chiamate di metodo).
Ted Hopp,

dove e quando chiamare il metodo sopra?
Makvin,

1
@Makvin decidi tu come chiamarlo. Il mio caso era il riavvio dell'app dopo il cambio di lingua.
android_dev l'

@TedHopp ha commentato ogni risposta come "non buona", hai qualche soluzione fattibile? Non essendo sarcastico, è davvero necessario ricreare un'applicazione senza lasciare alcuna traccia; dalle variabili statiche alle istanze di classe.
Farid

1
@FARID - Probabilmente funzionerà qualsiasi delle soluzioni che prevedono la chiamata Runtime.getRuntime().exit(0)(o System.exit(0)). Alcuni dei miei commenti "non buoni" sono per le risposte (come quello di Ilya Gazman che sono stati modificati per incorporare una simile chiamata.
Ted Hopp

37

IntentCompat.makeRestartActivityTask

Il nuovo modo di farlo è usare IntentCompat.makeRestartActivityTask

Crea un Intento che può essere utilizzato per riavviare l'attività di un'applicazione nel suo stato di base. È come makeMainActivity (ComponentName), ma imposta anche i flag Intent.FLAG_ACTIVITY_NEW_TASK e FLAG_ACTIVITY_CLEAR_TASK.

PackageManager packageManager = context.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
context.startActivity(mainIntent);
System.exit(0);

6
Ciò riavvia l'attività, ma non riavvia il processo, né l' Applicationoggetto. Pertanto tutti i staticdati, i dati inizializzati durante la creazione delle Applicationclassi jni o rimangono nel loro stato corrente e non vengono reinizializzati.
Ted Hopp,

2
@TedHopp Oh, ho perso quella parte. Ho aggiunto System.exit (0); Ma non sono sicuro al 100% che funzionerà. Lo
proverò

1
La migliore soluzione senza utilizzare la libreria open source per farlo. Mani in alto e grazie per aver fornito questa risposta, +1
blueware

4
Purtroppo, IntentCompat.makeRestartActivityTaskora è deprecato . Se controlli il codice sorgente , è semplice come aggiungere semplicemente i flag Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.
Paul Lammertsma,

IntentCompat.makeRestartActivityTask rimosso
luckyhandler il

28

C'è davvero un bel trucco. Il mio problema era che alcune vecchie librerie Jni C ++ trapelavano risorse. Ad un certo punto, ha smesso di funzionare. L'utente ha tentato di uscire dall'app e avviarla di nuovo, senza risultati, perché terminare un'attività non equivale a terminare (o uccidere) il processo. (A proposito, l'utente potrebbe andare all'elenco delle applicazioni in esecuzione e fermarlo da lì - questo funzionerebbe, ma gli utenti semplicemente non sanno come chiudere le applicazioni.)

Se vuoi osservare l'effetto di questa funzione, aggiungi una staticvariabile alla tua attività e incrementala ciascuna, diciamo, premi il pulsante. Se si esce dall'attività dell'applicazione e quindi si richiama nuovamente l'applicazione, questa variabile statica manterrà il suo valore. (Se l'applicazione fosse davvero uscita, alla variabile verrebbe assegnato il valore iniziale.)

(E devo commentare il motivo per cui non volevo correggere l'errore. La libreria è stata scritta decenni fa e ha fatto trapelare risorse da allora. La direzione ritiene che abbia sempre funzionato . Il costo di fornire una correzione invece di una soluzione alternativa ... Penso che tu abbia avuto l'idea.)

Ora, come posso ripristinare una libreria condivisa jni (aka dynamic, .so) allo stato iniziale? Ho scelto di riavviare l'applicazione come nuovo processo.

Il trucco è che System.exit () chiude l'attività corrente e Android ricrea l'applicazione con un'attività in meno.

Quindi il codice è:

/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    // Do not forget to add it to AndroidManifest.xml
    // <activity android:name="your.package.name.MagicAppRestart"/>
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.exit(0);
    }
    public static void doRestart(Activity anyActivity) {
        anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
    }
}

L'attività chiamante esegue semplicemente il codice MagicAppRestart.doRestart(this);, l'attività chiamante onPause()viene eseguita e quindi il processo viene ricreato. E non dimenticare di menzionare questa attività in AndroidManifest.xml

Il vantaggio di questo metodo è che non ci sono ritardi.

UPD: ha funzionato in Android 2.x, ma in Android 4 qualcosa è cambiato.


3
ho usato activity.startActivity (i); System.exit (0); soluzione geniale
max4ever,

5
Questa soluzione chiude l'app per me, ma non si riavvia. Almeno su Android 4.3.
Kirill Rakhman,

1
Su samsung galaxy mega android 4.2.2 provoca un loop infinito di riavvio. Quindi l'app non si riavvierà.
Gunhan,

@Gunhan 1) cosa succede se si sostituisce System.exit(0)con android.os.Process.killProcess(android.os.Process.myPid());? 2) un ciclo infinito molto probabilmente significa che non rimuovono l'attività più alta quando riavviano un'app. In linea di principio, è possibile aggiungere una variabile booleana statica, impostarla su true prima di richiamare l'attività di riavvio e dopo il riavvio sarà falsa. Quindi l'attività può scoprire se il riavvio è già avvenuto (e se è accaduto, basta finire () ). OTOH, il tuo rapporto indica che il trucco non funziona in modo identico su tutti i dispositivi.
18446744073709551615,

@Gunham Se stai iniziando la stessa attività che sta causando il riavvio, sarà un ciclo infinito su qualsiasi dispositivo.
Lukas Hanacek,

23

La mia soluzione non riavvia il processo / l'applicazione. Consente all'app solo di "riavviare" l'attività home (e di chiudere tutte le altre attività). Sembra un riavvio per gli utenti, ma il processo è lo stesso. Penso che in alcuni casi le persone vogliano ottenere questo effetto, quindi lo lascio qui FYI.

public void restart(){
    Intent intent = new Intent(this, YourHomeActivity.class);
    this.startActivity(intent);
    this.finishAffinity();
}

15

Ok, ho eseguito il refactoring della mia app e non finirò A automaticamente. Ho lasciato correre questo e finisco l' onActivityResultevento. In questo modo posso usare i flag FLAG_ACTIVITY_CLEAR_TOP+ FLAG_ACTIVITY_NEW_TASKper ottenere ciò che voglio:

public class A extends Activity {

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        // ...
        if (loggedIn) {
            startActivityForResult(new Intent(this, MainActivity.class), 0);
        } else {
            startActivityForResult(new Intent(this, LoginActivity.class), 0);
        }
    }
}

e nel ResultReceiver

@Override
public void onClick(DialogInterface dialog, int which) {
    MyApp.factoryReset();
    Intent i = new Intent(MyApp.getContext(), A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MyApp.getContext().startActivity(i);
}

Grazie comunque!


23
Questo non riavvierà l'applicazione, ma solo ricreare le classi. Pertanto, qualsiasi variabile statica all'interno delle classi manterrà i valori delle esecuzioni precedenti.
Brian White,

14
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

24
Questo non riavvierà l'applicazione, ma solo ricreare le classi. Pertanto, qualsiasi variabile statica all'interno delle classi manterrà i valori delle esecuzioni precedenti.
Brian White,

14

L'unico codice che non ha attivato "La tua app si è chiusa inaspettatamente" è il seguente. È anche un codice non deprecato che non richiede una libreria esterna. Inoltre non richiede un timer.

public static void triggerRebirth(Context context, Class myClass) {
    Intent intent = new Intent(context, myClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);
    Runtime.getRuntime().exit(0);
}

8

Ho scoperto che funziona su API 29 e successive, allo scopo di uccidere e riavviare l'app come se l'utente l'avesse avviata quando non era in esecuzione.

public void restartApplication(final @NonNull Activity activity) {
   // Systems at 29/Q and later don't allow relaunch, but System.exit(0) on
   // all supported systems will relaunch ... but by killing the process, then
   // restarting the process with the back stack intact. We must make sure that
   // the launch activity is the only thing in the back stack before exiting.
   final PackageManager pm = activity.getPackageManager();
   final Intent intent = pm.getLaunchIntentForPackage(activity.getPackageName());
   activity.finishAffinity(); // Finishes all activities.
   activity.startActivity(intent);    // Start the launch activity
   System.exit(0);    // System finishes and automatically relaunches us.
}

Ciò è stato fatto quando l'attività di avvio nell'app ha questo:

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Ho visto commenti che affermano che è necessaria una categoria di DEFAULT, ma non ho trovato che sia così. Ho confermato che l'oggetto Applicazione nella mia app è stato ricreato, quindi credo che il processo sia stato effettivamente interrotto e riavviato.

L'unico scopo per cui lo uso è riavviare l'app dopo che l'utente ha abilitato o disabilitato la segnalazione degli arresti anomali per Firebase Crashlytics. Secondo i loro documenti, l'app deve essere riavviata (processo interrotto e ricreato) per rendere effettiva la modifica.


7

Il modo migliore per riavviare completamente un'app è riavviarla, non solo per passare a un'attività con FLAG_ACTIVITY_CLEAR_TOPe FLAG_ACTIVITY_NEW_TASK. Quindi la mia soluzione è farlo dalla tua app o anche da un'altra app, l'unica condizione è conoscere il nome del pacchetto dell'app (esempio: ' com.example.myProject ')

 public static void forceRunApp(Context context, String packageApp){
    Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageApp);
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(launchIntent);
}

Esempio di riavvio dell'utilizzo o avvio di appA da appB :

forceRunApp(mContext, "com.example.myProject.appA");

Puoi verificare se l'app è in esecuzione:

 public static boolean isAppRunning(Context context, String packageApp){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
    for (int i = 0; i < procInfos.size(); i++) {
        if (procInfos.get(i).processName.equals(packageApp)) {
           return true;
        }
    }
    return false;
}

Nota : so che questa risposta è un po 'fuori tema, ma può essere davvero utile per qualcuno.


5

Il mio modo migliore per riavviare l'applicazione è usare finishAffinity();
Since, finishAffinity();può essere utilizzato solo sulle versioni JELLY BEAN, quindi possiamo usarlo ActivityCompat.finishAffinity(YourCurrentActivity.this);per le versioni precedenti.

Quindi utilizzare Intentper avviare la prima attività, quindi il codice sarà simile al seguente:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    finishAffinity();
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
} else {
    ActivityCompat.finishAffinity(YourCurrentActivity.this);
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
}

Spero che sia d'aiuto.


1
Questo termina tutte le attività dell'attività corrente, ma non riavvia il processo, né ricrea l'oggetto Application. Pertanto, tutti i dati statici, i dati inizializzati durante la creazione dell'applicazione o le classi jni, rimangono nel loro stato corrente e non vengono reinizializzati.
Ted Hopp,


3

Ecco un esempio per riavviare l'app in modo generico utilizzando PackageManager:

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

Ciò riavvia l'attività, ma non riavvia il processo, né l' Applicationoggetto. Pertanto, tutti i dati statici, i dati inizializzati durante la creazione delle Applicationclassi jni o rimangono nel loro stato corrente e non vengono reinizializzati.
Ted Hopp,

3

prova questo:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

1
Come per ogni altra risposta che già suggerisce la stessa cosa, questo non riavvierà l'applicazione, ma solo ricreare le classi. Pertanto, i dati statici all'interno del processo non verranno ripristinati.
Ted Hopp,

2

Avviare direttamente la schermata iniziale con FLAG_ACTIVITY_CLEAR_TASKe FLAG_ACTIVITY_NEW_TASK.


2

Ho dovuto aggiungere un gestore per ritardare l'uscita:

 mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 200, mPendingIntent);
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Runtime.getRuntime().exit(0);
            }
        }, 100);

2

Uso:

navigateUpTo(new Intent(this, MainActivity.class));

Funziona a partire dal livello API 16 (4.1), credo.


1

Puoi usare il startInstrumentationmetodo di Activity. È necessario implementare vuoto Instrumentatione puntato in manifest. Dopodiché puoi chiamare questo metodo per riavviare la tua app. Come questo:

try {           
    InstrumentationInfo info = getPackageManager().queryInstrumentation(getPackageName(), 0).get(0);
    ComponentName component = new ComponentName(this, Class.forName(info.name));
    startInstrumentation(component, null, null);
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Ricevo dinamicamente il nome della classe di Strumentazione ma puoi hardcodificarlo. Alcuni come questo:

try {           
    startInstrumentation(new ComponentName(this, RebootInstrumentation.class), null, null); 
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Chiama startInstrumentationmake ricaricare la tua app. Leggi la descrizione di questo metodo. Ma non può essere sicuro se agisci come un'app kill.


1

L'applicazione a cui sto lavorando deve offrire all'utente la possibilità di scegliere quali frammenti visualizzare (i frammenti vengono modificati dinamicamente in fase di esecuzione). La soluzione migliore per me era riavviare completamente l'applicazione.

Quindi ho provato molte soluzioni e nessuna di queste ha funzionato per me, ma questo:

final Intent mStartActivity = new Intent(SettingsActivity.this, Splash.class);
final int mPendingIntentId = 123456;
final PendingIntent mPendingIntent = PendingIntent.getActivity(SettingsActivity.this, mPendingIntentId, mStartActivity,
                    PendingIntent.FLAG_CANCEL_CURRENT);
final AlarmManager mgr = (AlarmManager) SettingsActivity.this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
this.finishAffinity(); //notice here
Runtime.getRuntime().exit(0); //notice here

Spero che possa aiutare qualcun altro!


0

prova questo:

private void restartApp() {
    Intent intent = new Intent(getApplicationContext(), YourStarterActivity.class);
    int mPendingIntentId = MAGICAL_NUMBER;
    PendingIntent mPendingIntent = PendingIntent.getActivity(getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
    System.exit(0);
}

-1

Con la libreria Process Phoenix . L'attività che si desidera riavviare è denominata "A".

Sapore Java

// Java
public void restart(){
    ProcessPhoenix.triggerRebirth(context);
}

Sapore di Kotlin

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}

Questo ha lo sfortunato risultato di disconnettere il debugger.
DrSatan1,

-3

È possibile riavviare l'attività corrente in questo modo:

Frammento:

activity?.recreate()

Attività :

recreate()

3
Questo non è affatto ciò che OP vuole fare.
Ted Hopp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.