我正在开发的应用程序在第一次安装时有一种奇怪的行为。如果用户第一次正常退出应用程序,它将永远按预期运行。如果用户在安装应用程序后第一次使用主页按钮,它会将应用程序视为应该再次重新启动主屏幕并在旧版本之前启动新版本的活动。
所以手头有两个问题。我似乎无法解决这两个问题。
我没有将清单文件中的launchMode
属性定义为任何内容。因此,不应该有任何奇怪的行为。我现在已经使用应用程序的launchmode
属性进行了实验,看看我是否能够按照预期的方式运行它,但这里似乎还有更多内容,而不仅仅是正确启动活动。当我按下主页按钮时,应用程序没有理由第一次关闭。
我也不在应用程序中使用onUserLeaveHint
。通过对项目进行搜索,我必须再次确定。因此,似乎根本没有尝试覆盖主页按钮。
即使重新启动手机,主页按钮也会再次正常运行。不确定是什么原因导致初始安装将主页按钮视为从头开始启动应用程序的标志。
用户第一次退出应用程序后,问题将永久解决。关于我应该在哪里看的任何想法?
最近在应用程序中进行了一次搜索,看看是否它只是触发因为SQLite数据库方法的onUpgrade()
组件导致了一些奇怪的行为。
@Override
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
}
}
或者在另一个可能触发清单文件更新的位置,如果我将新版本的APK传递给其上有版本的设备已经低于当前版本。但是,在这部分代码中没有任何内容让我相信它应该影响与启动顺序相关的任何事情。
下面提供了清单文件(名称已更改),以用于当前在应用程序中使用的内容。
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="com.android.vending.CHECK_LICENSE"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.VIBRATE" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA" android:required="false"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:allowBackup="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
>
<activity android:name=".MyMain"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<activity android:name=".StartupActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SelectActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"/>
<activity android:name=".ImageSelectionActivity"
android:theme="@android:style/Theme.Dialog"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden"/>
<activity android:name=".DetailsActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"/>
<activity android:name=".EMailActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"/>
<activity android:name=".SendTo"
android:label="@string/share_label"
android:theme="@android:style/Theme.Dialog" >
<INTENT-FILTER>
<ACTION android:name="android.intent.action.MAIN">
<CATEGORY android:name="android.intent.category.LAUNCHER"/>
<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="callback" android:host="twitter"/>
</CATEGORY>
</CATEGORY>
</ACTION>
</INTENT-FILTER>
</ACTION>
</INTENT-FILTER>
</activity>
<activity android:name=".CreateMyActivity"
android:label="@string/create_account_label"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog"/>
<activity android:name=".ViewInLayoutActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"/>
<activity android:name=".Preferences"
android:label="@string/set_preferences"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog"/>
<activity android:name=".AboutActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"/>
<activity android:name=".InteractiveActivity"
android:label="@string/app_name_with_version"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog"/>
<activity android:name=".AlertFailedCommunications"
android:screenOrientation="portrait"
android:label="@string/alert_account_label"
android:theme="@android:style/Theme.Dialog"/>
</application>
答案 0 :(得分:63)
欢迎来到不断增长的用户名单。
这是众所周知且长期存在的Android错误。第一次从安装程序,Web浏览器和IDE(IntelliJ,Eclipse等)启动应用程序的方式。请参阅很久以前提出的与此问题相关的问题:
http://code.google.com/p/android/issues/detail?id=2373
http://code.google.com/p/android/issues/detail?id=26658
它仍然破碎,你无法防止这种情况发生。您唯一能做的就是检测Android何时将根活动的第二个实例启动到现有任务。您可以将此代码放在根活动的onCreate()
中来执行此操作:
if (!isTaskRoot()) {
// Android launched another instance of the root activity into an existing task
// so just quietly finish and go away, dropping the user back into the activity
// at the top of the stack (ie: the last state of this task)
finish();
return;
}
答案 1 :(得分:5)
为什么这样做,没有任何线索。但我知道自定义Launcher
具有特定的launchModes
设置。
例如ADW.Launcher:
android:clearTaskOnLaunch="true"
android:launchMode="singleTask"
Android SDK示例中的家庭应用程序:android-sdk\samples\android-16\Home\AndroidManifest.xml
android:launchMode="singleInstance"
引用CommonsWare:How to prevent custom home launcher app restart activity?
我将使用SDK中的Home示例应用程序 singleInstance。奇怪的是,AOSP发射器使用singleTask
答案 2 :(得分:1)
上面的答案对我使用 Nativescript 不起作用 - 这通过在活动标签中添加这两个属性解决了这个问题:
android:alwaysRetainTaskState="true"
android:launchMode="singleTask"
此链接提供了此解决方案:https://github.com/NativeScript/NativeScript/issues/3415
答案 3 :(得分:0)
看起来问题是由应用的不同实例引起的。可能第一个实例是在安装程序的任务下启动的,第二个实例是在用户单击应用程序图标时自行执行的任务。用户似乎恢复了应用程序,但实际上他此时再次启动它。
如果您想让您的应用仅在自己的任务中运行,可能的方法是添加
android:allowTaskReparenting="true"
到AndroidManifest的应用程序级别。安装后第一次单击应用程序图标后,您的应用程序将移至分离的任务。