Bagaimana cara saya "me-restart" aplikasi Android?

231

Pertama, saya tahu bahwa seseorang seharusnya tidak benar-benar mematikan / memulai ulang aplikasi di Android. Dalam kasus penggunaan saya, saya ingin mengatur ulang pabrik aplikasi saya dalam kasus tertentu di mana server mengirimkan informasi tertentu ke klien.

Pengguna hanya dapat login di server dengan SATU instance aplikasi (yaitu beberapa perangkat tidak diperbolehkan). Jika instance lain mendapatkan "login" -kunci maka semua instance lain dari pengguna tersebut harus menghapus data mereka (reset pabrik), untuk mempertahankan konsistensi.

Dimungkinkan untuk mendapatkan kunci secara paksa, karena pengguna mungkin menghapus aplikasi dan menginstalnya kembali yang akan menghasilkan id-instance yang berbeda dan pengguna tidak akan dapat membebaskan kunci lagi. Karena itu dimungkinkan untuk mendapatkan kunci secara paksa.

Karena kemungkinan-kekuatan itu kita perlu selalu memeriksa secara konkret bahwa ia memiliki kunci. Itu dilakukan pada (hampir) setiap permintaan ke server. Server mungkin mengirim "salah-kunci-id". Jika itu terdeteksi, aplikasi klien harus menghapus semuanya.


Itu adalah kasus penggunaan.

Saya memiliki nilai ActivityA yang memulai Login ActivityL atau ActivityB utama aplikasi tergantung pada nilai sharedPrefs. Setelah memulai L atau B itu menutup sendiri sehingga hanya L atau B yang berjalan. Jadi dalam hal pengguna sudah masuk B sedang berjalan sekarang.

B dimulai C. C panggilan startServiceuntuk IntentServiceD. Itu hasil di tumpukan ini:

(A)> B> C> D

Dari metode onHandleIntent dari D, sebuah event dikirimkan ke ResultReceiver R.

R sekarang menangani acara itu dengan menyediakan dialog kepada pengguna di mana ia dapat memilih untuk mengatur ulang aplikasi (menghapus database, sharedPrefs, dll.)

Setelah reset pabrik saya ingin me-restart aplikasi (untuk menutup semua aktivitas) dan hanya memulai A lagi yang kemudian meluncurkan login ActivityL dan menyelesaikan sendiri:

(A)> L

Metode onClick Dialog terlihat seperti ini:

@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);
}

Dan itulah MyAppkelasnya:

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() {
        // ...
    }
}

Masalahnya adalah jika saya menggunakan FLAG_ACTIVITY_NEW_TASKAktivitas B dan C masih berjalan. Jika saya menekan tombol kembali pada login Activitysaya melihat C, tetapi saya ingin kembali ke layar beranda.

Jika saya tidak mengatur FLAG_ACTIVITY_NEW_TASKsaya mendapat kesalahan:

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?

Saya tidak dapat menggunakan Kegiatan ' Context, karena ServiceIntentD juga dapat dipanggil dari tugas latar belakang yang dimulai oleh AlarmManager.

Jadi bagaimana saya bisa menyelesaikan ini hingga tumpukan aktivitas menjadi (A)> L?

Terjebak
sumber

Jawaban:

284

Anda dapat menggunakan PendingIntentuntuk mengatur meluncurkan aktivitas awal Anda di masa depan dan kemudian menutup aplikasi Anda

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);
Oleg Koshkin
sumber
5
Ini bekerja dengan baik untuk saya! Saya baru saja menggunakan android.os.Process.killProcess (android.os.Process.myPid ()); lebih dari System.exit ();
FDIM
29
Pada perangkat 4.3 dan 4.4 (Semua yang telah saya uji) ini tampaknya mematikan aktivitas saat ini dan kemudian meluncurkan yang baru di atas yang lama. Saya 2 activies deep (main -> prefs). Menekan kembali membawa saya ke aplikasi lama, satu layar kembali.
Mgamerz
5
Dalam kasus saya, System.exit (0) tidak berfungsi karena transaksi dibatalkan. Sebagai gantinya saya menggunakan activity.finish (); dan itu berfungsi dengan baik.
satukan
6
@Qulin, Kawan! Kamu tidak bisa serius! Contoh ini lebih seperti arahan daripada contoh kehidupan nyata. Anda harus memodifikasi cuplikan ini dengan memulai nama aktivitas, maksud, dan keluar dari mekanis apa pun yang Anda miliki. Jangan menyalin secara membabi buta.
Oleg Koshkin
19
Ini tidak berfungsi lagi dengan Android Q karena pembatasan baru pada aktivitas latar belakang developer.android.com/preview/privacy/…
Marco Righini
103

