2014-04-24 56 views
4

我有一個已經實施的應用程序。在這個應用程序。用戶可以從任何其他活動開始任何活動。連接活動的Android最佳做法

我想做什麼:

如果問要啓動的活動已在歷史堆棧存在。應該重新啓動堆棧上的活動,並且應該完成堆棧之前存在的所有活動。

ex:A-> B-> C-> D-> E-> F 現在我們要開始了D. ABCD應該完成並且D的新實例應該開始保持堆棧E-> F-> D

謝謝,

回答

2

我也建議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(); 
} 

現在,OverridestartActivity方法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

+0

的。我使用BroadcastReceiver在增量和ondestroy方法內的基本活動中註冊和取消註冊活動。每次我開始一項活動時,我都會向每個註冊活動發送一條消息,告知將要開始的活動。活動本身檢查它是否具有相同類型的類,並使用setResult將結果發送給每個下面的活動。每個活動都完成自己的開始活動,但不應完成,但只有在主題或語言更改後才能重新加載。 – hasan83

+1

我喜歡你的方法。我會試試這個。我希望你已經註冊了活動來接收清單中的廣播事件,因爲如果我們在代碼中註冊並且暫停時的活動不會收到廣播事件。 – Libin

3

爲什麼不使用片段而不是活動?

+0

因爲應用程序已經實現,變道活動片段需要很多我沒有完全實現你的方法工作 –

3

我的工作在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(); 
        } 
       } 
      } 
     } 
    } 
} 
+1

您的解決方案的作品太友了。但是,另一個更詳細,更多的努力已經完成了他們。感謝你的回答。 – hasan83

+0

不幸的是我不能分裂賞金:) – hasan83

+1

沒關係。很高興幫助:) – Danny

1

如果您打算定位老版本的android,那麼fragment可能不是別人正在處方的最佳選項。因爲Android 3.0或Honeycomb帶來了基本的用戶界面變化,最明顯的就是Fragment API的形式。

在情況下,如果你只是想刪除歷史堆棧活動,完成活動,同時通過意圖的另一項活動是你的需求,然後

您可以從您的AndroidManifest.xml文件實現這一點,只是通過 添加機器人:noHistory =「true」屬性在那些你想