我有一個已經實施的應用程序。在這個應用程序。用戶可以從任何其他活動開始任何活動。連接活動的Android最佳做法
我想做什麼:
如果問要啓動的活動已在歷史堆棧存在。應該重新啓動堆棧上的活動,並且應該完成堆棧之前存在的所有活動。
ex:A-> B-> C-> D-> E-> F 現在我們要開始了D. ABCD應該完成並且D的新實例應該開始保持堆棧E-> F-> D
謝謝,
我有一個已經實施的應用程序。在這個應用程序。用戶可以從任何其他活動開始任何活動。連接活動的Android最佳做法
我想做什麼:
如果問要啓動的活動已在歷史堆棧存在。應該重新啓動堆棧上的活動,並且應該完成堆棧之前存在的所有活動。
ex:A-> B-> C-> D-> E-> F 現在我們要開始了D. ABCD應該完成並且D的新實例應該開始保持堆棧E-> F-> D
謝謝,
我也建議Fragment
這一要求,但因爲你的應用程序已經實現,你可以用這個方法去。
all the activities that exists before it in the stack should be finished.
Android
不提供任何標誌,以清除所有下面Activities
喜歡使用clearTop
頂部結算Activities
。這將是簡單的,如果我們有clearBottom
:)
好的。如果您的定位爲Android API version from 16
,則此方法將以優化的方式提供幫助。對於其他較低版本,您需要分別完成每個Activity
。
創建一個BaseActivity
它將所有Activity
實例添加到HashMap
(類似於添加Fragments to back Stack
)。但是這裏只是記住堆棧中的Activities
。您還可以使用ActivityManager.RunningTaskInfo
檢查堆棧中的Activities
,但我不想讓它更復雜。
聲明一個靜態變量。我更喜歡在我的Application class
中做。
public class MyApp extends Application {
public static HashMap<String , CommonActivity > mBackStackActivities
= new HashMap<String, CommonActivity>();
}
現在,當一個Activity created
其實例添加到HashMap
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp.mBackStackActivities.put(getComponentName().getClassName(), this);
}
而且,刪除它時,Activity destroy
@Override
protected void onDestroy(){
MyApp.mBackStackActivities.remove(getComponentName().getClassName());
super.onDestroy();
}
現在,Override
的startActivity
方法base Activity class
和當Activity
開始check if the
活動exists in
HashMap . If exists
finish all the below
活動using
finishAffinity`。
@Override
public void startActivity(Intent intent) {
if(MyApp.mBackStackActivities
.containsKey(intent.getComponent().getClassName())){
if(android.os.Build.VERSION.SDK_INT >= 16) {
Activity activity = MyApp.mBackStackActivities.get(intent.getComponent().getClassName());
// finish the activity as well as all the below Activities.
activity.finishAffinity(); // supported from API 16
}else {
// loop through all the below activity and finish it
}
}
super.startActivity(intent);
}
最後,如果你需要設置android:taskAffinity
在清單的要求Activities
,默認情況下所有的Activities
都會有相同的親和力名(包名)。如果您想要覆蓋您的所有Activities
,您可以離開。
<activity
android:name="com.example.app.activities.MainActivity"
android:label="@string/title_activity_common"
android:taskAffinity="@string/task_affinity_name">
</activity>
在字符串XML
<string name="task_affinity_name">com.example.app.affinity</string>
注:如上所述,對於較低的版本說,你需要完成每個Activity
Individually`
在這裏找到完整的源https://gist.github.com/androidbensin/7d9261fd148c15575dd1
爲什麼不使用片段而不是活動?
因爲應用程序已經實現,變道活動片段需要很多我沒有完全實現你的方法工作 –
我的工作在Tooleap SDK上,我還需要一次管理多個活動。這與我所做的相似。 您可以創建自己的活動管理器類。
public class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
myActivityManager.register(this)
}
}
您的行爲管理類將保存所有的啓動活動的數組,並調用完成每一個以前被稱爲活動,並將其從: 每次你的活動開始時間,它與你的行爲管理這樣登記陣列。請注意,您應該將WeakReferences放在您的Activity類中,以防止上下文泄漏。
public class MyActivityManager {
static List<WeakReference<Activity>> sManagedActivityInstances = new ArrayList<WeakReference<Activity>>();
static void register(Activity activity) {
if (isActivityContainedInList()) {
for (Iterator<WeakReference<Activity>> iterator = sManagedActivityInstances.iterator(); iterator.hasNext();)
{
WeakReference<Activity> activityWeakRef = iterator.next();
if (isSameActivity(activity, activityWeakRef))
{
iterator.remove();
if (activityWeakRef != null) {
activityWeakRef.finish();
}
}
}
}
}
}
如果您打算定位老版本的android,那麼fragment可能不是別人正在處方的最佳選項。因爲Android 3.0或Honeycomb帶來了基本的用戶界面變化,最明顯的就是Fragment API的形式。
在情況下,如果你只是想刪除歷史堆棧活動,完成活動,同時通過意圖的另一項活動是你的需求,然後
您可以從您的AndroidManifest.xml文件實現這一點,只是通過 添加機器人:noHistory =「true」屬性在那些你想
的。我使用BroadcastReceiver在增量和ondestroy方法內的基本活動中註冊和取消註冊活動。每次我開始一項活動時,我都會向每個註冊活動發送一條消息,告知將要開始的活動。活動本身檢查它是否具有相同類型的類,並使用setResult將結果發送給每個下面的活動。每個活動都完成自己的開始活動,但不應完成,但只有在主題或語言更改後才能重新加載。 – hasan83
我喜歡你的方法。我會試試這個。我希望你已經註冊了活動來接收清單中的廣播事件,因爲如果我們在代碼中註冊並且暫停時的活動不會收到廣播事件。 – Libin