Anda cukup menelepon:

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);
}

Yang digunakan di perpustakaan ProcessPhoenix


Sebagai alternatif:

Inilah versi jawaban @Oleg Koshkin yang sedikit lebih baik.

Jika Anda benar-benar ingin memulai kembali aktivitas Anda termasuk penghentian proses saat ini, coba ikuti kode. Tempatkan di HelperClass atau di tempat Anda membutuhkannya.

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");
        }
    }

Ini juga akan menginisialisasi ulang kelas jni dan semua instance statis.

mikepenz
sumber
1
Solusi ini bagus, tetapi akan tertunda selama beberapa detik hingga restart aplikasi Anda, bahkan jika Anda menurunkan 100 Millis. Namun, perpustakaan ini ProcessPhoenix oleh Jack Wharton melakukannya dengan lebih baik dan cepat, tetapi tidak layak menambahkan perpustakaan hanya untuk fungsi ini di dalam aplikasi.
blueware
@blueware Saya telah memperbarui jawaban saya dan menambahkan kode yang digunakan di dalam ProcessPhonix
mikepenz
@mikepenz, orang ini "Ilya_Gazman" melakukan jauh lebih baik dan tanpa menggunakan perpustakaan seperti itu.
blueware
3
@blueware - Kecuali solusi Ilya tidak akan memulai ulang proses, sehingga data statis atau pustaka NDK yang dimuat tidak akan diinisialisasi ulang dengan benar.
Ted Hopp
Beberapa perangkat Huawei dan Samsung memiliki batasan AlarmManagerdan kesalahan perilaku jika menggunakan solusi ini, Adakah pendekatan yang lebih baik?
blueware
69

Jake Wharton baru-baru ini menerbitkan perpustakaan ProcessPhoenix , yang melakukan ini dengan cara yang dapat diandalkan. Anda pada dasarnya hanya perlu menelepon:

ProcessPhoenix.triggerRebirth(context);

Perpustakaan akan secara otomatis menyelesaikan aktivitas panggilan, mematikan proses aplikasi dan memulai kembali aktivitas aplikasi default setelahnya.

TBieniek
sumber
Ini tampaknya berhasil, tetapi saya mengalami kerusakan (yang dilaporkan). Tidak yakin ini ideal.
BK-
1
Saya tidak pernah memiliki masalah dengan lib, tetapi merasa bebas untuk melaporkan bug di github.com/JakeWharton/ProcessPhoenix/issues
TBieniek
Argh, saya menarik kembali komentar saya karena saya tidak melihat pesan cukup dekat. Saya melewatkan filter maksud pada aktivitas peluncuran default saya. Mungkin perlu diperhatikan filter maksud persis yang dibutuhkan.
BK-
1
Sejauh ini solusi terbaik.
yongsunCN
1
@ Shambhu Anda harus menambahkan tag <category android:name="android.intent.category.DEFAULT" />ke aktivitas default Anda <intent-filter> di manifes aplikasi.
Muhammed Refaat
57

