current position:Home>New jetpack member splashScreen: create a new app launch screen

New jetpack member splashScreen: create a new app launch screen

2022-01-26 23:41:28 TechMerger

Android 12 Newly introduced in Splash Screen function , Can effectively create freedom 、 Rich application startup effect . But low version devices that still dominate the market , How can I taste fresh ? The answer is Jetpack New members of SplashScreen library , Let's explore its usage and the principle behind it !

Preface

As early as Android 12 Preview When the edition was published , I noticed the cool Splash Screen function , Quickly customize and share various startup effects created with it , Received a lot of positive feedback . It's a great honor : be responsible for Splash Screen Functional Google The engineer also gave me Demo I like it , Also forwarded !

But many developers say Android 12 The effect is certainly good , can 12 The previous version is the mainstream , If it's not compatible , There are some chicken ribs . Including me , They are very concerned about how to apply this new feature in the lower version .

Read this Google Engineer's history tweets , Unexpected discovery not long ago AndroidX Bao has just launched a program called SplashScreen The same name of API. We all know AndroidX ascription Jetpack, Is independent of SDK A collection of development frameworks other than version , Obviously, it is used to be compatible with lower versions Splash Screen Function library .

This is timely rain , We must study , Give Way Splash Screen Function, give full play to its role ! In addition, the article shared before did not mention the implementation principle , This paper discusses .

1. New blood SplashScreen

Jetpack SplashScreen Is backward compatible Android 12 Splash Screen Function development library . Its earliest support to Android 6(API 23), Global Android In the device 6 The occupancy rate of versions and above has reached 9 become above , It's quite enough .

1.1 Functions and limitations

Splash Screen The startup screen created by the function is divided into Approach and Exit Two parts : The former is responsible for showing Icon、Icon Animation and brand Logo Etc , The latter is used to show the whole or Icon The animation effect of the view transition to the target picture .

For the exit part , Whether or not running in 12 On ,Jetpack SplashScreen Libraries can reach Android 12 The same effect ; But if the entry part is running on a lower version , There are some limitations for the time being .

  • Display is not supported temporarily Icon Animation :AnimatedVectorDrawable
  • Configuration is not supported Icon background :IconBackgroundColor
  • Brand setting is not supported temporarily Logo:BrandingImage
Function comparison of mobilization part Jetpack edition Android 12 edition
ScreenBackground YES YES
ScreenIcon YES YES
AnimatedVectorDrawable NA YES
IconBackgroundColor NA YES
BrandingImage NA YES

remarks : I'll talk about it later SplashScreen Implementation principle of Library , The entry effect for lower versions is essentially a LayerDrawable. Tell the truth , For support Vector Drawable Animation 、Adaptive Icon The background is powerless . But the author believes that some additional processing should be added at the code level , It can be perfectly supported , I look forward to improving it in the later upgrade !

2.2 Import dependence

SplashScreen The latest version of the library is 1.0.0-alpha01,Gradle Just rely on it .

dependencies {
    def core_version = "1.6.0"
    ...
    // Optional - APIs for SplashScreen, including compatiblity helpers on devices prior Android 12
    implementation "androidx.core:core-splashscreen:1.0.0-alpha01"
}
 Copy code 

2.3 SplashScreen Library preset theme

SplashScreen The library defines a special for the creation of the startup screen Attr, Setting up Icon And the background of the picture windowSplashScreenAnimatedIcon and windowSplashScreenBackground, And after setting the startup screen to exit Activity The theme of postSplashScreenTheme etc. .

The lower version does not support Icon Animation , It's not about configuration time , But the library still provides related properties windowSplashScreenAnimationDuration, The reason is not clear .

<attr format="reference" name="postSplashScreenTheme"/>
<attr format="reference" name="windowSplashScreenAnimatedIcon"/>
<attr format="integer" name="windowSplashScreenAnimationDuration"/>
<attr format="color" name="windowSplashScreenBackground"/>
 Copy code 

In addition, in order to simplify App End configuration , Also preset theme , At the same time, the device versions are distinguished .

