Поведение Activity SingleTask с SplashScreen

В моем приложении у меня есть:

-SplashScreen (SSc) подготовка приложения (запуск служб и т. д.) -MainActivity (MA) наиболее важная часть приложения, обрабатывающая большинство действий -и некоторые другие действия, которые не так важны

Для моего приложения я хотел бы иметь поведение, подобное launchMode singleTask, чтобы мое приложение всегда запускалось как новая задача, даже при открытии по ссылке в приложении SMS/EMail. Лучше всего иметь только один экземпляр моих действий, поскольку все они последовательно доступны.

Однако, когда я запускаю SSc как singleTask, это корень стека, и я перехожу к MainActivity, нажимаю домой, снова щелкаю значок Launcher, приложение полностью перезапускается. Итак, SSc снова показывается и так далее. В этой ситуации я бы хотел, чтобы MainActivty вместо этого была выведена на передний план.

мое желание было бы: launcherclick -> SSc -> MA -> HOME -> launcherclick -> вывести MA на передний план -> HOME-> перезапустить из недавних -> вывести MA на передний план

Нажмите на ссылку ->SSc/MA (будь то первый запуск) с теми же экземплярами

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

Есть ли у вас какие-либо рекомендации для достижения этой цели?

моей первой идеей была LauncherActivity с одиночной задачей launchMode без макета для маршрутизации намерений к другим действиям (которые, скорее всего, будут singleTop !?, потому что тогда это только в одной задаче), например:

public class LauncherActivity extends Activity {
 private boolean firstStart = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(firstStart){
            startActivity(new Intent(this, SplashScreen.class));
            firstStart = false;
        } else {
            Intent i = new Intent(this, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            startActivity(i);
        }
    }
}

XML-файл манифеста:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="x.startintenttest">

    <application
        android:allowBackup="true"
        android:allowTaskReparenting="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name="x.startintenttest.MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"></activity>
        <activity
            android:name="x.startintenttest.MainActivity2"
            android:label="@string/title_activity_main_activity2"></activity>
        <activity
            android:name="x.startintenttest.SplashScreen"
            android:label="@string/title_activity_splash_screen"
            android:launchMode="singleTask">
            <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:host="*.xyz.de"
                    android:pathPattern="/...-........."
                    android:scheme="https" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        
    </application>

</manifest>

person Denny1989    schedule 14.05.2014    source источник
comment
Не могли бы вы опубликовать файл манифеста?   -  person Chaosit    schedule 14.05.2014
comment
Это происходит каждый раз? Или только при запуске приложения из установщика или из IDE (Eclipse, IntelliJ и т.д.). Попробуйте принудительно закрыть приложение, а затем запустить его из списка доступных приложений и посмотреть, исчезнет ли проблема. Если это так, то вы просто видите эту неприятную ошибку Android: stackoverflow.com/a/16447508/769265   -  person David Wasser    schedule 14.05.2014


Ответы (2)


Все просто, я тоже так делал. Я использовал singleTask для заставки и основного действия. Так что я столкнулся с той же проблемой (всплеск показывался при каждом пробуждении). Но я решил это, удалив singleTask из заставки и оставив его только для MA (раньше я заканчивал заставку, когда начинается MA). Попробуйте этот трюк.

person Sripathi    schedule 14.05.2014
comment
благодарю вас. я буду использовать этот подход в нашем приложении. это наиболее близко к нашим потребностям. - person Denny1989; 15.05.2014
comment
@SudoPlz в Androidmanifest поместите android:launchmode=singleTask в свою основную деятельность, а не на SplashScreen. Вот и все. - person Mikkel Larsen; 11.07.2018
comment
Большое спасибо. Однако это решение оставляет экран-заставку в качестве предварительного просмотра приложения для приложения, которое запустило событие щелчка на экране последних приложений, поскольку оно запускается в той же задаче, что и действие вызывающего абонента. У кого-нибудь есть решение для этого? Мне было интересно, должен ли я создать новое действие по обработке ссылок с launchMode=singleTask только для того, чтобы исправить эту проблему, а затем перенаправить на обычный экран-заставку, который, в свою очередь, откроет основное действие. Теоретически это устранило бы проблему с предварительным просмотром приложения и заставкой OP. - person Gonzalo; 18.10.2018

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

class LinkEntryPointActivity : MyBaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val intentClone = intent.clone() as Intent
        val componentName = intentClone.component
        val newComponentName = ComponentName(componentName.packageName, SplashActivity::class.java.name)
        intentClone.component = newComponentName
        startActivity(intentClone)
        finish()
    }
}

И объявите его в AndroidManifest.xml как

<activity android:name=".ui.LinkEntryPointActivity"
    android:launchMode="singleTask"   <-- This forces to open the link in a new task
    android:screenOrientation="portrait">
    <!-- Intent filters here -->
</activity>

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

person Gonzalo    schedule 18.10.2018