Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android连接活动的最佳实践_Android_Memory Management_Navigation_Android Activity - Fatal编程技术网

Android连接活动的最佳实践

Android连接活动的最佳实践,android,memory-management,navigation,android-activity,Android,Memory Management,Navigation,Android Activity,我有一个已经实现的应用程序。在这个应用程序中。用户可以从任何其他活动开始任何活动 我想做的是: 如果请求启动的活动已存在于历史堆栈中。应该重新启动堆栈上的活动,并且应该完成堆栈中它之前存在的所有活动 例:A->B->C->D->E->F 现在我们想要开始D。A B C D应该完成,并且D的一个新实例应该开始保持在堆栈E->F->D上 谢谢,为什么不使用片段而不是活动?对于这一点,您有片段: 我还想推荐使用导航抽屉实现 导航抽屉: 例如: 对于这个需求,我也建议使用片段,但由于您的应用程序已经实

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

我想做的是:

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

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


谢谢,

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

对于这一点,您有片段:

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

导航抽屉:

例如:


对于这个需求,我也建议使用
片段
,但由于您的应用程序已经实现,您可以使用这种方法

 all the activities that exists before it in the stack should be finished.
Android
不提供任何标志来清除下面所有的
活动
,比如使用
clearTop
清除top
活动
。如果我们有
clearBottom
:),这会很简单

嗯。如果您的目标
Android API版本来自16
,此方法将以优化的方式提供帮助。对于另一个较低版本,您需要单独完成每个
活动

创建一个
BaseActivity
,它将把所有
Activity
实例添加到
HashMap
(类似于将
片段添加到后堆栈中)。但这只是为了记住堆栈中的
活动。您还可以使用
ActivityManager.RunningTaskInfo
检查堆栈中的
Activities
,但我不想让它变得更复杂

声明一个静态变量。我更喜欢在我的
应用程序类中做

 public class MyApp extends Application {
    public static HashMap<String , CommonActivity > mBackStackActivities
                   = new HashMap<String, CommonActivity>();
  }
并且,当
活动销毁时将其删除

@Override
protected void onDestroy(){
    MyApp.mBackStackActivities.remove(getComponentName().getClassName());
    super.onDestroy();
}
现在,
覆盖
基本活动类中的
startActivity
方法,并在启动
活动时检查
活动
是否存在于
HashMap
中。如果存在
finishafinity`,则使用
finishafinity`,完成以下所有
Activity

 @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
,默认情况下,所有
活动
将具有相同的关联名称(包名称)。如果您希望涵盖您的所有
活动
,则可以保留此选项

    <activity
        android:name="com.example.app.activities.MainActivity"
        android:label="@string/title_activity_common"
        android:taskAffinity="@string/task_affinity_name">
    </activity>

我在Tooleap SDK上工作,而且我还需要同时管理多个活动。这里有一些类似于我所做的事情。 您可以创建自己的活动管理器类。 每次活动开始时,它都会向活动管理器注册,如下所示:

public class ActivityA extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        myActivityManager.register(this)
    }
}
activity manager类将保存所有已启动活动的数组,并对以前调用的每个活动调用finish,然后将它们从数组中删除。请注意,您应该保留对活动类的weakreference,以防止上下文泄漏

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();
                   }
               }
            }
        }
    }
}
公共类MyActivityManager{
静态列表sManagedActivityInstances=new ArrayList();
静态无效寄存器(活动){
如果(IsActivityContainedList()){
for(Iterator Iterator=sManagedActivityInstances.Iterator();Iterator.hasNext();)
{
WeakReference activityWeakRef=iterator.next();
if(isSameActivity(activity,activityWeakRef))
{
iterator.remove();
如果(activityWeakRef!=null){
activityWeakRef.finish();
}
}
}
}
}
}

如果您计划针对较旧版本的android,那么碎片可能不是其他人开出的最佳选择。因为Android 3.0或蜂巢(Honeycomb)带来了基本的用户界面变化,最显著的形式是片段API

在这种情况下,如果您只想从历史堆栈中删除活动并在将意图传递给另一个活动时完成该活动,那么

您可以从AndroidManifest.xml文件实现这一点,只需 在您想要的属性中添加android:noHistory=“true”属性


因为应用程序已经实现,所以从活动到片段的更改需要大量的工作。我并没有完全实现您的方法。我使用BroadcastReceiver在increate和ondestroy方法中注册和注销基本活动中的活动。每次启动活动时,我都会向每个注册的活动发送一条消息,其中包含将要启动的活动。活动本身检查是否具有相同类型的类,并使用setResult将结果发送到下面的每个活动。每一个活动都会自动完成,直到开始活动。开始活动不应该完成,但只有在主题或语言发生变化时才会重新加载。我喜欢你的方法。我试试这个。我希望您已经在清单中注册了接收广播事件的活动,因为如果我们在代码中注册,那么暂停中的活动将不会接收广播事件。您的解决方案也很有效。但是,另一个更详细,他们已经做了更多的努力。谢谢你的回答。不幸的是我不能分享赏金:)没关系。很乐意帮忙:)
public class ActivityA extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        myActivityManager.register(this)
    }
}
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();
                   }
               }
            }
        }
    }
}