The following are topics for lower versions :

<style name="Theme.SplashScreen" parent="Theme.SplashScreenBase"> <item name="postSplashScreenTheme">?android:attr/theme</item> <item name="windowSplashScreenAnimationDuration">@integer/default_icon_animation_duration</item> <item name="windowSplashScreenBackground">@android:color/background_light</item> <item name="windowSplashScreenAnimatedIcon">@android:drawable/sym_def_app_icon</item> </style>

<style name="Theme.SplashScreenBase" parent="android:Theme.NoTitleBar"> <item name="android:windowBackground">@drawable/compat_splash_screen</item> <item name="android:opacity">opaque</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:fitsSystemWindows">false</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:navigationBarColor">@android:color/transparent</item> </style>
 Copy code 

The key is the parent theme SplashScreenBase Set up windowBackground attribute , It points to Drawable Responsible for displaying the startup screen of the lower version .

The principle is simple : Read windowSplashScreenBackground Setting background ColorDrawable and windowSplashScreenAnimatedIcon Set icon Drawable, Icon Drawable Place in the background Drawable In the middle of , And then combine it into Layer Drawable. honestly , It is similar to our previous idea of customizing the startup screen .

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:gravity="fill">
        <color android:color="?attr/windowSplashScreenBackground" />
    </item>
    <item android:drawable="?attr/windowSplashScreenAnimatedIcon" android:gravity="center" android:width="@dimen/splashscreen_icon_size" android:height="@dimen/splashscreen_icon_size" />
</layer-list>
 Copy code 

because 12 Version provides Splash Screen System properties of functions , So for 12 And the above topics , You only need to convert the attributes defined by the library into system attributes .

<style name="Theme.SplashScreen" parent="android:Theme.DeviceDefault.NoActionBar"> <item name="android:windowSplashScreenAnimatedIcon">?windowSplashScreenAnimatedIcon</item> <item name="android:windowSplashScreenBackground">?windowSplashScreenBackground</item> <item name="android:windowSplashScreenAnimationDuration"> ?windowSplashScreenAnimationDuration</item> </style>
 Copy code 

2. Create an entry effect

In the original Demo Adapt to the new API, Feel a lack of novelty . I used to use Jetpack Compose Retro Flappy Bird The game didn't have time to design the startup screen , Then this time use Jetpack Of SplashScreen Improve the library .

2.1 Prepare animated icons

Flappy Bird Game Logo It's a bird , At present, there is only one PNG, To customize Icon The animation effect should be changed to SVG.

Found a lot of tools , Finally found a way to PNG The perfect conversion to SVG Website : Support to add and delete various color areas , Then each color block can be restored to the greatest extent , Every Path.

www.pngtosvg.com/

adopt AS Self contained Vector Asset Tool and Animated Vector Drawable label , Can be SVG Expand into vector graphics animation file with format effect .

<animated-vector ...>
    <aapt:attr name="android:drawable">
        <vector android:width="400dp" android:height="404.73373dp" ...>
            <group android:name="BirdGroup" android:pivotX="200" android:pivotY="202" android:rotation="0">
                <path android:fillColor="#503745" android:fillType="evenOdd" android:pathData="M173.7,133.065C173.419,133.178 ..." android:strokeColor="#00000000" />
                ...
            </group>
        </vector>
    </aapt:attr>

  <target android:name="BirdGroup">
    <aapt:attr name="android:animation">
      <set>
        <objectAnimator android:duration="@integer/icon_animator_duration" android:interpolator="@android:anim/decelerate_interpolator" android:propertyName="translateX" android:valueFrom="@integer/icon_animator_translate_from" android:valueTo="@integer/icon_animator_translate_to" />
        ...
      </set>
    </aapt:attr>
  </target>

</animated-vector>
 Copy code 

2.2 Adaptive theme

Android 12 Up to the entrance Activity Appoint Splash Screen The relevant attributes of the function can achieve the mobilization effect .SplashScreen Library is the same idea , But to simplify the code , We can give Activity Configure the theme preset by the library .

