Android面试:启动activity显示的第一帧

我们有这样一个需求,当一个activity启动后的第一帧,也就是肉眼可见的第一帧后做一个更新界面updateText的操作,这里的第一帧有没有一个合理的时机,让我们认为activity界面可见了?onResume是否可以认为是第一帧可见?

public class MainActivity extends AppCompatActivity {
    private static final int DEALY_TIME = 300 ;

    private ImageView imageView1;
    private ImageView imageView2;
    private ImageView imageView3;
    private TextView textView1;
    private TextView textView2;
    private TextView textView3;

    private Handler myHandler = new Handler();
    private Runnable mLoadingRunnable = new Runnable() {
        @Override
        public void run() {
            updateText();
        }
    };

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

        imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        textView1 = (TextView) findViewById(R.id.text1);
        textView2 = (TextView) findViewById(R.id.text2);
        textView3 = (TextView) findViewById(R.id.text3);

//      第一种写法:直接Post
        myHandler.post(mLoadingRunnable);

//      第二种写法:直接PostDelay 300ms.
        myHandler.postDelayed(mLoadingRunnable, DEALY_TIME);

//      第三种写法:优化的DelayLoad
      getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                myHandler.post(mLoadingRunnable);
            }
        });

        // Dump当前的MessageQueue信息.
        getMainLooper().dump(new Printer() {
            @Override
            public void println(String x) {
                Log.i("Gracker",x);
            }
        },"onCreate");
    }

    private void updateText() {
        TraceCompat.beginSection("updateText");
        textView1.setText("image1 : w=" + imageView1.getWidth() +
                " h =" + imageView1.getHeight());
        textView2.setText("image2 : w=" + imageView2.getWidth() +
                " h =" + imageView2.getHeight());
        textView3.setText("image3 : w=" + imageView3.getWidth() +
                " h =" + imageView3.getHeight());
        TraceCompat.endSection();
    }

第三种写法我们认为是屏幕可见的第一帧回调,通过观察systrace图可见

Activity 的 onCreate/onStart/onResume三个回调中,并没有执行Measure和Layout操作,这个是在后面的performTraversals中才执行的。因为我们知道,,应用启动的时候,要等两次 performTraversals 都执行完成之后才会显示第一帧, 

因此updateText 方法需要在第二个performTraversals 方法执行完成后(即APP第一帧在屏幕上显示),马上就去执行,那么即起到了 Delay Load的作用,又可以正确显示图片的宽高。updateText 在第二个 performTraversals 方法执行完成后马上执行,然后下一个 VSYNC 信号来了之后,,TextView就更新了。

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/114763496