2012-12-20 137 views
5

有什麼更好的方法來檢查活動是否仍在堆棧中以便回撥?如何檢查活動是否仍在堆棧中?

Intent i = new Intent(getApplicationContext(),MyClass.class); 
startActivity(i); 
+2

爲什麼照顧?這取決於Android。 – m0skit0

+0

看到這篇文章http://stackoverflow.com/questions/5975811/how-to-check-if-an-activity-is-the-last-one-in-the-activity-stack-for-an-applica/ 6242122#6242122 –

+0

因爲我有一個活動誰需要params爲了從xml文件中檢索數據,所以我想從堆棧中調用它來避免從文件傳遞params和gettinig數據因爲這對於用戶來說是痛苦的每次看到ProgressDialog。 – leonidas79

回答

-1

看那ActivityManager API

要獲得ActivityManager的一個實例,使用此代碼:

ActivityManager mngr = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 
+8

如果有更多的細節,我應該使用ActivityManager來檢查活動是否在堆棧上,這將是非常好的。只是「閱讀這個類的文檔」是不夠好的國際海事組織。 – Tapemaster

+0

他指的是ActivityManager.getRunningTasks,但它在棒棒糖中已被棄用。 – grebulon

1

我很驚訝這(種)問題(S)是如何不得人心的。

讓我從溶液中開始第一:
由於ActivityManager.getRunningTasks因爲API 21已被棄用,
我們必須找到另一種方式來得到什麼活動都在堆棧中。我意識到我們實際上可以實現我們自己的「堆棧」!

我宣佈MyOwnApplication一個ArrayList:

private ArrayList<Class> runningActivities = new ArrayList<>(); 

而且加入公共的方法來訪問和修改此列表:

public void addThisActivityToRunningActivityies (Class cls) { 
    if (!runningActivities.contains(cls)) runningActivities.add(cls); 
} 

public void removeThisActivityFromRunningActivities (Class cls) { 
    if (runningActivities.contains(cls)) runningActivities.remove(cls); 
} 

public boolean isActivityInBackStack (Class cls) { 
    return runningActivities.contains(cls); 
} 

BaseActivity所有活動擴展它:

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     ((MyOwnApplication)getApplication()).addThisActivityToRunningActivityies(this.getClass()); 
    } 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    ((MyOwnApplication)getApplication()).removeThisActivityFromRunningActivities(this.getClass()); 
} 

然後你可以很容易地使用isActivityInBackStack來檢查。

爲什麼這是必要的?

是的,當然,大多數情況下可以通過使用意圖標誌和正確的導航。
但有這樣的用例,我認爲這應該是常見的,我沒有簡單地通過使用意向標誌找到解決方案。

假設我有一個應用程序幾乎在每個活動中都有一個導航抽屜。
我從MainActivity導航到ActivityA,然後從ActivityA創建了ChildActivityB。請注意,ActivityA不是ChildActivityB的母公司,因爲ChildActivityB可以從其他活動如通知中打開。

請注意,ChildActivityB也有一個抽屜。我可以通過抽屜導航到ActivityA,而不是按下或返回按鈕。現在,想象你循環這樣的過程:活動A - > ChildActivity B - >抽屜 - >活動A - > ChildActivityB - >抽屜 - >活動A ..... 無限活動將在後臺創建。
要解決這樣的行爲,我們需要使用意向標誌:

(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); 

到目前爲止好。 但是,我通過使用overridePendingTransition()來定製活動轉換動畫。我注意到,如果我將上述意圖標誌與overridePendingTransition(),一起放在一起,動畫會出現故障,因爲由於標誌Intent.FLAG_ACTIVITY_CLEAR_TOP,動畫在動畫的中間被破壞。

現在,如果我能夠檢測ActivityA是否在返回堆棧與否,行爲將是完美的:

private void navigateToDrawerItems(Class cls) { 
    drawerLayout.closeDrawer(GravityCompat.END); 
    Intent intent = new Intent(this, cls); 
    if (((MyOwnApplication)getApplication()).isActivityInBackStack(cls)) { 
     intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     startActivity(intent); 
    } else { 
     startActivity(intent); 
     overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out); 
    } 
} 
+0

提及導航用例。我將補充一點,雖然這是導航抽屜的有效用例,但它對於選項卡欄導航(又名BottomNavigationView)更爲重要。 Android沒有FLAG_ACTIVITY_REORDER_TO_FRONT用於片段疊加。因此,如果您想在標籤之間切換時輕鬆保持狀態並且不會耗盡內存,則使用活動標籤而不是片段標籤是唯一的方法。 – flopshot

相關問題