because App The client should assign unique resources to these attributes , So the theme needs to be simply expanded , At the same time, we should also distinguish between versions . If you happen to support at the earliest Android 6 Words , Configure the default theme and orientation 12 Of values-v31 The theme is just , Otherwise, you need to configure the oriented 6~11 Of values-23 The theme .

The default theme must be extended from the default theme Theme.SplashScreen, At the same time, rewrite Icon、Duration and ScreenBackground Three attributes . Because of 12 Some properties of the theme are consistent with the default theme , So draw out the common parts to Base Medium multiplexing .

<style name="JetpackSplashTheme" parent="JetpackSplashTheme.Base">
</style>

<style name="JetpackSplashTheme.Base" parent="Theme.SplashScreen"> ... <item name="windowSplashScreenAnimatedIcon">@drawable/ic_icon_bird_small_animated_translate</item> <item name="windowSplashScreenAnimationDuration">@integer/icon_animator_duration</item> <item name="windowSplashScreenBackground">@color/appBackground</item> <item name="postSplashScreenTheme">@style/SplashActivityTheme</item> </style>

<style name="SplashActivityTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="colorPrimary">@color/purple_500</item> <item name="colorPrimaryDark">@color/purple_700</item> <item name="colorAccent">@color/teal_200</item> </style>
 Copy code 

One caveat , You'd better specify postSplashScreenTheme attribute . Because the subsequent customization effect needs to use SplashScreen class , And it will strictly check the configuration that requires this property , Otherwise it will happen Crash.

Cannot set AppTheme. No theme value defined for attribute postSplashScreenTheme.

in addition , Most of the Activity Generally inherited from AppCompat Framework provided Activity, The frame requires that the screen must be configured AppCompat Department theme . in other words ,postSplashScreenTheme Attribute should not only specify , It has to be AppCompat Department theme !

remarks :AppCompat The reason why the framework makes this restriction , You can check in the previous article 「 In depth reading Jetpack The cornerstone of the framework -AppCompat」.

You need to use a Theme.AppCompat theme!

By reusing common topics , oriented 12 You only need to specify Icon Background properties IconBackgroundColor And brand Logo attribute BrandingImage.

<style name="JetpackSplashTheme" parent="JetpackSplashTheme.Base"> <item name="android:windowSplashScreenIconBackgroundColor">@color/skyBlue</item> <item name="android:windowSplashScreenBrandingImage">@drawable/ic_tm_brand_newer</item> </style>
 Copy code 

The following are running on Android 8.1 and 12 The entry effect of the startup screen on the , The animation of birds entering from the left and gradually enlarging .

Another example is that the bird rotates to enlarge the entry animation .

in fact Animated Vector Drawable Supported by the Path Animation is more cool and flexible , Can create a richer animation experience , You can try !

2.3 Optimize the entry of the lower version Icon

by force of contrast , You can see 8.1 It's really not shown in the entry effect of Icon Animation , either Icon Background and brand Logo. In order to be as close as possible to 12 The approach effect is close to , You can change the icon attribute of the lower version theme to Adaptive Icon, oriented 12 Use animation for your theme Icon.

<!--  Default theme : oriented 12 Previous version  -->
<style name="JetpackSplashTheme" parent="JetpackSplashTheme.Base"> <!-- Adaptive icon drawable --> <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher_bird_final</item> </style>

<!--  oriented 12 Version of  -->
<style name="JetpackSplashTheme" parent="JetpackSplashTheme.Base"> <!-- Animated vector drawable --> <item name="windowSplashScreenAnimatedIcon">@drawable/ic_icon_bird_small_animated_translate</item> ... </style>
 Copy code 

3. Extend the splash screen

3.1 obtain SplashScreen Custom entrance

After the above theme is configured, the mobilization effect can be realized , But in order to further control the startup screen or customize the exit effect , You have to get the entrance of control, that is SplashScreen class .SplashScreen The library provides installSplashScreen().

class MainActivity : ComponentActivity() {
    private val viewModel: GameViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        // Need to be called before setContentView or other view operation on the root view.
        val splashScreen = installSplashScreen()

