Подтвердить что ты не робот

Повторный запуск кнопки "Активность на дому", но... только в первый раз

Приложение, которое я разрабатываю, имеет странное поведение в первый раз, когда оно установлено. Если пользователь в первый раз полностью отказывается от приложения, он будет вечно вести себя так, как должен. Если пользователь впервые использует домашнюю кнопку, после первого запуска приложения обращается к приложению, как если бы он снова запустил домашний экран и запустил новую версию активности перед старой.

Итак, есть действительно две проблемы. Кажется, я не могу решить их обоих.

  • Держите приложение закрытым, когда оно впервые установлено при нажатии пользователем кнопки "домой".
  • Держите несколько версий приложения от запуска, когда он это делает (startMode помогает здесь немного, но первый компонент все еще срабатывает).

У меня нет атрибута launchMode в файле манифеста, который определен как что-либо. Поэтому в результате этого не должно быть какого-то нечетного поведения. Я экспериментировал теперь с атрибутом launchMode приложения, чтобы увидеть, могу ли я заставить его вести себя так, как он предназначен, но, похоже, здесь больше, чем просто запуск соответствующих действий. Нет причин, чтобы приложение закрывалось в первый раз, насколько я могу видеть, когда нажата кнопка "домой".

Я не использую onUserLeaveHint в приложении. Я должен был быть уверен еще раз, выполнив поиск по проекту. Таким образом, похоже, что не было никакого переопределения домашней кнопки вообще.

Даже после повторного запуска телефона домашняя кнопка ведет себя нормально снова. Не уверен, что вызывает первоначальную установку для обработки домашней кнопки в качестве флага для запуска приложения с нуля.

Как только пользователь в первый раз выйдет из приложения, проблема будет окончательно решена. Любые мысли о том, где я должен выглядеть?

Недавно в приложении был обнаружен поиск, возможно, он срабатывает только тогда из-за компонента onUpgrade() метода базы данных SQLite, вызывающего нечетное поведение.

@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>    

4b9b3361

Ответ 1

Добро пожаловать в постоянно растущий список пользователей, которые были укушены этим.

Это известная и давняя ошибка Android. в том, как приложения запускаются впервые с установщика, веб-браузера и через 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;
}

Ответ 2

Почему это ведет себя, нет подсказки. Но я знаю, что пользовательский Launcher имеет определенный launchModes набор.

Например, ADW.Launcher:

android:clearTaskOnLaunch="true"
android:launchMode="singleTask" 

Домашнее приложение в образцах SDK для Android: android-sdk\samples\android-16\Home\AndroidManifest.xml

android:launchMode="singleInstance"

Чтобы процитировать CommonsWare: Как предотвратить обычную перезагрузку приложения запуска приложения?

Я собираюсь с помощью примера приложения Home из SDK, который использует SingleInstance. Любопытно, что пусковые установки AOSP используют singleTask

Ответ 3

Похоже, проблема вызвана разными экземплярами приложения. Вероятно, первый экземпляр запускается под задачей установщика, а второй - под свою собственную задачу, когда пользователь нажимает на значок приложения. Кажется, пользователь он возобновляет приложение, но на самом деле он запускает его снова в этот момент.

Если вы хотите, чтобы ваше приложение запускалось только в своей собственной задаче, возможным способом является добавление

android:allowTaskReparenting="true"

на уровне приложения вашего AndroidManifest. Как только значок приложения будет нажат в первый раз после установки, ваше приложение будет перемещено в отдельную задачу.