【问题标题】:Activity layout blinking after finish() is called调用完成()后活动布局闪烁
【发布时间】:2015-08-04 19:45:41
【问题描述】:

当我打开我的应用程序时,会启动一个 Activity,并在其 onCreate 方法中检查一些条件。如果条件为真,我会完成我当前的活动并打开另一个活动。问题是:第一个活动在屏幕上闪烁,然后第二个活动被打开。代码如下:

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() 是在检查之后,但在第二个活动开始之前,第一个活动仍然在屏幕上闪烁。 有谁知道怎么让它不眨眼?

提前致谢。

【问题讨论】:

    标签: android android-activity activity-lifecycle


    【解决方案1】:

    finish() 的目的是销毁当前活动并将其从后台堆栈中移除。通过调用完成然后触发意图,您要求活动自行销毁它(我假设眨眼是它试图恢复)然后将意图触发到第二个。将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;
    }
    

    【讨论】:

    • 这是我所知道的最好的方法。
    • 您好,@EthanKeiser,我刚刚注意到这个解决方案适用于 Android Lollipop,但是在签入 KitKat 设备时,它仍然会闪烁。
    • 我注意到的几件事.... 1,为什么 onCreate 是受保护的和最终的?为什么捆绑包是最终的?你使用任何多态性吗?请您按原样包括整个班级吗?
    【解决方案2】:

    您的代码顺序错误。你不应该在

    之后调用任何东西
    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
    
    }
    

    【讨论】:

      【解决方案3】:

      闪烁和闪烁的Activity

          - Reason finish();
          - Remove finish() in Activity 
          - added android:noHistory="true" in AndroidManifest
      

      android:noHistory 将清除堆栈中的 Activity,这些 Activity 需要在后按时清除,否则它会在屏幕上显示 Activity A。

      【讨论】:

        【解决方案4】:

        下面提到的技巧对我来说非常有效。希望这对其他人有用。

        从活动 A 中打开活动 B

        要关闭活动B我正在使用:

        finish(); 
        overridePendingTransition(0, 0);
        

        避免黑色闪烁问题。

        【讨论】:

          【解决方案5】:

          而不是做

          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);
              }
          }
          

          您会看到该视图,因为意图在 onCreate 完成之前不会触发,因此会调用 setContentView

          【讨论】:

          • 您的解决方案是上述其他解决方案的变体,但仍然有效...谢谢!
          【解决方案6】:

          当您计划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);
              }
          }
          

          【讨论】:

          • 与上面其他的解决方案基本相同,但仍然正确谢谢!
          【解决方案7】:

          试试你的风格

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-06-16
            • 2016-05-27
            • 2016-11-07
            • 1970-01-01
            • 2013-07-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多