How to avoid black screen on startActivity when FLAG_ACTIVITY_CLEAR_TASK is set?
Asked Answered
A

1

19

I am launching a new activity using the following:

Intent intent = new Intent(this, MyNewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
overridePendingTransition(0, 0);

While MyNewActivity is launching, a black screen is shown.

If I remove Intent.FLAG_ACTIVITY_CLEAR_TASK, the activity is launched without showing a black screen at any moment (instead, the previous activity is shown while the new one loads).

Is there any way to avoid this black screen? Removing the flags seems to not be an option (I need to clear all the current task's stack and launch a new activity as the root one).

EDIT: I attach a very simple code which reproduces the issue (set a dark theme such as Theme.AppCompat for the app). The black screen is shown for very little time (depends on how many work the receiving activity does when launching), but you can see it. If you don't use FLAG_ACTIVITY_CLEAR_TASK, the black screen is not shown and the transition is smooth:

MainActivity

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MyNewActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                overridePendingTransition(0,0);
            }
        });
    }
}

MyNewActivity

public class MyNewActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new);
    }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_bright">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CLICK ME!" />

</RelativeLayout>

activity_new.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_light">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I am the new activity!" />

</RelativeLayout>

Thanks!

Alfy answered 12/3, 2015 at 17:0 Comment(5)
Fix your app so that it doesn't do a lot in onCreate(). Offload the stuff into a background thread that you start in onCreate() instead.Riggle
I can't optimize it anymore, unfortunately (the app has some very special visual design guidelines which require doing some handling of background images in the main thread). Anyway, that's not the problem. I have attached sample code to reproduce it on any project, even with an activity that does nothing.Alfy
Another option would be to use Intent.FLAG_ACTIVITY_CLEAR_TOP instead of CLEAR_TASK. This will only work if you leave the original instance of MyNewActivity in the stack (ie: don't finish it when you launch other Activities). If this still doesn't fix it, you can try Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP. This will clear all other activities off the stack and return to the existing instance of MyNewActivity. In this case, you could add an "extra" to the Intent, which MyNewActivity can check in onNewIntent() and if set, it could reinitialize itself.Riggle
I have already checked the other Intent launch modes, FLAG_ACTIVITY_CLEAR_TOP is not useful in my case as I could have never launched MyNewActivity, and I want to clear all the previous activity stack. For example, I have the following flow: A->B->C->D->MyNewActivity I want to erase from my activity stack the A, B, C and D activities, and launch MyNewActivity. The only flag that does what I want is Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK. At least, that is the only one I'm aware of.Alfy
You should delete FLAG_ACTIVITY_CLEAR_TASK and instead call finish() after starting new activity. this link helped me a lot.Gimcrackery
B
26

To completely avoid the "black screen" (aka "preview") you can add the following to your AppTheme:

<style name="AppTheme" parent="Theme.AppCompat">
    <item name="android:windowDisablePreview">true</item>
    ...
</style>

However a better approach is do less things on main thread during Activity.onCreate and let show the preview screen while user is waiting. For a smooth transition, you can set a custom background to your windows adding this to your theme:

<style name="AppTheme" parent="Theme.AppCompat">
    <item name="android:windowBackground">@drawable/slash_screen</item>
    ...
</style>
Backbreaker answered 3/8, 2015 at 7:21 Comment(1)
Thank you very much! I never thought that what was being displayed was the preview!Alfy

© 2022 - 2024 — McMap. All rights reserved.