        setContent { ... }
        
        SplashScreenController(splashScreen, viewModel).apply {
            customizeSplashScreen()
        }
    }
}
 Copy code 

There is one thing to note :installSplashScreen() Must precede setContentView() call , The reason lies in install Function gets postSplashScreenTheme Property to specify the topic , And after passing the inspection setTheme to Activity.

It needs to be clear :install The function just performs the initialization of topics and resources , The exit view has not been loaded at this time .

3.2 Control the display duration of the startup screen

When App The first frame of the drawing begins , Start screen Window namely Splash Screen Window Will exit . If the drawing has begun , But some of the key logic has not been implemented yet , This will affect the complete presentation . At this time, we can appropriately extend the startup screen , Let the user wait a little longer .

Android 12 There is no provision to control the start-up time API, Previous Demo It's through ContentView register OnPreDrawListener The callback is implemented by suspending the drawing .( Hanging strokes indirectly leads to Splash Screen Window Delayed exit , So as to achieve the purpose of extending the startup screen .)

SplashScreen The library provides dedicated services API To deal with this need , namely KeepOnScreenCondition. We need to inform SplashScreen Conditions that need to be continuously displayed , Before conditions are destroyed WMS Will maintain its display . In fact API The implementation principle of is consistent with the previous idea .

class SplashScreenController( ... ) {
    fun customizeSplashScreen() {
        keepSplashScreenLonger()
        ...
    }

    // Keep splash screen showing till data initialized.
    private fun keepSplashScreenLonger() {
        splashScreen.setKeepVisibleCondition { !viewModel.isDataReady() }
    }
}
 Copy code 

It can be seen that the display time of the startup screen has obviously increased .

4. Custom exit effect

In order to make the startup screen transition to the target screen perfectly , Customization of exit effect is particularly important . And compared with entering the field, you can only customize Icon Animation , Exit can customize the whole and Icon All kinds of animation , More space , And more flexible .

4.1 Perform exit animation

Splash Screen Window At the time of exit , It's time to perform the exit animation . adopt SplashScreen Library provides the OnExitAnimationListener API You can get this opportunity , It will also return to the splash screen view , Convenient for subsequent customization .

differ Android 12,SplashScreen The library startup screen view is uniformly encapsulated in SplashScreenViewProvider in . This API The corresponding view will be returned according to the version : The lower version is custom FrameLayout,12 Is version specific SplashScreenView.

fun customizeSplashScreen() {
    ...
    customizeSplashScreenExit()
}

// Customize splash screen exit animator.
private fun customizeSplashScreenExit() {
    splashScreen.setOnExitAnimationListener { splashScreenViewProvider ->
        val onExit = {
            splashScreenViewProvider.remove()
        }
        showSplashExitAnimator(splashScreenViewProvider.view, onExit)
        showSplashIconExitAnimator(splashScreenViewProvider.iconView, onExit)
    }
}
 Copy code 

No matter which version is running , Provided through a unified SplashScreenViewProvider example , Can perform consistent animation effects .

For example, zoom and fade out animation for the overall view .

private fun showSplashExitAnimator(splashScreenView: View, onExit: () -> Unit = {}) {
    val alphaOut = ObjectAnimator.ofFloat(
        splashScreenView,
        ...
    )

    val scaleOut = ObjectAnimator.ofFloat( ... )

    AnimatorSet().run {
        duration = defaultExitDuration
        interpolator = AnticipateInterpolator()
        playTogether(scaleOut, alphaOut)
        start()
    }
}
 Copy code 

in the light of Icon Zoom the view 、 Fade out and displacement animation . The purpose is to make the bird gradually shrink and move up to the game screen , That is, seamless transition to the game area .

private fun showSplashIconExitAnimator(iconView: View, onExit: () -> Unit = {}) {
    val alphaOut = ObjectAnimator.ofFloat(
        iconView,
        ...
    )
    val scaleOut = ObjectAnimator.ofFloat( ... )
    val slideUp = ObjectAnimator.ofFloat( ... )

    AnimatorSet().run {
        ...
        playTogether(alphaOut, scaleOut, slideUp)
        doOnEnd {
            onExit()
        }
        start()
    }
}
 Copy code 

