日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Splash闪屏页秒开 Activity白屏、Activity黑屏问题

發布時間:2023/12/10 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Splash闪屏页秒开 Activity白屏、Activity黑屏问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

本文轉自嚴振杰的博客:?http://blog.csdn.net/yanzhenjie1003

?

今天在處理項目中閃屏界面的時候,遇到程序第一次開啟會出現白屏大約2秒左右,然后再執行閃屏,故找到該篇文章,問題解決:

本篇博客要剖析和解決的兩個問題:?
1. APP啟動時白屏/黑屏、Activity打開時白屏/黑屏。?
2. APP啟動速度慢,如何實現點擊ICON后APP秒開。APP啟動加速。


APP啟動時白屏/黑屏、Activity打開時白屏/黑屏

首先要說明的是無論是APP啟動,還是startActivity都是Activity的啟動,所以這歸根結底是一個問題,看完本博客就明白了。

這是一個很多新手或者從事Android開發已經一年多的同學們可能遇到的疑問,究其原因是對Activity的啟動機制和Activity的繪制機智不太了解。

繪制整個窗口需要按順序執行以下幾個步驟:?
1. 繪制背景。?
2. 繪制View本身的內容。?
3. 繪制子View。?
4. 繪制修飾內容(例如滾動條)。

這里是主要的四步,還有些其他對于今天內容不太重要省去沒寫。

閃屏原因剖析StartingWindow(Preview Window)

我們正常開發中會在Activity的onCreate()方法中調用setContentView(View)設置該Activity的顯示布局,那么問題就來了,既然我們設置了布局,為什么啟動的時候還會白屏或者黑屏而不是顯示我set的布局呢?下面就帶領大家一起來剖析一下原因。

當打開一個Activity時,如果這個Activity所屬Application還沒有在運行,系統會為這個Activity的創建一個進程(每開啟一個進程都會有一個Application,所以Application的onCreate()可能會被調用多次),但進程的創建與初始化都需要時間,在這個動作完成之前,如果初始化的時間過長,屏幕上可能沒有任何動靜,用戶會以為沒有點到按鈕。所以既不能停在原來的地方又沒到顯示新的界面,怎么辦呢?這就有了StartingWindow(也稱之為PreviewWindow)的出現,這樣看起來就像Activity已經啟動起來了,只是數據內容還沒有初始化好。

StartingWindow一般出現在應用程序進程創建并初始化成功前,所以它是個臨時窗口,對應的WindowType是TYPE_APPLICATION_STARTING。目的是告訴用戶,系統已經接受到操作,正在響應,在程序初始化完成后實現目的UI,同時移除這個窗口。

這個StartingWindow就是我們要討論的白屏和黑屏的“元兇”,一般情況下我們會對Application和Activity設置Theme,系統會根據設置的Theme初始化StartingWindow。Window布局的頂層是DecorView,StartingWindow顯示一個空DecorView,但是會給這個DecorView應用這個Activity指定的Theme,如果這個Activity沒有指定Theme就用Application的(Application系統要求必須設置Theme)。

上述內容是后來更新,特別感謝高山流水29同學和爵小友的指正。

在Theme中可以指定窗口的背景,Activity的ICON,APP整體文字顏色等,如果說沒有指定任何屬性,就會用默認的屬性,也就是上文中提到的空DecorView,所以我們的白屏和黑屏和空DecorView息息相關,我們給APP設置的Style就決定了是白屏還是黑屏。

1、如果選擇了Black的系列的主題那么Activity跳轉的時候就是黑屏:

@android:style/Theme.Black"
  • 1
  • 1

2、如果選擇了Light的系列的主題那么Activity跳轉的時候就是白屏:

@android:style/Theme.Light"
  • 1
  • 1

解決辦法

通常的解決辦法都是給Activity設置一個透明背景的主題:

<style name="SplashTheme" parent="AppTheme"><item name="android:windowFullscreen">true</item><item name="android:windowIsTranslucent">true</item> </style>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

如上設置后APP和Activity啟動時,我們的StartingWindow會應用我們這個透明背景的主題,跳轉時確實沒有白屏和黑屏了,但是這樣設置會產生如下后果:

1、給SplashActivity設置后,用戶點擊我們APP圖標后,需要等待2秒左右的時候才會顯示contentView。造成了APP啟動速度慢的假象,其實Activity已經啟動了,只是background是透明的,這時候你點擊桌面的其他地方是無效的。這樣就和Google的初衷背道而馳了,所以還要繼續往下看。?
2、給其他Activity設置后,會導致通過overridePendingTransition設置的啟動關閉Activity的動畫無效。需要在style中重新寫如下幾個動畫:

<style name="AppTheme" parent="AppBaseTheme"> <item name="android:windowAnimationStyle">@style/Animation.Activity.Translucent.Style</item> <item name="android:windowFullscreen">true... <item name="android:windowIsTranslucent">true... </style><style name="Animation.Activity.Style" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">... <item name="android:activityOpenExitAnimation">... <item name="android:activityCloseEnterAnimation">... <item name="android:activityCloseExitAnimation">... </style><style name="Animation.Activity.Translucent.Style" parent="@android:style/Animation.Translucent"> <item name="android:windowEnterAnimation">... <item name="android:windowExitAnimation">... </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3、Activity之間的跳轉可能偶爾會看到桌面一閃而過(如果SplashActivity和其他Activity都設置了透明)。

小結:一般情況下是只會給SplashActivity設置一個透明背景的主題,其他Activity不會設置,經過實踐,這種體驗是最好的。但是如果要做到APP秒開還是不行的,和我們的文章開頭所分析的原理相斥了。

秒開方案

那像媽媽去哪兒、美團、淘寶等APP是如何實現秒開的?其實看完上面的原理分析,這個基本上也就明白了。

還是從Activity的Theme下手,既然可以讓Window白屏黑屏或者透明,那么是不是可以設置其他顏色或者圖片來實現APP的秒開呢?答案是肯定的。

原理

我們之前設置了Window透明,實現了去掉白屏和黑屏,現在要弄一個顏色或者圖片來代替白屏和黑屏,所以首先要把原來style中的透明屬性去掉。然后給Window設置一個背景顏色或者圖片。

實現步驟

1、首先在res/drawable下新建一個layer-list,名字隨便取,比如splash.xml:

<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"><!-- 背景顏色 --><item android:drawable="@color/white" /><item><!-- 圖片 --><bitmap android:gravity="center"android:src="@drawable/wel_page" /></item> </layer-list>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

layer-list大家都會寫吧,上面是背景顏色,下面是一張圖,這張圖可以是全屏的圖,可以是一張小圖。如果是全屏的圖,那上面的顏色也可以不用設置,如果是小圖,就要指定下顏色了,并且可以指定圖片在位置。

2、給主題設置Window背景:

<style name="SplashTheme" parent="AppBaseTheme"><!-- 歡迎頁背景引用剛才寫好的 --><item name="android:windowBackground">@drawable/splash</item><item name="android:windowFullscreen">true</item><!-- <item name="android:windowIsTranslucent">true</item> --> <!-- 透明背景不要了 --> </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

上面的<item name="android:windowBackground">可以用我們上面的layer-list作為背景,當然也可以設置個全屏的圖片。

3、在AndroidManifest.xml中定義SplashActivity的theme為SplashTheme:

<activity android:name=".SplashActivity"android:theme="@style/SplashTheme"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter> </activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、SplashActivity的實現,在onCreate()啟動你的MainActivity即可,其他什么都別干:

public class SplashActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);startActivity(new Intent(this, MainActivity.class));finish();} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

特別注意:為保證啟動速度,SplashActivity不要調用setContentView()方法。因為Activity設置了layout,它在App完全初始化完成后才會顯示,也會耗時。使用該啟動畫面實現也能兼容到上面說的白屏和黑屏的問題。跟上面的小結一樣,其他Activity不要設置。

特別更新:博客剛發不久,有人跟我吐槽說,SplashActivity中需要做一個初始化的操作,被我放哪里了?可能是因為在上面第四點中說了個直接啟動MainActivity其他什么都不別干,這里可以把MainActivity換成別的InitializeActivity,初始化、引導頁的判斷可以放在這里,這里都操作完了再啟動MainActivity?、CoreActivity等即可。

當然大多數必要的初始化可以放在Application中(建議再啟動一個子線程),因為你的進程說不定什么時候就被系統回收了,這時候直接啟動時是啟動被系統回收的時候正處于Resume狀態的那個Activity,那你的初始化的`Activity就不會被執行了。

參考:?
http://cyrilmottier.com/2013/01/23/android-app-launching-made-gorgeous/?
https://www.bignerdranch.com/blog/splash-screens-the-right-way/

總結

以上是生活随笔為你收集整理的Android Splash闪屏页秒开 Activity白屏、Activity黑屏问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。