Saya telah sedikit memodifikasi jawaban Ilya_Gazman untuk menggunakan API baru (IntentCompat tidak digunakan mulai API 26). Runtime.getRuntime (). Exit (0) tampaknya lebih baik daripada 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);
}
android_dev
sumber
8
Langsung dari dokumen : " Panggilan System.exit(n) secara efektif setara dengan panggilan: Runtime.getRuntime().exit(n) ". Secara internal, System.exit()hanya berbalik dan menelepon Runtime.getRuntime().exit(). Tidak ada yang "lebih baik" tentang yang satu atau yang lainnya (kecuali jika ada yang khawatir tentang seberapa banyak yang diketik seseorang atau tentang satu lapisan tambahan panggilan metode).
Ted Hopp
dimana dan kapan memanggil metode di atas?
Makvin
1
@ Makvin Anda memutuskan di mana untuk menyebutnya. Kasing saya adalah restart aplikasi setelah perubahan bahasa.
android_dev
@TedHopp mengomentari setiap jawaban sebagai "tidak baik", apakah Anda punya solusi yang layak? Tidak menjadi sarkastik, benar-benar perlu membuat ulang aplikasi tanpa jejak tertinggal; dari variabel statika ke instance kelas.
Farid
1
@ FARID - Salah satu solusi yang melibatkan panggilan Runtime.getRuntime().exit(0)(atau System.exit(0)) mungkin akan berfungsi. Beberapa komentar "tidak baik" saya adalah untuk jawaban (seperti yang oleh Ilya Gazman yang sejak itu telah diedit untuk memasukkan panggilan semacam itu.
Ted Hopp
37

IntentCompat.makeRestartActivityTask

Cara baru untuk melakukannya, adalah dengan menggunakan IntentCompat.makeRestartActivityTask

Buat Intent yang dapat digunakan untuk meluncurkan kembali tugas aplikasi dalam kondisi dasarnya. Ini seperti makeMainActivity (ComponentName), tetapi juga menetapkan flag Intent.FLAG_ACTIVITY_NEW_TASK dan 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);
Ilya Gazman
sumber
6
Ini meluncurkan kembali tugas, tetapi tidak memulai ulang proses, atau bahkan Applicationobjek. Oleh karena itu setiap staticdata, data yang diinisialisasi selama pembuatan Application, atau kelas jni tetap dalam keadaan saat ini dan tidak diinisialisasi ulang.
Ted Hopp
2
@TedHopp Oh aku merindukan bagian itu. Saya menambahkan System.exit (0); Tapi saya tidak yakin 100% itu akan berhasil. Saya akan mengujinya terakhir pada
Ilya Gazman
1
Solusi terbaik tanpa menggunakan pustaka sumber terbuka untuk melakukannya.
Angkat
4
Sayangnya, IntentCompat.makeRestartActivityTasksekarang sudah usang . Jika Anda memeriksa kode sumber , sesederhana menambahkan bendera Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.
Paul Lammertsma
IntentCompat.makeRestartActivityTask dihapus
luckyhandler
28

Ada trik yang sangat bagus. Masalah saya adalah bahwa beberapa perpustakaan C ++ jni benar-benar tua membocorkan sumber daya. Pada titik tertentu, itu berhenti berfungsi. Pengguna mencoba untuk keluar dari aplikasi dan meluncurkannya lagi - tanpa hasil, karena menyelesaikan suatu kegiatan tidak sama dengan menyelesaikan (atau membunuh) proses. (Omong-omong, pengguna dapat masuk ke daftar aplikasi yang sedang berjalan dan menghentikannya dari sana - ini akan berhasil, tetapi pengguna tidak tahu cara menghentikan aplikasi.)

Jika Anda ingin mengamati efek dari fitur ini, tambahkan staticvariabel ke aktivitas Anda dan tambahkan masing-masing, katakanlah, tekan tombol. Jika Anda keluar dari aktivitas aplikasi dan menjalankan aplikasi lagi, variabel statis ini akan mempertahankan nilainya. (Jika aplikasi benar-benar keluar, variabel akan diberi nilai awal.)

(Dan saya harus mengomentari mengapa saya tidak ingin memperbaiki bug sebagai gantinya. Perpustakaan ditulis beberapa dekade yang lalu dan membocorkan sumber daya sejak saat itu. Manajemen percaya itu selalu berhasil . Biaya menyediakan perbaikan bukan solusi ... Saya pikir, Anda mendapatkan idenya.)

Sekarang, bagaimana saya bisa mereset pustaka jni shared (alias dynamic, .so) ke keadaan awal? Saya memilih untuk memulai kembali aplikasi sebagai proses baru.

Kuncinya adalah System.exit () menutup aktivitas saat ini dan Android membuat ulang aplikasi dengan satu aktivitas lebih sedikit.

Jadi kodenya adalah:

/** 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));
    }
}

Aktivitas panggilan hanya mengeksekusi kode MagicAppRestart.doRestart(this);, aktivitas panggilanonPause() dieksekusi, dan kemudian proses dibuat kembali. Dan jangan lupa untuk menyebutkan kegiatan ini di AndroidManifest.xml

Keuntungan dari metode ini adalah tidak ada penundaan.

UPD: itu bekerja di Android 2.x, tetapi di Android 4 ada sesuatu yang berubah.

18446744073709551615
sumber
3
saya menggunakan activity.startActivity (i); System.exit (0); solusi jenius
max4ever
5
Solusi ini menutup aplikasi untuk saya, tetapi tidak restart. Setidaknya di Android 4.3.
Kirill Rakhman
1
Pada samsung galaxy mega android 4.2.2 Ini menyebabkan loop restart tidak terbatas. Jadi aplikasi tidak akan mulai lagi.
Gunhan
@Gunhan 1) apa yang terjadi jika Anda mengganti System.exit(0)dengan android.os.Process.killProcess(android.os.Process.myPid());? 2) infinite loop kemungkinan besar berarti mereka tidak menghapus aktivitas paling atas ketika mereka me-restart aplikasi. Pada prinsipnya, Anda dapat menambahkan variabel boolean statis, mengaturnya menjadi true sebelum menjalankan aktivitas restart, dan setelah restart itu akan salah. Dengan demikian aktivitas dapat mengetahui apakah restart telah terjadi (dan jika sudah terjadi, cukup selesaikan () ). OTOH, laporan Anda berarti bahwa trik itu tidak berfungsi secara identik pada semua perangkat.
18446744073709551615
@Gunham Jika Anda memulai aktivitas yang sama yang menyebabkan restart maka itu akan menjadi loop tak terbatas pada perangkat apa pun.
Lukas Hanacek
23

Solusi saya tidak memulai kembali proses / aplikasi. Itu hanya memungkinkan aplikasi "memulai kembali" aktivitas rumah (dan mengabaikan semua aktivitas lainnya). Sepertinya restart untuk pengguna, tetapi prosesnya sama. Saya pikir dalam beberapa kasus orang ingin mencapai efek ini, jadi saya tinggalkan saja di sini FYI.

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

Oke, saya refactored aplikasi saya dan saya tidak akan menyelesaikan A secara otomatis. Saya membiarkan ini berjalan selalu dan menyelesaikannya melalui onActivityResultacara tersebut. Dengan cara ini saya bisa menggunakan tanda FLAG_ACTIVITY_CLEAR_TOP+ FLAG_ACTIVITY_NEW_TASKuntuk mendapatkan yang saya inginkan:

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);
        }
    }
}

dan di 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);
}

Bagaimanapun, terima kasih!

Terjebak
sumber
23
Ini tidak akan memulai ulang aplikasi, hanya membuat ulang kelas. Dengan demikian, variabel statis apa pun di dalam kelas akan mempertahankan nilai dari proses sebelumnya.
Brian White
14
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Nirav Ranpara
sumber
24
Ini tidak akan memulai ulang aplikasi, hanya membuat ulang kelas. Dengan demikian, variabel statis apa pun di dalam kelas akan mempertahankan nilai dari proses sebelumnya.
Brian White
14

Satu-satunya kode yang tidak memicu "Aplikasi Anda ditutup secara tidak terduga" adalah sebagai berikut. Ini juga kode yang tidak usang yang tidak memerlukan perpustakaan eksternal. Itu juga tidak memerlukan 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);
}
Haskell McRavin
sumber
8

Saya telah menemukan bahwa ini berfungsi pada API 29 dan yang lebih baru - untuk tujuan membunuh dan memulai ulang aplikasi seolah-olah pengguna telah meluncurkannya ketika tidak berjalan.

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

Itu dilakukan ketika aktivitas peluncur di aplikasi memiliki ini:

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

Saya telah melihat komentar yang mengklaim bahwa kategori DEFAULT diperlukan, tetapi saya belum menemukan itu yang menjadi masalahnya. Saya telah mengkonfirmasi bahwa objek Aplikasi di aplikasi saya dibuat ulang, jadi saya percaya bahwa proses tersebut benar-benar telah dimatikan dan dimulai ulang.

Satu-satunya tujuan yang saya gunakan ini adalah untuk me-restart aplikasi setelah pengguna telah mengaktifkan atau menonaktifkan pelaporan kerusakan untuk Firebase Crashlytics. Menurut dokumen mereka, aplikasi harus dihidupkan ulang (proses dibunuh dan dibuat ulang) agar perubahan itu berlaku.

Mark Peters
sumber
7

Cara terbaik untuk me-restart aplikasi sepenuhnya adalah untuk meluncurkan kembali, bukan hanya untuk melompat ke suatu aktivitas dengan FLAG_ACTIVITY_CLEAR_TOPdan FLAG_ACTIVITY_NEW_TASK. Jadi solusi saya adalah melakukannya dari aplikasi Anda atau bahkan dari aplikasi lain, satu-satunya syarat adalah mengetahui nama paket aplikasi (contoh: ' 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);
}

Contoh penggunaan, restart atau luncurkan appA dari appB :

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

Anda dapat memeriksa apakah aplikasi sedang berjalan:

 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;
}

Catatan : Saya tahu jawaban ini sedikit keluar dari topik, tetapi bisa sangat membantu bagi seseorang.

Choletski
sumber
5

Cara terbaik saya untuk me-restart aplikasi adalah menggunakan finishAffinity();
Sejak, finishAffinity();dapat digunakan pada versi JELLY BEAN saja, sehingga kita dapat menggunakan ActivityCompat.finishAffinity(YourCurrentActivity.this);untuk versi yang lebih rendah.

Kemudian gunakan Intentuntuk meluncurkan aktivitas pertama, sehingga kode akan terlihat seperti ini:

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);
}

Semoga ini bisa membantu.

Hussein ND
sumber
1
Ini mengakhiri semua kegiatan dalam tugas saat ini, tetapi tidak memulai ulang proses, atau bahkan membuat ulang objek Aplikasi. Oleh karena itu setiap data statis, data yang diinisialisasi selama pembuatan Aplikasi, atau oleh kelas jni, tetap dalam kondisi saat ini dan tidak diinisialisasi ulang.
Ted Hopp
3

Coba gunakan FLAG_ACTIVITY_CLEAR_TASK

Pedro Loureiro
sumber
hm dikembangkan untuk 2.1: Intent.FLAG_ACTIVITY_CLEAR_TASK tidak dapat diatasi
Terjebak
Maaf - Sejak: API Level 11 developer.android.com/reference/android/content/…
Pedro Loureiro
3

Berikut adalah contoh untuk memulai ulang aplikasi Anda secara umum dengan menggunakan PackageManager:

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Alireza Ghanbarinia
sumber
Ini meluncurkan kembali tugas, tetapi tidak memulai ulang proses, atau bahkan Applicationobjek. Oleh karena itu setiap data statis, data yang diinisialisasi selama pembuatan Application, atau kelas jni tetap dalam keadaan saat ini dan tidak diinisialisasi ulang.
Ted Hopp
3

coba ini:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
veeson
sumber
1
Seperti setiap jawaban lain di sini sudah menyarankan hal yang sama, ini tidak akan memulai ulang aplikasi, hanya membuat ulang kelas. Dengan demikian, data statis apa pun dalam proses tidak akan diatur ulang.
Ted Hopp
2

Langsung mulai Layar Awal dengan FLAG_ACTIVITY_CLEAR_TASKdan FLAG_ACTIVITY_NEW_TASK.

Yijun Li
sumber
2

Saya harus menambahkan Handler untuk menunda keluar:

 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);
Andy7229082
sumber
2

Menggunakan:

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

Ia bekerja mulai dari API level 16 (4.1), saya percaya.

Peter Mortensen
sumber
1

Anda dapat menggunakan startInstrumentationmetode Activity. Anda perlu mengimplementasikan kosong Instrumentationdan menunjuk dalam manifes. Setelah itu, Anda dapat memanggil metode ini untuk memulai kembali aplikasi Anda. Seperti ini:

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);
}

Saya mendapatkan nama kelas Instrumentasi secara dinamis tetapi Anda dapat meng-hardcode-nya. Beberapa menyukai ini:

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

Hubungi startInstrumentationmake reload dari aplikasi Anda. Baca deskripsi metode ini. Tapi itu bisa tidak aman jika bertingkah seperti membunuh aplikasi.

Enyby
sumber
1

Aplikasi yang sedang saya kerjakan harus memberi pengguna kemungkinan untuk memilih fragmen mana yang akan ditampilkan (fragmen diubah secara dinamis saat run-time). Solusi terbaik bagi saya adalah me- restart sepenuhnya aplikasi .

Jadi saya mencoba banyak solusi dan tidak ada yang bekerja untuk saya, tetapi ini:

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

Berharap itu akan membantu orang lain!

hzitoun
sumber
0

coba ini:

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);
}
Muhammad Mubeen
sumber
-1

Dengan perpustakaan Proses Phoenix . Aktivitas yang ingin Anda luncurkan kembali dinamai "A".

Rasa Jawa

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

Rasa Kotlin

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}
Raymond Chenon
sumber
Ini memiliki hasil yang disayangkan membuat putuskan debugger Anda.
DrSatan1
-3

Anda dapat memulai kembali aktivitas Anda saat ini seperti ini:

Pecahan :

activity?.recreate()

Aktivitas :

recreate()

sumber
3
Ini sama sekali bukan apa yang OP ingin lakukan.
Ted Hopp