Be careful : After the exit animation, be sure to call remove() Manually remove the view , Otherwise, you may see that the startup screen is covered all the time App On , Can't disappear . about 12 Come on , This is actually what the system returns SplashScreenView Surface It remains on the picture all the time , The lower version is FrameLayout Still exist ContentView In the tree .

4.2 Optimize exit animation duration

App When you start drawing , Whether or not the approach animation is completed ,Splash Screen Window Will quit , Perform preset exit animation at the same time . The performance of the equipment is good or bad or the load state is different , It will affect App When to start painting , Therefore, the execution time of exit animation is not fixed , As the condition of the equipment changes slightly .

  • If App Draw early , The approach animation may not be finished yet . In order to make users see the target content faster , Exit animation can shorten the execution time , For example, directly use the remaining duration of the approach animation

  • contrary , If you draw late , The entry animation is long over . If the exit animation takes up more time , That will seriously delay users from seeing the target content , cause Start Caton Bad impression of . So at this point , Exit animations can be executed for a short fixed duration , You can not even execute

let me put it another way , Exit animation is intended to buffer and transition loaded in the background , You can't sacrifice the launch experience just to show the animation , The occupation time of exit can be flexibly controlled .

For the convenience of calculation Icon The rest of the animation ,SplashScreen The library provides a way to get its start time and total time API:

/** * Start time of the icon animation. * * On API 31+, returns the number of millisecond since the Epoch time (1970-1-1T00:00:00Z) * * Below API 31, returns 0 because the icon cannot be animated. */
public val iconAnimationStartMillis: Long get() = impl.iconAnimationStartMillis

/** * Duration of the icon animation as provided in attr. */
public val iconAnimationDurationMillis: Long get() = impl.iconAnimationDurationMillis
 Copy code 

The following code demonstrates how to judge whether the next entry animation is completed before the exit animation is executed , If it's finished, use the remaining time of the animation , Otherwise, the execution will be abandoned .

private fun getRemainingDuration(splashScreenView: SplashScreenViewProvider): Long {
    // Get the duration of the animated vector drawable.
    val animationDuration = splashScreenView.iconAnimationDurationMillis

    // Get the start time of the animation.
    val animationStart = splashScreenView.iconAnimationStartMillis

    // Calculate the remaining duration of the animation.
    return if (animationDuration == 0L || animationStart == 0L)
        defaultExitDuration
    else (animationDuration - SystemClock.uptimeMillis() + animationStart)
        .coerceAtLeast(0L)
}
 Copy code 

As mentioned earlier, the lower version does not support Icon Animation , Naturally, there is no need to calculate the remaining time . So if you run on a lower version , these two items. API Always return the default value 0, Noteworthy !

private open class ViewImpl(val activity: Activity) {
    open val iconAnimationStartMillis: Long get() = 0
    open val iconAnimationDurationMillis: Long get() = 0
    ...
}
 Copy code 

5. SplashScreen Realization principle

Android 12 The source code of has not been made public , The following for Jetpack SplashScreen The source code of the library .※ I thought before SplashScreen Library provides the API Simple and clear , The principle should not be complicated . But after delving into the source code, I found , Many details are inconsistent with speculation , It's worth rethinking .

5.1 Overall framework

Activity adopt SplashScreen Library provides the SplashScreen The instance can obtain the entry of the control startup screen , Its internal will be based on OS Version decided to adopt 12 Exclusive API Or customize the view , To show 、 Delay or remove the startup screen .

5.2 installSplashScreen

obtain SplashScreen Example of installSplashScreen() The target will be read and set Activity Of Theme. If running on a lower version , You also need to get Icon and Background Configuration of . Now just get , Custom views for exit are not added .

5.3 setKeepVisibleCondition

adopt setKeepVisibleCondition() Can extend the display of the startup screen , Irrelevant running version , The principle is to ContentView Of ViewTreeObserver register OnPreDrawListener Callback to implement . When the drawing is released , In the lower version, you need to manually execute the exit callback ,12 The system will execute by itself .

