2010-03-18 64 views
57

由於某個未知原因,我無法讓我的應用程序正常離開,這樣當我再次按下主頁按鈕和應用程序圖標時,我會恢復到應用程序中的位置。 我想強制應用程序在第一個Activity上重新啓動。強制應用程序在第一個活動時重新啓動

我想這與onDestroy()或onPause()有關,但我不知道該怎麼做。如果你想總是在你想設置android:clearTaskOnLaunch爲true的根系活力

回答

128

下面是使用PackageManager重新啓動在一個通用的方法您的應用程序的例子:

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

它幫助我。謝謝。我用這樣,「嘗試{ \t \t \t \t \t \t \t \t意圖我; \t \t \t \t \t \t \t \t I = getBaseContext()getPackageManager() \t \t \t \t \t \t \t \t .getLaunchIntentForPackage( getBaseContext()。getPackageName()); \t \t \t \t \t \t \t \t i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); \t \t \t \t \t \t \t \t startActivity(ⅰ); \t \t \t \t \t \t \t}趕上(的NameNotFoundException E){ \t \t \t \t \t \t \t \t e.printStackTrace(); \t \t \t \t \t \t \t} – tknv 2011-01-19 06:06:37

+0

工程就像一個魅力。 – PapaFreud 2013-02-01 12:35:25

+0

這種方法的一個問題。 在舊的活動堆棧獲取onDestroy之前調用新活動的onCreate – AAverin 2014-03-13 11:35:40

12

與home鍵:

android:clearTaskOnLaunch 
在清單

@Override 
public void onRestart(){ 
    onCreate(); 
} 

這做的伎倆......(當它被放在WHI的onResume優於

ch會在每次啓動應用程序時調用,即使是第一次,也會導致雙重顯示)

+1

是的,我試過,但後來當我再次點擊該圖標似乎在恢復,而不是的onCreate ... 調用,這意味着我得到一個屏幕沒有任何的開始 – Sephy 2010-03-18 17:07:05

+19

我的方法爲什麼是這個答案標作爲接受的? – 2013-03-03 16:09:08

+1

或以編程方式將Intent.FLAG_ACTIVITY_CLEAR_TASK標誌添加到意圖。 – Davidea 2015-05-17 14:04:40

-1

經過艱苦的思考和檢驗我終於打電話給我的活動重新正道根啓動應用程序是離開的時候

+2

聽起來很糟糕。你應該只需要'clearTaskOnLaunch'屬性。你最初如何啓動你的應用程序?使用ADT工具直接從Eclipse獲得?如果是這樣,那就意味着應用程序沒有從Eclipse正確啓動。它從那以後就被修復了。 – 2010-04-15 18:55:17

+0

是的,直接從日食。但我試過只有clearTaskOnLaunch,並且我努力讓它工作... – Sephy 2010-04-16 09:22:30

+0

嗨如何添加'onRestart()'方法。你能給一個片段嗎?謝謝 – 2011-06-24 12:38:29

2

FLAG_ACTIVITY_CLEAR_TOP會執行您需要執行的操作嗎?

Intent i = new Intent(getBaseContext(), YourActivity.class); 
      i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      startActivity(i); 
7
android:clearTaskOnLaunch="true" 
android:launchMode="singleTask" 

使用這個屬性在起點類(第一項活動)清單文件。

25

標記爲「答案」的解決方案有效,但有一個缺點對我至關重要。 使用FLAG_ACTIVITY_CLEAR_TOP,您的目標活動將在您的舊活動堆棧收到onDestroy之前調用onCreate。雖然我已經在onDestroy中清除了一些必要的東西,但我不得不努力工作。

這是爲我工作的解決方案:

