欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android優(yōu)化提升應(yīng)用啟動(dòng)速度及Splash頁面的設(shè)計(jì)

 更新時(shí)間:2021年12月09日 09:11:38   作者:冬日毛毛雨  
這篇文章主要介紹了Android性能優(yōu)化的一些相關(guān)資料,文章圍繞提升應(yīng)用啟動(dòng)速度及Splash頁面的設(shè)計(jì)的內(nèi)容展開介紹,需要的朋友可以參考一下,希望對你有所幫助

1.啟動(dòng)分為兩種方式

  • 1) 冷啟動(dòng):當(dāng)直接從桌面上直接啟動(dòng),同時(shí)后臺(tái)沒有該進(jìn)程的緩存,這個(gè)時(shí)候系統(tǒng)就需要重新創(chuàng)建一個(gè)新的進(jìn)程并且分配各種資源。
  • 2) 熱啟動(dòng):app后臺(tái)有該進(jìn)程的緩存,這時(shí)候啟動(dòng)的進(jìn)程就屬于熱啟動(dòng)。
  • 熱啟動(dòng)不需要重新分配進(jìn)程,也不會(huì)Application了,直接走的就是app的入口Activity,這樣速度就很快

2.如何測量一個(gè)應(yīng)用的啟動(dòng)時(shí)間

使用命令行來啟動(dòng)app,同時(shí)進(jìn)行時(shí)間測量。單位:毫秒

?adb shell am start - W [PackageName] /[PackageName.MainActivity]

例: adb shell am start -W com.haocai.app/.activity.GuideActivity

熱啟動(dòng)耗時(shí):

打印的結(jié)果為:

  • ThisTime activity啟動(dòng)耗時(shí)
  • TotalTime 應(yīng)用自身啟動(dòng)耗時(shí)=ThisTime+應(yīng)用application等資源啟動(dòng)時(shí)間
  • WaitTime 系統(tǒng)啟動(dòng)應(yīng)用耗時(shí)=TotalTime+系統(tǒng)資源啟動(dòng)時(shí)間

3.應(yīng)用啟動(dòng)的流程

Application從構(gòu)造方法開始 ---> attachBaseContext() ---> onCreate()
Activity
構(gòu)造方法 ---> onCreate() ---> 設(shè)置顯示界面布局,設(shè)置主題、背景等等屬性 ---> onStart()
---> onResume() ---> 顯示里面的View(測量、布局、繪制,顯示到界面上)

從構(gòu)造方法我們知道,啟動(dòng)耗時(shí)的主要花費(fèi)在各個(gè)啟動(dòng)流程中

4.減少應(yīng)用的啟動(dòng)時(shí)間的耗時(shí)

根據(jù)應(yīng)用的啟動(dòng)流程,我們從而得到以下減少應(yīng)用啟動(dòng)耗時(shí)操作的建議:

  • 不要在Application的構(gòu)造方法、attachBaseContext() 、onCreate()里面進(jìn)行初始化耗時(shí)操作。
  • MainActivity,由于用戶只關(guān)心最后顯示的這一幀,對我們的布局的層次要求減 自定義控件的測量、布局、繪制的時(shí)間。 同時(shí) 不要在onCreate、onStartonResume當(dāng)中的做耗時(shí)操作。
  • 對于SharedPreference的初始化

因?yàn)樗跏蓟臅r(shí)候是需要將數(shù)據(jù)全部讀取出來放到內(nèi)存當(dāng)中。

  • 優(yōu)化1:可以盡可能減少sp文件數(shù)量(IO需要時(shí)間)
  • 優(yōu)化2:像這樣的初始化最好放到線程里面
  • 優(yōu)化3:大量的數(shù)據(jù)緩存到數(shù)據(jù)庫中

app啟動(dòng)的耗時(shí)主要在:Application初始化 + MainActivity的界面加載繪制時(shí)間。

由于MainActvity的業(yè)務(wù)和布局復(fù)雜度非常高,甚至該界面必須要有一些初始化的數(shù)據(jù)才能顯示。
那么這個(gè)時(shí)候MainActivity就可能半天都出不來,這就給用戶感覺App太卡了。

常規(guī)方法:

1.我們要做的就是給用戶趕緊利落的體驗(yàn)。點(diǎn)擊app就立馬彈出我們的界面。
于是乎想到使用SplashActivity--非常簡單的一個(gè)歡迎頁面上面都不干就只顯示一個(gè)圖片。
2.但是SplashActivity啟動(dòng)之后,還是需要跳到MainActivity。MainActivity還是需要從頭開始加載布局和數(shù)據(jù)。
想到SplashActivity里面可以去做一些MainActivity的數(shù)據(jù)的預(yù)加載。然后需要通過意圖傳到MainActivity。

