我在网上阅读了android开发者指南和一些文章,我仍然对此感到困惑singleTask launchmode.让我们举一个例子:
用户启动App1,android启动一项新任务.假设App1按以下顺序创建活动:
ActivityA -> ActivityB -> ActivityC
Run Code Online (Sandbox Code Playgroud)
这就是task1的样子.
然后用户点击home buttom并选择启动App2,这样task1进入后台并且android启动一个新任务:task2,用户执行的操作:
ActivityD -> ActivityE
Run Code Online (Sandbox Code Playgroud)
现在让我们说ActivityE尝试启动ActivityB,并ActivityB拥有launchmode singleTask.
我的理解是task1再次来到前端,task2进入后台.而task1现在看起来像这样:
ActivityA -> ActivityB
Run Code Online (Sandbox Code Playgroud)
意思是:
在ActivityC将从任务1被移除并ActivityB变得顶端活动.
如果用户现在点击"返回"按钮,他将来到ActivityAtask1而不是返回ActivityEtask2
我对吗?
谢谢
我正在努力将我的应用程序限制为单个实例.目前,如果用户按下主屏幕退出应用程序,然后在外面执行某些操作并再次单击应用程序的图标,则会启动应用程序的第二个实例.
这是我的完整清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mydomain.qfa"
android:versionCode="4"
android:versionName="1.3">
<uses-sdk android:minSdkVersion="7"
android:targetSdkVersion="13"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:debuggable=["false"]
android:testOnly=["false"]
android:icon="@drawable/icon.png"
>
<activity
android:name="com.mydomain.qfa"
android:launchMode=["singleTask"]
android:alwaysRetainTaskState="true"
android:icon="@drawable/icon.png"
>
</activity>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
它是一个单一的活动应用程序(基本上没有活动定义)在主JQM页面上,我有类似这样的条目:
<div data-role="page" id="HomePage">
<div data-theme="d" data-role="header" data-position="fixed" style="padding-bottom: 0px;" data-tap-toggle="false">
<div data-role="navbar">
<div data-role="content" class="MainContent" style="overflow:hidden; padding-top: 0px;">
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我,如果我的清单是正确的,我是否应该使用
android:name="com.mydomain.qfa"
Run Code Online (Sandbox Code Playgroud)
还是应该是其他类似的东西
android:name="com.mydomain.qfa.HomePage"?
Run Code Online (Sandbox Code Playgroud)
要么
android:name="com.mydomain.qfa.MainContent"?
Run Code Online (Sandbox Code Playgroud)
提前致谢.
这张图片非常有助于理解singleTask从这里获取的洗衣模式提供的功能
但是,在同一个应用程序的情况下,我理解这一点,如果两个任务属于两个不同的应用程序,我会遇到问题
令人困惑的场景(虚构),
当我输入我的电子邮件内容时,我切换到一些聊天应用程序,应用程序崩溃了,并为我提供了通过电子邮件向开发人员报告问题的选项,现在当我选择" 报告 "时,我的电子邮件应用程序(这是将打开相同的默认电子邮件应用程序).
现在,由于电子邮件应用程序的根活动是单一任务,我写的内容是否会对我可见?
最重要的是这次,任务/堆栈属于两个不同的应用程序.
我有一个几乎完成的应用程序与非平凡的活动结构.有与此应用程序关联的推送通知,并且无论应用程序是前台/后台/未激活,选择通知条目都应该启动特定活动.
如果应用程序未处于活动状态,我可以成功启动应用程序并自动导航到相应的部分.但是,当应用程序处于活动状态时,我遇到了问题.我将提出问题的简化版本,以传达问题的本质,我将根据需要发布我的应用程序的活动结构和相关代码的详细信息(实际上,现在正在处理).
所以,我的应用程序的活动堆栈(大大简化)看起来像这样:
A - > B - > X.
其中A,根活动,是一个登录页面; B是"主页",X是可以从主页启动的几个活动之一(但一次只有一个活动;因为这些只能从B开始).
当选择通知时,我需要应用程序自动导航到B,无论事先处于什么状态 - 无论是[A],[A - > B],[A - > B - > X]还是[](应用程序未激活).
我的通知将Intent传递给活动A.我尝试过使用CLEAR_TOP和NEW_TASK标志,但没有.目前有launchmode = singleTask.这样做,我想我正在解决所有可能的现有堆栈配置并将它们减少到[A].Intent还带有一个额外的内容,它将其标识为来自通知,而不是通常的发布.
活动A,在识别出从通知发送的Intent时(它可以在onCreate()和onNewIntent()中执行此操作),将Intent发送到Activity B.此Intent包含CLEAR_TOP和SINGLE_TOP.B有launchmode = singleTop.
95%的时间,这可以按照需要工作,按下通知后,应用程序的堆栈为[A - > B].大约5%的时间,应用程序不知何故最终得到一堆[A - > B - > B].
关于这里发生了什么,或者我做错了什么的任何想法?
如果事实证明这是一个非常重要的问题,我会发布更多细节.事实上,现在发布更多细节......
~~~~~~~~~~~~~~~~~~~~~~~详细信息~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
单步执行调试器会显示,每次A将其意图发送给B时,现有的B实例都是onDestroy(),然后才能进入onCreate(),然后调用onNewIntent().这对我来说似乎很奇怪,并且暗示我误解了我正在使用的标志(CLEAR_TOP和SINGLE_TOP),或者其他东西正在干扰它们.
我没有成功地在调试中重现错误的堆栈结构.不确定是不是因为它没有在调试中发生,或者我没有尝试过足够的次数.
意图代码:
在C2DM接收器服务中:
protected void onMessage(Context context, Intent intent) {
int icon = R.drawable.some_drawable;
CharSequence tickerText = "blah";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
//Context context = getApplicationContext(); //Don't …Run Code Online (Sandbox Code Playgroud) 我开发了一个简单的应用程序,它解释了我注意到的Android 4.4.X设备上的一些奇怪的行为.
假设我想要进行2次"主要"活动,其中第一次活动表示"Hello"(通过启动"HelloActivity")每秒恢复一次,第二次android:launchMode="singleTask" android:taskAffinity=".MyAffinity"定义.第二个是由第一个开始的.
清单非常简单:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.affinitylaunchmodebugtest.MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="HELLO"
android:name="com.example.affinitylaunchmodebugtest.HelloActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
</activity>
<activity
android:label="AffinityTestActivity"
android:name="com.example.affinitylaunchmodebugtest.AffinityTestActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:taskAffinity=".MyAffinity">
</activity>
</application>
Run Code Online (Sandbox Code Playgroud)
MainActivity在按钮单击时启动AffinityTestActivity并记录其生命周期.它还会在每次恢复时启动HelloActivity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println(this+" onCreate");
super.onCreate(savedInstanceState);
Button b = new Button(MainActivity.this);
b.setText("START AFFINITY TEST ACTIVITY");
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View …Run Code Online (Sandbox Code Playgroud) 我已阅读Google Android Developer页面,但任务的概念(http://developer.android.com/guide/components/tasks-and-back-stack.html)确实让我感到困惑.
在我读到SingleTask和SingleInstance之后,我变得更加困惑.
我想通过一些例子提出一些问题,希望我能从这些问题中得到更好的理解:
假设我有2个应用程序A和B,A有x,y,z活动; B有1,2,3个活动:
假设他们的启动模式是标准(不使用任何意图标志).而x是app A的主要活动; 1是应用程序B的主要活动.
1)启动应用程序A,然后x-> y - > 1,按主页按钮,再次启动应用程序A,我们将看到活动y或1?
2)启动app A然后x - > 1 - > y - > 2 - > z - > 3,按home键,启动app A,它将包含所有活动(x - > 1 - > y - > 2 - > z - > 3),还是只包含x - > y - > z?如果我们现在推出应用B怎么样?应用B包含哪些活动?
现在让我们说活动1,2,3是SingleTask; x,y,z仍为标准:
3)启动应用程序A,然后x - > y - > 1 - > 2,按主页按钮,启动应用程序A,它将包含x - > y或它包含x - > y - > 1 - > …
我不知道如何处理这个Android问题.简而言之,我的2个应用程序之间的流程如下:

我想用以下组件创建一个任务:

我尝试更改BillingActivity + PaymentActivity "launchMode":
singleInstance
为它们创建了一个新任务.按下返回按钮(或调用finish()方法)时,用户将按预期重定向到上一个活动.问题:"StartActivityForResult"不能在多个任务之间使用(立即调用onActivityResult).
SingleTask
在BillingActivity中按下返回按钮(或调用finish()方法)时,用户将被重定向到Top2Activity(在后台任务中).
我试图解决它已经失去了超过48小时.我很感激你的帮助.我可以根据需要发布代码.
谢谢
-----------编辑2015-02-02
按照David的建议,我删除了所有特殊启动模式:
TOP2Activity(背景):
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/title_activity_main"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" >
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="xxx" />
<data android:host="xxx" …Run Code Online (Sandbox Code Playgroud) android aidl android-intent launchmode android-pendingintent
我遇到了一个有趣的问题,即Activity被多次创建,甚至它被定义为清单中的singleTask或singelInstance活动.以下是如何重现这一点.比如,在主要活动中:
@Override
protected void onResume() {
Intent i = new Intent(MainActivity.class, SingleActivity.class);
startActivity(i);
}
Run Code Online (Sandbox Code Playgroud)
在我的SingleActivity中,我有:
@Override
protected void onCreate(Bundle savedInstanceState) {
...
Log.i("SingleActivity", "onCreate " + System.identityHashCode(this));
...
}
Run Code Online (Sandbox Code Playgroud)
在清单中,我有:
<activity android:name=".SingleActivity"
android:launchMode="singleInstance"
/>
Run Code Online (Sandbox Code Playgroud)
现在,如果我启动应用程序,事情似乎没问题,在一种情况下可以预期:如果我SingleActivity在前面按下"后退"按钮,它会导航回到MainActivity,在那里MainActivity.onResume()将创建另一个SingleActivity实例,而不是提出已经存在的实例.这是我所知道的,因为在日志中,会显示不同的身份哈希码.
如果启动模式是singleTask,则同样如此.
唯一的解决方法似乎是覆盖onBackPressed(),但这似乎是一个丑陋的解决方案.
我不知道我做错了什么
我有一个作为共享目标的应用程序。它是一个单活动架构,清单中带有 launchMode="singleTask" 。
所有其他应用程序在将数据共享到我的应用程序时,似乎都会遵守这一点,因此,即使该活动之前已打开,也会打开同一个实例。
然而,Google 文件似乎总是强制我的 Activity 的新实例,并且它始终保留在他们的任务中。
我调试了意图标志,但我对此不太聪明:
FLAG_ACTIVITY_FORWARD_RESULT|FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_PREVIOUS_IS_TOP|FLAG_GRANT_READ_URI_PERMISSION|FLAG_RECEIVER_FOREGROUND
Run Code Online (Sandbox Code Playgroud)
我怎样才能防止这种情况发生?我不希望我的单个活动有超过 1 个实例。甚至 launchMode="singleInstance" 也不起作用。
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize|stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud) 我有一个launchMode 作为singleTask 的活动。但是出于某种原因,当我尝试在 "adb shell dumpsys activity activites" 中查找日志时,存在两个实例。第一个实例
intent={act= flg=0x10000000 cmp=}以以下方式启动,第二个实例以以下意图启动
intent= { act= flg=0x10200000 cmp= (has extras)}。它是什么旗帜?
实际上,第二个意图是由不同的应用程序启动的。如何防止该应用启动我的活动的新实例。