public static void restart(Context context, int delay) { 
    if (delay == 0) { 
     delay = 1; 
    } 
    Log.e("", "restarting app"); 
    Intent restartIntent = context.getPackageManager() 
      .getLaunchIntentForPackage(context.getPackageName()); 
    PendingIntent intent = PendingIntent.getActivity(
      context, 0, 
      restartIntent, Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    manager.set(AlarmManager.RTC, System.currentTimeMillis() + delay, intent); 
    System.exit(2); 
} 

的想法是火焰通過AlarmManager一個的PendingIntent那將是稍後調用,使老年活動組一些時間來清理。

+1

爲什麼不直接調用Activity的'finish()'方法而不是'System.exit'?該文檔說:「當你的活動完成並且應該關閉時,打電話給這個。」 – oligofren 2014-03-14 13:22:31

+1

我剛剛意識到這是由於該方法是靜態的,因此無法調用任何非靜態方法,如「finish」。我只是'重新啓動'非靜態,並取而代之的是System.exit調用。 – oligofren 2014-03-14 13:27:59

+0

經過測試,我發現使用finish()會導致我的應用在啓動時掛起,而System.exit可以正常工作。 – oligofren 2014-03-14 14:25:13

2

馬克的答案很好,除了我的情況,我的主要活動有一個singleTop launchMode。一旦我運行這個意圖,然後導航到新的活動,並按設備上的主頁按鈕,然後從應用程序圖標再次啓動我的應用程序,我最終創建一個主要活動的新實例,與我以前的活動在後面的堆棧。根據this question這是因爲意圖不匹配。看看adb dumpsys activity,我從標準的android啓動器看到,包是空的,而當我按照Marc的建議做時,intent包就是我的包的名稱。這種差異導致它們不匹配,並在再次點擊應用程序圖標並且主要活動不在最上時開始新實例。

但是,在Kindle上的其他發射器上,包設置在啓動器的意圖,所以我需要一個通用的方式來處理髮射器。我添加靜態方法像這樣:

static boolean mIsLaunchIntentPackageNull = true;  

public static boolean isLaunchIntent(Intent i) { 
    if (Intent.ACTION_MAIN.equals(i.getAction()) && i.getCategories() != null 
      && i.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 
     return true; 
    } 

    return false; 
} 

public static void handleLaunchIntent(Intent i) { 
    if (isLaunchIntent(i)) { 
     if (i.getPackage() != null) { 
      mIsLaunchIntentPackageNull = false; 
     } 
     else { 
      mIsLaunchIntentPackageNull = true; 
     } 
    } 
} 

有歸家的機制是這樣的:

Intent intentHome = appContext.getPackageManager() 
      .getLaunchIntentForPackage(appContext.getPackageName()); 
    intentHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

    // need to match launcher intent exactly to avoid duplicate activities in stack 
    if (mIsLaunchIntentPackageNull) { 
     intentHome.setPackage(null); 
    } 
    appContext.startActivity(intentHome); 

然後在我的清單中定義的主要活動,我加入這一行:

public void onCreate(Bundle savedInstanceState) { 
    [class from above].handleLaunchIntent(getIntent()); 

這對kindle和我的手機適用於我,並允許我正確地重置應用程序而不添加主要活動的另一個實例。

1

這個工作對我來說:

Intent mStartActivity = new Intent(ctx.getApplicationContext(), ActivityMain.class); 


    mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    mStartActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
     mStartActivity.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK 

    int mPendingIntentId = 123456; 


    PendingIntent mPendingIntent = PendingIntent.getActivity(ctx, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT); 
    AlarmManager mgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE); 
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, mPendingIntent); 

    ActivityManager manager = (ActivityManager) ctx.getApplicationContext().getSystemService(ctx.getApplicationContext().ACTIVITY_SERVICE); 
    List<ActivityManager.RunningAppProcessInfo> activityes = ((ActivityManager)manager).getRunningAppProcesses(); 




    ((Activity)ctx).moveTaskToBack(true); 
    manager.killBackgroundProcesses("com.yourpackagename"); 
    System.exit(0); 
2

FLAG_ACTIVITY_CLEAR_TOP並沒有爲我工作,因爲我必須支持2.3.3。我的第一個解決方案是:

Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); 
    intent.addFlags(Build.VERSION.SDK_INT >= 11 ? Intent.FLAG_ACTIVITY_CLEAR_TASK : Intent.FLAG_ACTIVITY_CLEAR_TOP); 
context.startActivity(intent); 

這幾乎可以工作,但不完全。

因爲我有一個基本的Activity,我添加了一個關閉所有我的運行活動的kill廣播。

public abstract class BaseActivity extends AppCompatActivity { 

    private static final String ACTION_KILL = "BaseActivity.action.kill"; 
    private static final IntentFilter FILTER_KILL; 
    static { 
     FILTER_KILL = new IntentFilter(); 
     FILTER_KILL.addAction(ACTION_KILL); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     registerReceiver(killReceiver, FILTER_KILL); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unregisterReceiver(killReceiver); 
    } 

    private final BroadcastReceiver killReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      finish(); 
     } 
    }; 

    public void killApp(){ 
     sendBroadcast(new Intent(ACTION_KILL)); 
    } 
} 

我所有的活動,從這個類擴展,所以

((BaseActivity)getActivity()).killApp(); 
startActivity(new Intent(getActivity(), StartActivity.class)); 

重新啓動應用程序。測試genymotion v10,v16,v21和Nexus 5與v22。

編輯:這不會刪除一個活動,如果它在發送意圖時被銷燬。我仍在尋找解決方案。

2

以下代碼適用於我,它可以完全重新啓動完整的應用程序!

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); 
+0

mPendingIntentId的值是什麼意思?看起來像一個特別神奇的數字 - 它只是一個任意的整數? – aaaidan 2017-11-22 21:38:29

+0

這只是一個任意數字,你可以使用任何隨機整數。這是PendingIntent類中的消息編號。 – 2017-11-28 04:02:20

相關問題