Android:如何通过小部件防止启动多个活动实例?

11

重现问题的步骤:

  • 用户启动我的应用程序(根 Activity 的名称为“mainActivity”)=> mainActivity 的实例 A
  • 用户按下主屏幕按钮(mainActivity 在后台运行)
  • 用户安装与此应用程序相关的小部件
  • 他点击小部件 => 显示 mainActivity 的新实例(实例 B)
  • 他点击返回按钮:用户返回到活动 A(我不想要这个!应该关闭活动 B(实际上,整个应用程序都应该关闭))

你知道如何避免这个问题吗?(我在stackoverflow上看到了一些类似的问题,但不完全是我想要的)

谢谢!!!

代码:

public class MyWidgetProvider extends AppWidgetProvider {

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    // Build the intent to call the service//

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

    Intent openAppIntent = new Intent(context.getApplicationContext(), MainActivity.class);
    openAppIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
    PendingIntent openAppPendingIntent = PendingIntent.getActivity(context, 0, openAppIntent, 0);


    remoteViews.setOnClickPendingIntent(R.id.widgetLinearLayout, openAppPendingIntent);

//// ETC…///

    }
3个回答

4

尝试使用:

openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

这里提供了更多相关信息。


你也可以使用:

openAppIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

description here.


谢谢NeTeInStEiN和Craigy,但我仍然遇到同样的问题...还有其他想法吗? - toto_tata
每当您打开包括在清单中的活动(涵盖从应用程序抽屉启动)时,都需要设置标志。这是正确的答案,因此另一个想法将无法帮助您。 - Kuffs
嗨,Kuffs。我尝试在我的onUpdate方法中添加openAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)和openAppIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT),但它不起作用。我问题描述中的不同步骤仍然存在。我错在哪里?顺便问一下,“包括在清单中”是什么意思?谢谢。 - toto_tata
他的意思(我认为)是在清单文件中定义一个launchMode。http://developer.android.com/guide/topics/manifest/activity-element.html#lmode - neteinstein

2
我建议使用:
openAppIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

这将重用已经存在的Activity,并调用onNewIntent。您可以根据需要从那里更新UI。
要获取更多参考,请查看:Developer.android.com - FLAG ACTIVITY SINGLE TOP 编辑
启动器Activity是在AndroidManifest.xml中具有以下意图过滤器的Activity。
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

这些标志将无法工作,如果小部件启动了一个新的任务,该任务具有自己的活动堆栈。
我认为最好阅读这篇文章Developer.android.com - ACTIVITY TASK DESIGN 如果您找到任何信息,请告诉我们。

谢谢Gyuri,但我仍然有同样的问题...还有其他想法吗? - toto_tata
你的 MainActivity 是启动器活动吗? - Gyuri Majercsik
MainActivity 是应用程序从头开始启动时启动的活动;所以,是的,我想这就是你所说的“启动器活动”。问题是,当应用程序从头开始启动时,会先启动 MainActivity 的第一个实例,然后在我单击小部件时,会启动第二个实例。然后我有两个重叠的实例;当我单击返回按钮时,我从“小部件 MainActivity”返回到“启动器 MainActivity”。有什么想法吗?非常感谢! - toto_tata
请查看我的回答框中的回复。 - Gyuri Majercsik

1

我通过在清单文件中添加以下属性成功地防止了多个活动的实例:

android:launchMode="singleInstance"

这基本上告诉Android,该活动是“高地人”(“只能有一个”),并将防止其创建多个实例。每当打开相关的活动时,Android将要么将现有实例置于前台,要么在某些情况下销毁并重新创建当前实例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接