调用finish()后Activity布局闪烁

7
当我打开我的应用程序时,会启动一个Activity,在其onCreate方法中,我正在检查一些条件。如果条件为真,则完成当前的Activity并打开另一个Activity。问题是:第一个Activity在屏幕上闪烁,然后打开第二个Activity。以下是代码:
public class FirstActivity extends Activity {
    @Override
    protected final void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //some code here...
        checkSomeStuff();
        setContentView(R.layout.my_layout);
        //some code here...
    }
    private void checkSomeStuff() {
        if (/*some condition*/) {
            final Intent intent = new Intent(this, SecondActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            finish();
            startActivity(intent);
        }
    }
}

请注意setContentView ()在检查之后,但在启动第二个活动之前,第一个活动仍然在屏幕上闪烁。 有人知道如何使其不闪烁吗? 提前致谢。
7个回答

10

finish() 的目的是销毁当前 Activity 并将其从返回堆栈中移除。通过调用 finish 然后触发 Intent,您正在请求 Activity 销毁自身(我假设闪烁是它尝试恢复),然后触发 Intent 到第二个 Activity。将 finish 移动到 startActivity() 之后。

 @Override
protected final void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //some code here...
    if(checkSomeStuff()) {
         setContentView(R.layout.my_layout);
         //some code here...
    }
}

private boolean checkSomeStuff() {
    if (/*some condition*/) {
        final Intent intent = new Intent(this, SecondActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
        return false;
    }
    return true;
}

1
这是我所知道的最好的方法。 - EK_AllDay
嗨,@EthanKeiser,我刚刚注意到这个解决方案适用于Android Lollipop,但在KitKat设备上检查时,它仍然会闪烁。 - arthursfreire
我注意到几件事情... 1、为什么onCreate是protected和final的?为什么bundle是final的?你使用了多态吗?请包含整个类,就像它现在的样子一样。 - PSchuette

3
您的代码顺序有误。在

后面您不应该调用任何内容。
finish(); 

这是因为该活动将被销毁。随后进行的任何操作可能导致异常行为。
 @Override
  protected final void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //set my layout
    setContentView(R.layout.my_layout);
    //some code here...
    finish();
    //nothing here because activity will be destroyed

}

2
以下技巧对我非常有效,希望对其他人也有用。
从活动 A 打开活动 B
要关闭活动 B,我使用以下方法:
finish(); 
overridePendingTransition(0, 0);

为了避免黑色闪烁问题。

2
闪烁和闪烁活动
    - Reason finish();
    - Remove finish() in Activity 
    - added android:noHistory="true" in AndroidManifest
< p > android:noHistory 属性可以清除需要在返回键按下时清除的 Activity,否则会在屏幕上显示 Activity A。 < /p >

1
代替做

checkSomeStuff();
setContentView(R.layout.my_layout);

你应该这样做

private void checkSomeStuff() {
    if (//some condition) {
        final Intent intent = new Intent(this, SecondActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        finish();
        startActivity(intent);
    }else{
        setContentView(R.layout.my_layout);
    }
}

你之所以能看到视图,是因为Intent直到onCreate执行完成才被触发,所以setContentView被调用。

你的解决方案与上面的其他方案有所不同,但仍然有效... 谢谢! - arthursfreire

0
也许你可以更好地分离条件,以完全避免在计划使用finish()时调用setContentView()
public class FirstActivity extends Activity {
    @Override
    protected final void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (someCondition()) {
            goToNextActivity();
        } else {
            setContentView(R.layout.my_layout);
            //some code here...
        }
    }

    private boolean someCondition() {
        /* return result of some condition */
    }

    private void goToNextActivity() {
        final Intent intent = new Intent(this, SecondActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        finish();
        startActivity(intent);
    }
}

基本上与上面的其他解决方案相同,但仍然是正确的。谢谢! - arthursfreire

0

用你的风格试试这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接