1. 程式人生 > >Android UI優化— App啟動優化

Android UI優化— App啟動優化

黑白屏產生的原因和解決辦法

黑白屏產生的原因

1、還沒載入到佈局檔案,就已經顯示了window視窗背景
2、黑屏白屏就是window視窗背景

容易產生黑白屏的地方

1、Activity的onCreate()中

       @Override  
       protected void onCreate(Bundle savedInstanceState) {                                              
                super.onCreate(savedInstanceState);
              //這裡邏輯過於耗時或者佈局檔案過於複雜                                     
                setContentView(R.layout.activity_main);
      }

2、Application的onCreate()中

      @Override
      public void onCreate() {
            super.onCreate();
          //這裡的邏輯過於複雜,耗時多
      }

黑白屏解決辦法

1、避免在載入佈局檔案之前在主執行緒中執行耗時操作
2、給Window設定背景,將其設為透明或者和Splash介面一樣

App啟動頁優化

啟動頁優化思路

App啟動頁的正常寫法是設定一個SplashActivity,App啟動時先顯示SplashActivity,然後由SplashActivity跳轉到MainActivity。但是這種通常的做法有一個致命問題,就是如果MainActivity的佈局如果比較複雜,則進入主介面的時候會有明顯的卡頓和載入過程,並且有些頭重腳輕。
針對上述問題,可以做一些優化處理,如下:

把SplashActivity改成SplashFragment,應用程式的入口改為MainActivity。在MainActivity中先展示SplashFragment,當SplashFragment顯示完畢後再將它remove,同時在SplashFragment顯示的友好時間內進行網路資料快取等預處理事務,在視窗載入完畢後,我們載入activity_main的佈局,考慮到這個佈局有可能比較複雜,耽誤View的解析時間,採用ViewStub的形式進行懶載入。這樣一開始只要載入SplashFragment所展示的佈局就可以了,當MainActivity需要顯示的時候也把準備工作(載入佈局、預處理等)做好了。

流程如下:
1、把SplashActivity改成SplashFragment
2、在SplashFragment顯示的時間內進行網路資料快取等工作
3、採用ViewStub的形式載入activity_main的佈局

MainActivity的佈局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ge.jgc.cloudecg.activity.MainActivity">

   //替換為主介面佈局
    <ViewStub
        android:id="@+id/content_viewstub"
        android:layout="@layout/main_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>   

   //顯示 SplashFragment
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

MainActivity的程式碼如下:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
        setContentView(R.layout.activity_main);
        
        final SplashFragment splashFragment = new SplashFragment();
        final ViewStub mainLayout = (ViewStub) findViewById(R.id.content_viewstub);
        
        //1、首先顯示啟動頁面
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        if (supportFragmentManager != null) {
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
            if (fragmentTransaction != null) {
                fragmentTransaction.replace(R.id.container, splashFragment);
                fragmentTransaction.commit();
            }
        }
        //2、進行一些預處理事務
        //3、渲染完畢後,立刻載入主頁佈局
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, " getWindow().getDecorView().post");
                View mainView = mainLayout.inflate();
                //初始化主介面
                initView(mainView);
            }
        });
        //4、 splashFragment顯示一段時間之後移除
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                mHandler.postDelayed(new DelayRunnableImpl(MainActivity.this, splashFragment), 3000);
            }
        });
    }