Status Update
Comments
cl...@google.com <cl...@google.com>
[Deleted User] <[Deleted User]> #2
1. Have you saw crash in real device or only in simulators?
2. Do you use dynamic feature for language ID?
an...@google.com <an...@google.com> #3
Tested on Android 12 Emulator with custom executor, but cannot repro this issue.
[Deleted User] <[Deleted User]> #4
-
Second crash in the description is from a real device. Experienced it myself on two different Xiaomi phones, plus lots of crashes from users in the Google Play console.
-
Dynamic features are not used in the application.
As a wild guess, I have downgraded build tools from 31.0.0 to 30.0.3, compileSdk from 31 to 30, and moved all work with Language ID to the service in a separate process (just to be sure that crash can kill secondary process instead of main). This combination is in beta for 2 days by now and I don't see any SIGSEGV crashes.
an...@gmail.com <an...@gmail.com> #5
Hmm, I feel the crash might be something related to separate/secondary process.
I also changed compileSdk and targetSDK to 31 but still cannot repro this issue.
an...@google.com <an...@google.com> #6
On the contrary, there was no separate process before, when crashes started.
In the new build (with the aforementioned changes) I can see SIGSEGV crash, but only one instead of dozens and it has a bit different backtrace:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
liblanguage_id_jni.so (offset 0x11e000)
backtrace:
#00 pc 000000000003c7c0 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 000000000003b960 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 000000000003bb48 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 000000000003bafc /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 0000000000036c98 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 0000000000032714 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 0000000000031cac /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/split_config.arm64_v8a.apk!lib/arm64-v8a/liblanguage_id_jni.so (offset 0x11e000)
#00 pc 0000000000057438 /data/app/azagroup.reedy-mF7zTu2bv_ELlbFArwNgqA==/oat/arm64/base.odex (offset 0x57000)
[Deleted User] <[Deleted User]> #7
FYI, ML Kit launched a new language ID SDK in the latest release, which uses a new language ID model.
Could you try the new SDK version(17.0.0) to check if you can still repro this native crash? Thanks!
no...@gmail.com <no...@gmail.com> #8
Thank you, I'll try it and check.
mm...@gmail.com <mm...@gmail.com> #9
Hello. I have similar experience.
- I'm using mlkit-language 16.1.1
- I didnot meet this error until using AGP 4.2
- I can get this error since using AGP 7.0
- This error raised on Release build only(minimized by R8)
- This error raised without obfuscation.
ko...@gmail.com <ko...@gmail.com> #11
I created reproducible project.
$ git clone https://github.com/ganadist/VersionCodeDemo -b mlkit_agp7 mlkit_agp7
$ cd mlkit_agp7
$ ./gradlew :app:pPRUA
$ adb install app/build/outputs/universal_apk/productionRelease/app-production-release-universal.apk
$ adb shell am start -n com.example.myapplication/.MainActivity
$ adb logcat -b crash -d
10-19 19:41:49.844 17810 17810 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7acf9d733c in tid 17810 (e.myapplication), pid 17810 (e.myapplication)
10-19 19:41:50.473 17849 17849 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-19 19:41:50.473 17849 17849 F DEBUG : Build fingerprint: 'google/crosshatch/crosshatch:12/SPB5.210812.002/7671067:user/release-keys'
10-19 19:41:50.473 17849 17849 F DEBUG : Revision: 'MP1.0'
10-19 19:41:50.473 17849 17849 F DEBUG : ABI: 'arm64'
10-19 19:41:50.473 17849 17849 F DEBUG : Timestamp: 2021-10-19 19:41:49.903736988+0900
10-19 19:41:50.473 17849 17849 F DEBUG : Process uptime: 0s
10-19 19:41:50.473 17849 17849 F DEBUG : Cmdline: com.example.myapplication
10-19 19:41:50.474 17849 17849 F DEBUG : pid: 17810, tid: 17810, name: e.myapplication >>> com.example.myapplication <<<
10-19 19:41:50.474 17849 17849 F DEBUG : uid: 10240
10-19 19:41:50.474 17849 17849 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7acf9d733c
10-19 19:41:50.474 17849 17849 F DEBUG : x0 0000000000000000 x1 00000000000008fc x2 0000007a76760c71 x3 0000000000000000
10-19 19:41:50.474 17849 17849 F DEBUG : x4 0000000000000010 x5 0000007ba4db49d0 x6 0000007b34dc3680 x7 3de38e3900000608
10-19 19:41:50.474 17849 17849 F DEBUG : x8 0000007bb4dbedf0 x9 0000007acf9db2aa x10 0000000000000000 x11 0000007acf9d6640
10-19 19:41:50.474 17849 17849 F DEBUG : x12 0000000000000009 x13 0000000000000000 x14 0000000000000061 x15 00000000ebad6a89
10-19 19:41:50.474 17849 17849 F DEBUG : x16 0000007a767cfef8 x17 0000007d9a564b40 x18 0000007da3830000 x19 0000007feaf56a08
10-19 19:41:50.474 17849 17849 F DEBUG : x20 0000000000000000 x21 0000007ba4da50b0 x22 0000007bb4dbedf0 x23 0000007ba4da50b8
10-19 19:41:50.474 17849 17849 F DEBUG : x24 0000000000000009 x25 000000000000067e x26 0000000000000012 x27 0000000000000008
10-19 19:41:50.474 17849 17849 F DEBUG : x28 0000007b64dc8440 x29 0000000000000000
10-19 19:41:50.474 17849 17849 F DEBUG : lr 0000007a7678a964 sp 0000007feaf56810 pc 0000007a7678b7c0 pst 0000000060000000
10-19 19:41:50.474 17849 17849 F DEBUG : backtrace:
10-19 19:41:50.474 17849 17849 F DEBUG : #00 pc 000000000003c7c0 /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #01 pc 000000000003b960 /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #02 pc 000000000003bb48 /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #03 pc 000000000003bafc /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #04 pc 0000000000036c98 /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #05 pc 00000000000324a4 /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
10-19 19:41:50.474 17849 17849 F DEBUG : #06 pc 0000000000031b5c /data/app/~~mHaMq-e9ocbm9UfYnkCGkQ==/com.example.myapplication-HgG9vkluwDDO1K78-Vzr0A==/lib/arm64/liblanguage_id_jni.so (Java_com_google_mlkit_nl_languageid_internal_LanguageIdentificationJni_nativeIdentifyLanguage+100) (BuildId: 859ec0ec2000a39e6ae8ed42e1704f46)
But after downgrade to AGP 4.2, crash is not reproducible.
$ git clone https://github.com/ganadist/VersionCodeDemo -b mlkit_agp42 mlkit_agp42
$ cd mlkit_agp42
$ ./gradlew :app:pPRUA
$ adb install app/build/outputs/universal_apk/productionRelease/app-production-release-universal.apk
$ adb shell am start -n com.example.myapplication/.MainActivity
Also, I tried to disable
$ git clone https://github.com/ganadist/VersionCodeDemo -b mlkit_agp7_r8_disable_inline_optimizer mlkit_agp7_r8
$ cd mlkit_agp7_r8
$ ./gradlew :app:pPRUA
$ adb install app/build/outputs/universal_apk/productionRelease/app-production-release-universal.apk
$ adb shell am start -n com.example.myapplication/.MainActivity
va...@gmail.com <va...@gmail.com> #12
I tried the repro steps but got a NPE when I run ./gradlew :app:pPRUA
FAILURE: Build failed with an exception.
* What went wrong:
java.lang.NullPointerException
> java.lang.NullPointerException (no error message)
Could you also check if this is reproducible on 17.0.0
or 17.0.1
? If yes, could you attach the full log that I can take a look? Thanks!
si...@gmail.com <si...@gmail.com> #13
Here are gradle build scan logs for each branches.
All builds were clean build, and disabled build cache.
- mlkit_agp7 :
https://scans.gradle.com/s/qrymdqfzwokbq - mlkit_agp42 :
https://scans.gradle.com/s/b6644hzfyfhaw - mlkit_agp7_r8_disable_inline_optimizer :
https://scans.gradle.com/s/c6h5hy2nxod4u
Also, I pushed to update MLKit Language Id version 17.0.1 on
And here is crash log after apply 17.0.1
You can see that BuildId
of liblanguage_id_l2c_jni.so
was changed from 859ec0ec2000a39e6ae8ed42e1704f46
to be6e59455cc10135330c93acdebfc121
10-20 03:07:24.522 24587 24628 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7acf995426 in tid 24628 (pool-3-thread-3), pid 24587 (e.myapplication)
10-20 03:07:25.190 24710 24710 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-20 03:07:25.190 24710 24710 F DEBUG : Build fingerprint: 'google/crosshatch/crosshatch:12/SPB5.210812.002/7671067:user/release-keys'
10-20 03:07:25.190 24710 24710 F DEBUG : Revision: 'MP1.0'
10-20 03:07:25.190 24710 24710 F DEBUG : ABI: 'arm64'
10-20 03:07:25.190 24710 24710 F DEBUG : Timestamp: 2021-10-20 03:07:24.583346246+0900
10-20 03:07:25.190 24710 24710 F DEBUG : Process uptime: 0s
10-20 03:07:25.190 24710 24710 F DEBUG : Cmdline: com.example.myapplication
10-20 03:07:25.190 24710 24710 F DEBUG : pid: 24587, tid: 24628, name: pool-3-thread-3 >>> com.example.myapplication <<<
10-20 03:07:25.190 24710 24710 F DEBUG : uid: 10240
10-20 03:07:25.190 24710 24710 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7acf995426
10-20 03:07:25.190 24710 24710 F DEBUG : x0 0000007b54da9d30 x1 0000007d9a5fe7cc x2 0000000000000000 x3 0000000000000010
10-20 03:07:25.190 24710 24710 F DEBUG : x4 0000000000000000 x5 0000007c34dbc79c x6 0000002f0000083b x7 000003c300002dd5
10-20 03:07:25.190 24710 24710 F DEBUG : x8 0000000000000001 x9 0000000000000004 x10 0000000000000010 x11 0000000000000000
10-20 03:07:25.190 24710 24710 F DEBUG : x12 0000000000000000 x13 000000000000217e x14 0000007acf9932a8 x15 000000000000217e
10-20 03:07:25.190 24710 24710 F DEBUG : x16 0000000000000000 x17 0000007d9a564c78 x18 0000007a6ef18000 x19 0000007c34dbc580
10-20 03:07:25.190 24710 24710 F DEBUG : x20 0000007ca4dc7170 x21 0000007ca4dc7800 x22 0000007ca4dc71e0 x23 0000000000000000
10-20 03:07:25.190 24710 24710 F DEBUG : x24 0000000000000018 x25 0000000000000007 x26 0000000000000006 x27 0000000000000004
10-20 03:07:25.190 24710 24710 F DEBUG : x28 0000007ca4dc7090 x29 0000007cb4da9940
10-20 03:07:25.190 24710 24710 F DEBUG : lr 0000007a770a9624 sp 0000007a6f7de9c0 pc 0000007a770a96a8 pst 0000000020000000
10-20 03:07:25.190 24710 24710 F DEBUG : backtrace:
10-20 03:07:25.190 24710 24710 F DEBUG : #00 pc 00000000000386a8 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #01 pc 00000000000388a0 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #02 pc 00000000000844a0 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #03 pc 000000000008783c /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #04 pc 0000000000035fc4 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #05 pc 0000000000034954 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.190 24710 24710 F DEBUG : #06 pc 00000000000340e8 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/lib/arm64/liblanguage_id_l2c_jni.so (Java_com_google_mlkit_nl_languageid_internal_ThickLanguageIdentifier_nativeIdentifyPossibleLanguages+108) (BuildId: be6e59455cc10135330c93acdebfc121)
10-20 03:07:25.191 24710 24710 F DEBUG : #07 pc 00000000002d9a44 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #08 pc 000000000020a700 /apex/com.android.art/lib64/libart.so (nterp_helper+5648) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #09 pc 00000000000cd0dc /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #10 pc 000000000020a044 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #11 pc 00000000000ccfa8 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #12 pc 0000000000557cb4 /system/framework/arm64/boot-framework.oat (android.os.Binder.transact+148) (BuildId: 43a571a0ad85d6451b47016336a541ecb0eb12bb)
10-20 03:07:25.191 24710 24710 F DEBUG : #13 pc 000000000020b53c /apex/com.android.art/lib64/libart.so (nterp_helper+9292) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #14 pc 00000000000b7aba /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #15 pc 000000000020a044 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #16 pc 00000000000a7496 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #17 pc 000000000020a044 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #18 pc 00000000000a7360 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #19 pc 000000000020ae64 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #20 pc 000000000009e46c /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #21 pc 000000000020ae64 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #22 pc 00000000000d33d6 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #23 pc 000000000020ae64 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #24 pc 000000000009df0a /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #25 pc 0000000000209124 /apex/com.android.art/lib64/libart.so (nterp_helper+52) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #26 pc 000000000009e350 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #27 pc 000000000037b9ac /apex/com.android.art/javalib/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+988) (BuildId: ab2bf4ec264efdb6c452a238be38fe624de826b8)
10-20 03:07:25.191 24710 24710 F DEBUG : #28 pc 00000000003751d4 /apex/com.android.art/javalib/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+68) (BuildId: ab2bf4ec264efdb6c452a238be38fe624de826b8)
10-20 03:07:25.191 24710 24710 F DEBUG : #29 pc 000000000020aec4 /apex/com.android.art/lib64/libart.so (nterp_helper+7636) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #30 pc 000000000009e370 /data/app/~~KjjULZV48O7KSOgOP1wYNQ==/com.example.myapplication-vFUidUPTjaGg4oo3SRAYJw==/oat/arm64/base.vdex
10-20 03:07:25.191 24710 24710 F DEBUG : #31 pc 00000000001bf35c /apex/com.android.art/javalib/arm64/boot.oat (java.lang.Thread.run+76) (BuildId: ab2bf4ec264efdb6c452a238be38fe624de826b8)
10-20 03:07:25.191 24710 24710 F DEBUG : #32 pc 00000000002d0164 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #33 pc 000000000031ccac /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+156) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #34 pc 00000000003cf8a0 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+380) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #35 pc 0000000000460894 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+992) (BuildId: cdecb8dde1264c9871695c29854aa3b1)
10-20 03:07:25.191 24710 24710 F DEBUG : #36 pc 00000000000b1910 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: ba489d4985c0cf173209da67405662f9)
10-20 03:07:25.191 24710 24710 F DEBUG : #37 pc 00000000000513f0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: ba489d4985c0cf173209da67405662f9)
bi...@moveinsync.com <bi...@moveinsync.com> #14
Cross-posted on R8 issue tracker.
an...@google.com <an...@google.com>
[Deleted User] <[Deleted User]> #15
Hi,
Looks like we figured out the root cause in
For temporary workarounds for the existing SDKs, you need to add this rule
-keep class com.google.mlkit.nl.languageid.internal.LanguageIdentificationJni { *; }
for language-id 16.1.1
, and add this rule
-keep class com.google.mlkit.nl.languageid.internal.ThickLanguageIdentifier { *; }
for version language-id 17.0.0+
for the newer model.
We'll fix this issue in the upcoming release so that you'll not need these workarounds in the future release.
Thanks a lot for reporting this issue!
ni...@gmail.com <ni...@gmail.com> #16
Added workarounds in
ko...@gmail.com <ko...@gmail.com> #17
an...@google.com <an...@google.com> #18
Hello. Thanks, but no contributions are needed as this functionality is in progress already. We will keep you updated
ko...@gmail.com <ko...@gmail.com> #19
Is there a tracking change for it in the AOSP repo?
al...@google.com <al...@google.com> #20
Raising to P1
since this has been open for so long with no updates.
Back to Compose team for review since we have not heard from the assignee in the ~2 months it has been assigned.
ko...@gmail.com <ko...@gmail.com> #21
Only a few lines of code are needed to implement this:
- Add new parameter to
LazyListState
constructor (and torememberLazyListState
):
private val updateScrollPositionIfFirstItemMoved: Boolean = true // default to true to not break existing code, but it might be worth changing to false by default
- Update function
LazyListState.updateScrollPositionIfTheFirstItemWasMoved
to this:
internal fun updateScrollPositionIfTheFirstItemWasMoved(
itemProvider: LazyListItemProvider,
firstItemIndex: Int
): Int = if (updateScrollPositionIfFirstItemMoved) {
scrollPosition.updateScrollPositionIfTheFirstItemWasMoved(itemProvider, firstItemIndex)
} else {
firstItemIndex
}
Repeat this for LazyGridState
so the grids also can opt-out of this behavior.
There, fixed that for you.
an...@google.com <an...@google.com> #22
ap...@google.com <ap...@google.com> #23
Branch: androidx-main
commit 517482736873b04a504e85769234e059fdbc6fe7
Author: Tyler Wasniowski <tylerjames@google.com>
Date: Fri Mar 22 18:21:37 2024
Add requestScrollToItem to LazyListState.
When requestToScroll is called, we store the last requested scroll position. During the next measure pass, we will consume the last requested scroll position, scrolling there instead of to the following the previous first visible item key. The next measure pass, unless requestToScroll is called again, will still maintain index based on the first visible item key.
Relnote: For each measure-pass, the client may now opt-out of maintaining index based on the key by calling requestToScroll. This does not change existing behavior in anyway unless requestToScroll is called.
Change-Id: I98036297fdf1bdf73125c6713fe746d71d6d94a8
Test: LazyListRequestScrollTest
Fixes: 209652366
M compose/foundation/foundation/api/current.txt
M compose/foundation/foundation/api/restricted_current.txt
M compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
M compose/foundation/foundation/integration-tests/lazy-tests/src/androidTest/kotlin/androidx/compose/foundation/lazy/list/LazyCustomKeysTest.kt
A compose/foundation/foundation/integration-tests/lazy-tests/src/androidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListRequestScrollTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
ap...@gmail.com <ap...@gmail.com> #24
How should I call requestScrollToItem
to completely opt-out from maintaining index based on the key? It seems it needs to be called every measure-pass.
ty...@google.com <ty...@google.com> #25
Re
Please take a look at the test cases in
And yes, it does need to be called every time after the data changes, but before the next measure pass to ensure that you always have your desired behavior. Otherwise, every time it is not called before the measure pass, it will default to the old behavior of maintaining the first visible item by key.
va...@gmail.com <va...@gmail.com> #26
The solution that has been implemented does not fully cover our use cases. We cannot know when items change as we receive them asynchronously. Also, it is too cumbersome to add this function call to every place in the code that may change the order of items. Please implement a flag that will completely disable the behavior of maintaining the first visible item.
ty...@google.com <ty...@google.com> #27
Re:
What is your use-case? Given your desire for "a flag that will completely disable the behavior of maintaining the first visible item", do I understand correctly that you would like to maintain the same index when the data changes?
va...@gmail.com <va...@gmail.com> #28
Our use case is a list of items of various types that are sorted arbitrarily by domain-level business logic. There multiple (3+) types of interactions with list items which trigger an asynchronous update of the list that the composable receives. The composable doesn't know how the index will change on each operation. The list may be reordered, items may be removed, added, put to the end or to the top of the list. As such, it is not possible to call requestScrollToItem
within a single measure pass. And yes, the requirements are such that although the list is changing, the position of the user (scroll state) should always stay the same.
to...@gmail.com <to...@gmail.com> #29
If I may talk about some basic use case is having a list sorted by date of modification or date of last played.
The user is in the middle of the list, trigger an action on an item that can be delayed, like playing or changing something via a dialog or whatever, the database change the data is refreshed the item have changed position, the list scrolls to that item.
In a few cases it's not wanted, typically the user is doing operations at the end of a list to update things on the oldest stuff and every time he's jumped at start, or he want to play oldest stuff in order and the list keeps jumping ....
ko...@gmail.com <ko...@gmail.com> #30
I'm not the OP but my use case would be a to-do list where marking the first item done should not scroll the list to the end where the checked item gets moved to upon completion. The current solution is way too cumbersome for such a basic task.
ty...@google.com <ty...@google.com> #31
Great, thanks for that detail in
Re
It sounds like your use-cases best match the test-case requestScrollToItem_withFirstVisibleIndex_firstVisibleItemMoved_staysScrolledAtSameIndex
I will give a code-snippet below to show the template for the solution to these use-cases. I will then provide some detail below the snippet on how this solution works.
val state = rememberLazyListState()
// The content is inside of its own fun, so it gets recomposed when [list] changes and
// thus also triggers SideEffect.
@Composable
fun Content(list: List<T>) {
LazyColumn(state = state) {
items(list, key = { ... }) { ... }
}
SideEffect {
state.requestScrollToItem(index = state.firstVisibleItemIndex)
}
}
Content(list = list)
The solution above uses SideEffect
Adding list: List<T>
as a parameter to a @Composable
fun
, will cause the fun
to be recomposed when the list
changes.
Since the recomposition will always happen after the data changes, but before the next measure pass, SideEffect
will be called after each data change, before the next measure pass. This will essentially fully opt-out of maintaining the scroll position based on key, and rather will maintain the currently scrolled index and offset.
Does that fully answer your questions/concerns?
to...@gmail.com <to...@gmail.com> #32
Some of us lives in the future and use immutablelists.
And how does this handle state restoration? Specially if there's a delay on the query and so initial redraw have no data, state is skipped but you force a scroll, then it's broken.
There's so many side effects and things to handle this manually that it's still more an hack than something stable that won't bite in the future.
ko...@gmail.com <ko...@gmail.com> #33
I did manage to solve this earlier with one of the test cases but the point is still that it is a very complex API for such basic use cases. There should be a flag that completely disables the auto-scrolling behavior (see
va...@gmail.com <va...@gmail.com> #34
Solution from #31 is not an acceptable one to me. You suggest to trigger a scroll operation on every recomposition, which in a complex screen will happen much more frequently than when just the list is mutated. This solution is subpar in terms of performance and honestly looks like a hack. Doesn't the compose official documentation discourage the usage of SideEffect function? Then why is this suggested as a default solution for 116+ people who upvoted this topic?
an...@google.com <an...@google.com> #35
This solution is subpar in terms of performance
In most cases recomposition of the composable containing LazyColumn
will anyway trigger remeasure for lazy column. Then calling requestScrollToItem
is not making it worse. Also remeasuring lazy column is not as expensive as you think. We basically do this operation on every frame when the list is scrolling and this operation is heavily optimized.
And how does this handle state restoration?
We are not aware of any issues related to that. requestScrollToItem called with the same index/offset shouldn't change the behavior here. Please file a separate bug if you think there is an issue.
We are not saying that we will never introduce additional api to completely switch to maintaining the scroll position by index. For now we introduced requestScrollToItem
api which is very flexible and keeping the same index is just one of many possible use cases for it. We are also slightly surprised it is considered to be so common to want to stay on the same index. This logic is not working great with reorderings. Every time there are new items added before the first visible one it is causing a visible to the user content jump.
To sum up, if you want to always stay on the same index, those are three options we can offer at the moment:
- You can use SideEffect and request scroll to the same position everytime list composable is recomposed:
@Composable
fun MyList(list: List<Int>) {
val state = rememberLazyListState()
LazyColumn(state) {
items(list, key = { it }) {
...
}
}
SideEffect {
state.requestScrollToItem(
index = state.firstVisibleItemIndex,
scrollOffset = state.firstVisibleItemScrollOffset
)
}
}
- If you don't use immutable lists and the list might be updated without recomposition then you can try this pattern.
Here we wrap it into withoutReadObservation because without that reading state.firstVisibleItemIndex or state.firstVisibleItemScrollOffset will subscribe us to each scroll position updates causing us to do unnecessary work.
val list by remember { mutableStateListOf<String>() }
val state = rememberLazyListState()
LazyColumn(state) {
Snapshot.withoutReadObservation {
state.requestScrollToItem(
index = state.firstVisibleItemIndex,
scrollOffset = state.firstVisibleItemScrollOffset
)
}
items(list, key = { it }) {
...
}
}
- If you fully control all the list modifications you can just call requestScrollToItem manually every time you change the list and want to stay on the same index. For example from the button click lambdas.
We understand that it might still look too complex for some of you and you would just expect to have something like rememberLazyListState(maintainScrollPositionByKey = false)
instead.
But we are not yet sure it is a scaleable enough API as there are many different context specific use cases, in some of them it is reasonable to stay on the same key, in others to stay on the same index, but in rare cases you might want to just end up on a completely different position after the data set change.
We will still monitor the feedback and are open to consider introducing more APIs to make common use cases simpler.
to...@gmail.com <to...@gmail.com> #36
For the state restoration the lazy have hacks to not restore with paging for example when there's no items to avoid loosing the state, it wait for at least one item present.
With the side effect and no data yet restored it will try to scroll to an item that is not yet there so will fail, so will corrupt the state or crash or will have unpredictable effect.
This is something that needs to be taken in account.
Then there's the other API that was refused but can't find back the previous issue, it's proper control of that state restoration delay, since if you have an header and a paging source, the data is still restore too early and we need to do
val emptyState = remember(lazyPagingItems.itemCount) {
LazyGridState(
firstVisibleItemIndex = lazyGridState.firstVisibleItemIndex,
firstVisibleItemScrollOffset = lazyGridState.firstVisibleItemScrollOffset,
)
}
LazyVerticalGrid(
state = if (lazyPagingItems.itemCount == 0) emptyState else lazyGridState,
)
And now we need to mix both of those and hope there's no other things that will bite us.
Another question, is what happens when a fling is running and the content is changed, if currently this is properly handled and the fling keeps going, now it will behave differently.
Lazy stuff is complex enough with many quirks to handle already, adding something ultra invasive as this kind of forced scroll will be problematic at some moment and will be insanely hard to debug.
an...@google.com <an...@google.com> #37
For the state restoration the lazy have hacks to not restore with paging for example when there's no items to avoid loosing the state, it wait for at least one item present. With the side effect and no data yet restored it will try to scroll to an item that is not yet there so will fail, so will corrupt the state or crash or will have unpredictable effect.
As I said, I expect the new requestScrollToItem() to not change this behavior. The scroll position will not be "corrupted" while we don't have any items, in the same way as it works right now. If it is not what you experience please file a separate bug.
al...@workjam.com <al...@workjam.com> #38
ty...@google.com <ty...@google.com> #39
You need a compose foundation version of
yb...@gmail.com <yb...@gmail.com> #40
I tried the solution in #35 but if there's a scroll in progress when list changes, scrolling abrubtly stops.
ty...@google.com <ty...@google.com> #41
Re
If you'd like, you can first check the LazyListState
for isScrollInProgress
yb...@gmail.com <yb...@gmail.com> #42
That's what I ended up doing as a workaround. But now when list changes, LazyList tries to maintain scroll position if scroll is in progress. So it ends up scrolling to an unexpected position. It's very rare that this creates a problem, but I would still prefer a proper fix.
fr...@gmail.com <fr...@gmail.com> #43
I've a LazyColumn with bidirectional pagination. The data is loading completely asynchronously and I don't know how many items I'll get with after a successful request.
I'm adding a ProgressIndicator in both directions while I've not reached the end (in any directions).
As I'm adding items forward the list will always auto-scroll to show the ProgressIndicator, as it has a unique key and is always the first item.
I've tried playing with requestScrollToItem() but I can't make it works properly, when inserting the data at index 0 (reverse layout) the lazyListState.firstVisibleItemIndex is always 0.
Could we have a simple api to Opt-out? even if it's not flexible, it'd help a lot...
Or if you have any idea how to manage this ProgressIndicator without messing the scrolling.
I had the same code with a RecyclerView and it was working like a charm.
Thanks.
ga...@gmail.com <ga...@gmail.com> #44
Are there any examples that incorporate Paging3?
Description
Description:
When using a LazyList with keyed items the scroll position is maintained based on the key. It would be great if there would be a way to opt out from this behavior when using keyed items.
Use Case:
I want to be able to switch the first visible item without changing the scroll position.