[@capacitor/splash-screen] Android 8–11: failed Android 12 API attempt leaves a pre-draw hold, so nothing is drawn for launchShowDuration

Đang mở Phù hợp với người mới
#2,635 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
88/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
android, java
Lĩnh vực
frontend, mobile

Hướng nghiên cứu

Tìm đoạn mã của plugin màn hình khởi động Android, nơi showOnLaunch() gọi showWithAndroid12API() và chuyển sang đường dẫn cũ show(). Issue cung cấp một bản vá để kiểm tra phiên bản SDK trước khi gọi API Android 12. So sánh thay đổi đó với hành vi hiện tại và xác minh Android 8–11 sử dụng màn hình khởi động cũ, còn Android 12+ tiếp tục dùng đường dẫn hiện tại.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

platform: android

🤖 Automated review by Claude — posted via @ibrahimkhatib365's account; not written by them personally.

Bug Report

Plugin(s)

@capacitor/splash-screen 8.0.2. The same code is in every version from 4.x through 8.0.3 nightly, 9.0.0-alpha.2 and the current 9.0 dev builds.

Capacitor Version
Latest Dependencies:

  @capacitor/cli: 8.6.0
  @capacitor/core: 8.6.0
  @capacitor/android: 8.6.0
  @capacitor/ios: 8.6.0

Installed Dependencies:

  @capacitor/cli: 8.5.2
  @capacitor/core: 8.5.2
  @capacitor/android: 8.5.2
  @capacitor/ios: 8.5.2

[success] Android looking great! 👌
Platform(s)

Android 8–11 (API 26–30). Android 12+ is not affected.

Current Behavior

On Android 8–11, showOnLaunch() calls showWithAndroid12API() first. On those versions the attempt does the following:

  1. installSplashScreen() succeeds. The compat library supports API 23+.
  2. setKeepOnScreenCondition(() -> isVisible || isHiding) succeeds. Below API 31, the compat SplashScreen.Impl adds an OnPreDrawListener to android.R.id.content right away.
  3. With the default launchFadeOutDuration (200), setOnExitAnimationListener() then throws, because building the compat SplashScreenViewProvider needs Theme.SplashScreen attributes that a normal launch theme doesn't have.

The catch logs Android 12 Splash API failed... using previous method. and falls back to show(..., true). However, the compat pre-draw listener from step 2 is still registered, and the legacy path then sets isVisible = true. As a result, the activity's content is held back from drawing for the entire launchShowDuration. The legacy splash window shares the activity's window token, so it doesn't appear while the activity hasn't drawn either.

The visible result depends on timing:

  • On a cold launch, the first draw usually happens before isVisible flips, so the splash shows normally.
  • When the activity is recreated in an existing process (for example, after closing it with Back and reopening it from the launcher), the hold wins. Nothing of the app is drawn for launchShowDuration, and then the app appears at once.

On an Android 9 emulator with launchShowDuration: 3000, the reopen after Back logs Displayed .MainActivity: +3s426ms, and the next line in the log is SplashScreen was automatically hidden after the launch timeout. With a translucent launch theme, the launcher stays on screen for the whole 3.4 s. With an opaque launch theme, the window background shows instead of the plugin's splash.

The 9.x change to the default launchFadeOutDuration (0, #2526) makes this worse below Android 12. Step 3 no longer throws, so the plugin never reaches the legacy path. It only holds the first frame for launchShowDuration behind the theme's window. With launchFadeOutDuration: 0 on 8.0.2, Android 9 showed no splash at all on either a cold launch (+4.4 s) or a reopen (+3.2 s), only the launcher until the app appeared.

Expected Behavior

On Android 8–11, the legacy splash shows right away and the activity isn't held. That is what happens on a cold launch today.

Code Reproduction

No sample repository yet. The steps on a new app:

  1. npm init @capacitor/app, add @capacitor/splash-screen, and set SplashScreen.launchShowDuration to 3000 in capacitor.config. Keep the other defaults.
  2. Optional, to make the symptom obvious: add <item name="android:windowIsTranslucent">true</item> to AppTheme.NoActionBarLaunch.
  3. Run on an API 26–30 emulator, for example Android 9.
  4. Launch the app and wait for it to finish loading, press Back, then tap the launcher icon again.
  5. The app (and the splash) are not drawn for about 3 s. adb logcat shows Android 12 Splash API failed... and an ActivityManager: Displayed time of about launchShowDuration.
Other Technical Details
  • androidx.core:core-splashscreen 1.2.0 (the plugin default)
  • Reproduced on an Android 9 (API 28) emulator
  • minSdkVersion 26
Additional Context

A guard that only uses the Android 12 API where it applies fixes this, and we now ship it as a patch:

         try {
-            showWithAndroid12API(activity, settings);
-            return;
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+                showWithAndroid12API(activity, settings);
+                return;
+            }
         } catch (Exception e) {

With this guard on Android 9, the reopen after Back shows the legacy splash immediately (Displayed +182ms). The cold launch is unchanged, and Android 12+ runs the same code as before.

Another approach is to remove the pre-draw listener in the catch. However, the compat library doesn't expose it, so skipping the attempt below API 31 seems simpler. This is related to, but separate from, #2627 and #2548, which are about how hide() removes the plugin's own pre-draw listener.

Ngôn ngữ chính
Java
Star
688
Fork
691
Merge trung bình
1 ngày 5 giờ
Pull request đã merge (30 ngày)
5

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của ionic-team/capacitor-plugins

Tất cả issue của ionic-team/capacitor-plugins

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.