更好的優(yōu)化:

耗時(shí)的問題:Application+Activity的啟動(dòng)及資源加載時(shí)間;預(yù)加載的數(shù)據(jù)花的時(shí)間。

如果我們能讓這兩個(gè)時(shí)間重疊在一個(gè)時(shí)間段內(nèi)并發(fā)地做這兩個(gè)事情就省時(shí)間了。

比如:SplashActivityMainActivity合為一個(gè)。

一進(jìn)來還是顯示MainActivity,SplashActivity可以變成一個(gè)SplashFragment,然后放一個(gè)FrameLayout作為根布局直接顯示SplashFragment界面。
SplashFragment里面非常之簡單,就是現(xiàn)實(shí)一個(gè)圖片,啟動(dòng)非常快。

當(dāng)SplashFragment顯示完畢后再將它remove。同時(shí)在splash的2S的友好時(shí)間內(nèi)進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)緩存。
這個(gè)時(shí)候我們才看到MainActivity,就不必再去等待網(wǎng)絡(luò)數(shù)據(jù)返回了。

新問題SplashViewContentView加載放到一起來做了 ,這可能會(huì)影響應(yīng)用的啟動(dòng)時(shí)間?

解決:可以使用ViewStub延遲加載MainActivity當(dāng)中的View來達(dá)到減輕這個(gè)影響。
viewStub的設(shè)計(jì)就是為了防止MainActivity的啟動(dòng)加載資源太耗時(shí)了。延遲進(jìn)行加載,不影響啟動(dòng),用戶友好。
但是viewStub加載也需要時(shí)間。等到主界面出來以后。
viewStub.inflate(xxxx);

5.如何設(shè)計(jì)延遲加載DelayLoad

第一時(shí)間想到的就是在onCreate里面調(diào)用Handler.postDelayed()方法;
問題一:這個(gè)延時(shí)時(shí)間如何控制
不同的機(jī)器啟動(dòng)速度不一樣,這個(gè)時(shí)間如何控制?
假設(shè),先需要splash做一個(gè)2s動(dòng)畫,然后在MainActivity中主界面加載完成之后,關(guān)閉splash頁面

如果這樣寫:

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mProgressBar.setVisibility(View.GONE);
                iv.setVisibility(View.VISIBLE);
            }
        }, 2500);


是無法在準(zhǔn)確監(jiān)聽頁面加載完的

問題:什么時(shí)候應(yīng)用已經(jīng)啟動(dòng)并加載完成,界面已經(jīng)顯示出來了。
采用onResume執(zhí)行完了之后才顯示完畢?不行。

建議采用getDecorView() 獲取上級view 然后添加視圖

綜合上訴方案,以下是關(guān)鍵代碼:

public class MainActivity extends AppCompatActivity {

    private Handler mHandler = new Handler();
    private SplashFragment splashFragment;
    private ViewStub viewStub;

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

        splashFragment = new SplashFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.frame, splashFragment);
        transaction.commit();

        /**
         *這么寫不好判斷視圖有沒有加載完
         */
        //      mHandler.postDelayed(new Runnable() {
//          @Override
//          public void run() {
//              mProgressBar.setVisibility(View.GONE);
//              iv.setVisibility(View.VISIBLE);
//          }
//      }, 2500);

        viewStub = (ViewStub) findViewById(R.id.content_viewstub);

        //1.判斷當(dāng)窗體加載完畢的時(shí)候,立馬再加載真正的布局進(jìn)來
        getWindow().getDecorView().post(new Runnable() {

            @Override
            public void run() {
                // 開啟延遲加載
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        //將viewstub加載進(jìn)來
                        viewStub.inflate();
                    }
                });
            }
        });

        //2.判斷當(dāng)窗體加載完畢的時(shí)候執(zhí)行,延遲一段時(shí)間做動(dòng)畫。
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                // 開啟延遲加載,也可以不用延遲可以立馬執(zhí)行(我這里延遲是為了實(shí)現(xiàn)fragment里面的動(dòng)畫效果的耗時(shí))
                mHandler.postDelayed(new DelayRunnable(MainActivity.this, splashFragment), 2000);
            }
        });

    //3.同時(shí)進(jìn)行異步加載數(shù)據(jù)
        //......
    }
    

    static class DelayRunnable implements Runnable {

        private WeakReference<Context> contextWeakReference;
        private WeakReference<SplashFragment> splashFragmentWeakReference;

        public DelayRunnable(Context context, SplashFragment f) {
            contextWeakReference = new WeakReference<Context>(context);
            splashFragmentWeakReference = new WeakReference<SplashFragment>(f);
        }

        @Override
        public void run() {
            //移除Fragment
            if (contextWeakReference != null) {
                SplashFragment splashFragment = splashFragmentWeakReference.get();
                if (splashFragment == null) {
                    return;
                }
                FragmentActivity activity = (FragmentActivity) contextWeakReference.get();
                FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
                transaction.remove(splashFragment);
                transaction.commit();
            }

        }
    }
}