At this time, the custom view for exit has not been added yet , Just delayed Splash Screen Window Just quit .

5.4 setOnExitAnimationListener

setOnExitAnimationListener() You can monitor the exit time ,SplashScreen The splash screen view is ready to be encapsulated in SplashScreenViewProvider in , Then when the startup screen needs to exit , adopt OnExitAnimationListener Interface callback .

There are many views related processing in the lower version , need inflate A custom layout and add to ContentView in , And then install Ready background and icon Reflected in .

Custom layout added for lower versions :

<FrameLayout ...>

  <ImageView android:id="@+id/splashscreen_icon_view" android:layout_width="@dimen/splashscreen_icon_size" android:layout_height="@dimen/splashscreen_icon_size" android:layout_gravity="center" />

</FrameLayout>
 Copy code 

5.5 adjustInsets Special treatment

SplashScreenViewProvider After initialization, an additional call will be made adjustInsets(), And only for the lower version can the specific logic be realized . Let's study the purpose of this special treatment .

Let's look at the comments of the function first :

Adjust the insets to avoid any jump between the actual splash screen and the SplashScreen View.

It literally means to avoid the splash screen and SplashView Jump between views , You need to adjust the parameters of the lower view . I don't seem to understand , Combined with the specific implementation of the function :

private class Impl23(activity: Activity) : Impl(activity) {
    override fun adjustInsets( view: View, splashScreenViewProvider: SplashScreenViewProvider ) {
        // Offset the icon if the insets have changed
        val rootWindowInsets = view.rootWindowInsets
        val ty =
            rootWindowInsets.systemWindowInsetTop - rootWindowInsets.systemWindowInsetBottom
        splashScreenViewProvider.iconView.translationY = -ty.toFloat() / 2f
    }
}
 Copy code 

default adjustInsets() No specific implementation , Only the lower version has a specific implementation , That's why ?

The content of the processing is very straightforward : monitor SplashScreenViewProvider It's stored in the warehouse View Layout changes , Get from rootWindowInsets, Will cover in Window The height difference between the status bar and the navigation bar is taken as the median , And then Icon The view moves up or down .

  • The previous principle mentioned that the entry effect of too low version is actually a Layer Drawable It's set to Window Background On ,Icon In the Drawable The position in the is centered , therefore Icon stay Splash Screen Window It's also completely centered
  • But the screen view of the exit effect is not Window Background Drawable, But to ContentView Manually added in Framelayout Layout . For layout ,Icon The view is centered , But for what it belongs to Window Come on , Because of the top Statusbar And the bottom NavigationBar Different heights , Final Icon View in Window The overall position is not completely centered . Especially when the equipment adopts Gesture Navigation In navigation mode ,Icon The lower view is more obvious
  • 12 Your exit view can be said to be Splash Screen Window A full copy of , It's not custom ContentView Sub layout , There is no such problem

In conclusion , Without intervention , On the lower version, from the entry Window Background To the exit FrameLayout when ,App Of Icon There will be a sense of disobedience and dislocation or jumping !

5.6 remove

setOnExitAnimationListener After calling ,SplashScreen The library will call back the view of the startup screen , After executing the exit animation, you need to call remove() Manually remove the view , Its principle is very simple :

  • 12 It was before that FrameLayout from ContentView Remove... From the tree
  • 12 Is to call a dedicated API namely SplashScreenView#remove()

6. API summary

Yes SplashScreen Library several key API Make a clean up :

API explain
SplashScreen Jetpack Get the class of customized startup screen entry
Activity#installSplashScreen() overwrite Activity, The static member function used to get the custom entry
setKeepVisibleCondition Specify the conditions for maintaining the display of the startup screen
KeepOnScreenCondition Interface to realize display conditions
setOnExitAnimationListener Monitor the exit time of the startup screen
OnExitAnimationListener Callback interface for exit of startup screen
SplashScreenViewProvider Customize the startup screen view of exit effect

