Android最佳实践连接活动

时间:2014-04-24 11:35:10

标签: android memory-management navigation android-activity

我有一个已经实施的应用程序。在这个程序中。用户可以从任何其他活动开始任何活动。

我想做什么:

如果要求启动的活动已存在于历史堆栈中。应该重新启动堆栈上的活动,并且应该完成堆栈中存在的所有活动。

例如:A-> B-> C-> D-> E-> F 现在我们要开始D.应该完成一个B C D并且应该在堆栈上开始新的D实例E-> F-> D

谢谢,

5 个答案:

答案 0 :(得分:5)

准确地说,你有片段:

我还想推荐使用导航抽屉实现。

导航抽屉: Navigation drawer link

碎片示例:

Fragments in android developers

答案 1 :(得分:3)

为什么不使用片段而不是活动?

答案 2 :(得分:3)

我参与了Tooleap SDK,我还需要同时管理多个活动。这与我所做的类似。 您可以创建自己的Activity manager类。 每次您的活动开始时,它都会向您的活动经理注册,如下所示:

public class ActivityA extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        myActivityManager.register(this)
    }
}

您的活动管理器类将保存所有已启动活动的数组,并为之前调用的每个活动调用finish,并将其从阵列中删除。请注意,您应该将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();
                   }
               }
            }
        }
    }
}

答案 3 :(得分:2)

我还建议Fragment这个要求,但由于你的应用程序已经实现,你可以采用这种方法。

 all the activities that exists before it in the stack should be finished.

Android未提供任何标记,可使用Activities清除以下所有Activities清除热门clearTop。如果我们有clearBottom:)

,那就简单了

确定。如果您的定位Android API version from 16,此方法将以优化的方式提供帮助。对于其他较低版本,您需要单独完成每个Activity

创建BaseActivity,将所有Activity实例添加到HashMap(类似于添加Fragments to back Stack)。但这里只是记住堆栈中的Activities。您还可以使用Activities检查堆栈中的ActivityManager.RunningTaskInfo,但我不想让它更复杂。

声明一个静态变量。我更喜欢在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以及启动Activitycheck if the活动exists in HashMap . If exists光洁度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

在此处找到完整的来源https://gist.github.com/androidbensin/7d9261fd148c15575dd1

答案 4 :(得分:1)

如果您计划定位旧版Android,那么片段可能不是其他人开出的最佳选择。因为Android 3.0或Honeycomb带有基本的用户界面更改,最明显的是Fragment API的形式。

如果您只是想从历史堆栈中删除活动并完成活动,同时将意图传递给另一个活动是您的需要,那么

  

您可以通过AndroidManifest.xml文件实现此目的   添加android:noHistory =&#34; true&#34;属于你想要的人