activity_main.xml:

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

    <ViewStub 
        android:id="@+id/content_viewstub"
        android:layout="@layout/activity_main_viewstub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <FrameLayout
        android:id="@+id/frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>

</RelativeLayout>

ps:測試數(shù)據(jù)是在老款三星手機(jī)下所得耗時(shí)數(shù)據(jù)。
不過相較于SplashActivity+MainActivity啟動(dòng)速度優(yōu)化還是挺明顯的。大家可以在自己手機(jī)上試試。

到此這篇關(guān)于Android提升應(yīng)用啟動(dòng)速度及Splash頁面的設(shè)計(jì)的文章就介紹到這了,更多相關(guān)Android性能優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Flutter框架實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果

    Flutter框架實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果

    這篇文章主要介紹了Flutter框架實(shí)現(xiàn)Android拖動(dòng)到垃圾桶刪除效果,Flutter框架中的Draggable部件,用于支持用戶通過手勢拖動(dòng),它是基于手勢的一種方式,可以使用戶可以在屏幕上拖動(dòng)指定的部件,下面我們來詳細(xì)了解一下
    2023-12-12
  • Android中ImageView.src設(shè)置圖片拉伸、填滿控件的方法

    Android中ImageView.src設(shè)置圖片拉伸、填滿控件的方法

    最近公司有個(gè)需求,要展示客戶公司的企業(yè)形象,用一張圖片放在ImageView中實(shí)現(xiàn),但是發(fā)現(xiàn)圖片并沒有填滿,而是在上下邊上留出了一點(diǎn)空白,下面這篇文章主要跟大家介紹了Android中ImageView.src設(shè)置圖片拉伸、填滿控件的方法,需要的朋友可以參考下。
    2017-06-06
  • Android dataBinding與ListView及事件詳解

    Android dataBinding與ListView及事件詳解

    這篇文章主要介紹了Android dataBinding與ListView及事件詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Android滑動(dòng)事件沖突詳解(一)

    Android滑動(dòng)事件沖突詳解(一)

    這篇文章主要為大家詳細(xì)介紹了Android滑動(dòng)事件沖突,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android CheckBox 的使用案例分析

    Android CheckBox 的使用案例分析

    本篇文章小編為大家介紹,Android CheckBox 的使用案例分析。需要的朋友參考下
    2013-04-04
  • Android客戶端實(shí)現(xiàn)注冊、登錄詳解(1)

    Android客戶端實(shí)現(xiàn)注冊、登錄詳解(1)

    這篇文章主要為大家詳細(xì)介紹了Android客戶端實(shí)現(xiàn)注冊、登錄代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Android+SQLite數(shù)據(jù)庫實(shí)現(xiàn)的生詞記事本功能實(shí)例

    Android+SQLite數(shù)據(jù)庫實(shí)現(xiàn)的生詞記事本功能實(shí)例

    這篇文章主要介紹了Android+SQLite數(shù)據(jù)庫實(shí)現(xiàn)的生詞記事本功能,結(jié)合具體實(shí)例形式分析了Android操作SQLite數(shù)據(jù)庫實(shí)現(xiàn)生詞記錄功能的操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-09-09
  • Android異步消息機(jī)制詳解

    Android異步消息機(jī)制詳解

    這篇文章主要為大家詳細(xì)介紹了Android異步消息機(jī)制的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android仿QQ長按刪除彈出框功能示例

    Android仿QQ長按刪除彈出框功能示例

    對于列表來說,如果想操作某個(gè)列表項(xiàng),一般會(huì)采用長按彈出菜單的形式,默認(rèn)的上下文菜單比較難看,而QQ的上下文菜單就人性化多了,整個(gè)菜單給用戶一種氣泡彈出的感覺,而且會(huì)顯示在手指按下的位置,接下來通過本文給大家分享Android仿QQ長按刪除彈出框功能,一起看看吧
    2017-03-03
  • 設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法

    設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法

    在進(jìn)行Android系統(tǒng)開發(fā)的時(shí)候,有些特定的情況需要設(shè)置系統(tǒng)永不鎖屏,永不休眠。本篇文章給大家介紹Android 永不鎖屏,開機(jī)不鎖屏,刪除設(shè)置中休眠時(shí)間選項(xiàng),需要的朋友一起學(xué)習(xí)吧
    2016-03-03

最新評論