And on and on Android 12 Make a simple comparison between the versions provided :

Attr contrast Jetpack edition Android 12 edition
Designated target Activity The theme postSplashScreenTheme -
Assign animation Icon windowSplashScreenAnimatedIcon android:windowSplashScreenAnimatedIcon
Specifies the background of the splash screen windowSplashScreenBackground android:windowSplashScreenBackground
Appoint Icon Animation duration windowSplashScreenAnimationDuration android:windowSplashScreenAnimationDuration
Appoint Icon background - android:windowSplashScreenIconBackgroundColor
Designated brand Logo - android:windowSplashScreenBrandingImage
API contrast Jetpack edition Android 12 edition
Start screen custom entry class androidx.core.splashscreen.SplashScreen interface android.window.SplashScreen
Get the entry instance Activity#installSplashScreen() Activity#getSplashScreen()
Launch screen view SplashScreenViewProvider SplashScreenView

7. this paper Demo

Open source address :github.com/ellisonchan…

adapter Splash Screen After the function Compose edition Flappy Bird The overall effect of the game :

8. Outstanding issues

Through the above description, we already know : Launch screen showing exit effect on lower version , In essence, it is temporarily added to App Inside FrameLayout. and 12 Obviously not in this way , adopt Dump The command found that no additional... Was created when exiting Window.

  • that 12 On the startup screen Window Provide to... After exiting App Custom exit effect SplashScreenView What is it ?
  • If this “View” Does not belong to App In itself , that App Be able to access it and make changes to properties , How is it realized ?

When I decided to put this doubt aside , Stumble upon 12 During the execution of the upper startup screen, it will print Splash System log of related keywords :

StartingSurfaceDrawer: addSplashScreen com.ellison.flappybird: nonLocalizedLabel=null theme=7f1000e7 task= 334 StartingSurfaceDrawer: window attributes color: ffecfcdd icon android.graphics.drawable.AnimatedVectorDrawable... StartingSurfaceDrawer: fillViewWithIcon surfaceWindowView android.window.SplashScreenView... StartingSurfaceDrawer: Copying splash screen window view for task: 334 parcelable? android.window.SplashScreenView$SplashScreenViewParcelable StartingSurfaceDrawer: Task start finish, remove starting surface for task 334 StartingSurfaceDrawer: Removing splash screen window for task: 334

So I made a bold guess ,StartingSurfaceDrawer Responsible for passing WMS Read 、 Show and remove App Set up Splash Screen Window View . And in Window Pass... Before exiting WMS Inform the target Activity Of PhoneWindow, from Splash Screen Window Restore view in , Then recover the SplashScreenView Add to App On the screen . because PhoneWindow Direct holding DecorView, So it may be attached directly to DecorView Up .

StartingSurfaceDrawer Who the hell is 、 Whether the guess is correct and the specific details , Still to be seen 12 Open the source code and then do in-depth research ~

Conclusion

At first, it was speculated that Android 6 The above version has become the mainstream of the market , Just decided to let SplashScreen The library is compatible with this version at the earliest . When we explore the principle later , Found its internal call adjustInsets() Processing depends on one version 6 Just joined in API, So I feel that this is compatible with 6 The real reason .

Compatible to Android 6 Is the version due to occupancy or is it from API The limitations of are no longer important , The key is Splash Screen Enough functions have been supported Android equipment .

You said before Android 12 all-new Splash Screen Although the function is cool , But not compatible with lower versions , A little chicken ribs . Now there is Jetpack SplashScreen The blessing of the library , It's time to fit ?

Reference material

SplashScreen file

A peek inside Jetpack Core Splashscreen

Meet the Jetpack Splashscreen API: a definitive guide for splash screens in Android

Recommended reading

Android 12 New app launch screen on the Internet , It doesn't fit ?

With one : use Compose Perfect reproduction Flappy Bird!

from Preference The change of components Jetpack The past and this life

In depth reading Jetpack The cornerstone of the framework -AppCompat

copyright notice
author[TechMerger],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201262341175805.html

Random recommended