Status Update
Comments
il...@google.com <il...@google.com> #2
uc...@google.com <uc...@google.com>
ze...@google.com <ze...@google.com>
st...@gmail.com <st...@gmail.com> #3
gr...@ynab.com <gr...@ynab.com> #4
private void refreshAllLiveData() {
AppDataBase YOUR_DATABASE_WHICH_YOU_BUILD = .....
SupportSQLiteDatabase writableDatabase = YOUR_DATABASE_WHICH_YOU_BUILD.getOpenHelper().getWritableDatabase();
//get the database count;
Cursor cursor = writableDatabase.query("SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name != 'android_metadata' AND name != 'room_master_table';");
int tableCount = 0;
while(cursor.moveToNext()) {
tableCount = cursor.getInt(0);
}
for (int i = 0; i < tableCount; i++) {
//update version table with the incremented count because room modification log stores tables with ids instead of names
writableDatabase.execSQL("INSERT OR REPLACE INTO room_table_modification_log VALUES(null, "+(i)+")");
}
YOUR_DATABASE_WHICH_YOU_BUILD.getInvalidationTracker().refreshVersionsAsync();
}
-----
This is a workaroud for refreshing all live datas, I still prefer to use a proper API you implemented.
Thanx
re...@gmail.com <re...@gmail.com> #5
cl...@google.com <cl...@google.com> #6
As a work-around, you can temporarily wrap the desugared library types.
class LocalDateWrapper {
public LocalDate localDate;
}
The wrapper can be passed around without any issues.
We are investigating if better solutions are possible.
sa...@gmail.com <sa...@gmail.com> #7
da...@khol.me <da...@khol.me> #8
Sadly, in my humble opinion, the best option is to keep using 310 ABP.
We used to have a wrapper class as well, but developers occasionally forgot about this edge case and used the raw java.time
object.
Once we discovered it in code review but once it slipped into production.
I can live with a 100KB bigger APK but don't want to be dealing with crashing prod again.
mk...@gmail.com <mk...@gmail.com> #9
pr...@culqi.com <pr...@culqi.com> #10
cl...@google.com <cl...@google.com> #11
Here androidx uses reflection on a String to get the class. We can rewrite code with desugared library, but hardly strings. This means we end up in a situation where Class.forName("java.time.LocalDate")
is called instead of Class.forName("j$.time.LocalDate")
because the java in the string is not rewritten. In addition, the input strings are constructed from string concatenation so simple pattern matching would hardly apply correctly. I don't see a sound way around that.
It's a static method so R8 could retarget the call, it's not pretty but it could do the job... Something along the lines of (I would need to test it):
public static class NavTypeHandler {
public static NavType<?> fromArgType(String type, String packageName) {
try {
return NavType.fromArgType(type, packageName);
} catch (ClassNotFoundException e) {
if (packageName.startsWith("java")) {
return NavType.fromArgType(type, "j$" + packageName.substring(4, packageName.length()));
} else {
throw e;
}
}
}
}
The potential errors from this would be limited since normally people cannot use j$ as a prefix outside of desugared library. It's a fix for a specific library though, which is what we are trying to avoid, but I'm not sure we want to do this on all Class#forName.
Let's talk about this.
cl...@google.com <cl...@google.com> #12
Ok so I think this can work. One issue is that if the class java.time.LocaleDate becomes unused with shrinking and is used only through reflection, then the ClassNotFoundException will be there anyway. So you might have to add a field of the time used in Nav and keep it to make sure the type is used and present. It all practical cases it may work. I will try to make a fix and add it to desugared library 2.0.
ap...@google.com <ap...@google.com> #13
Branch: main
commit d5abe49929da9b1312ed3b0e095a881572451967
Author: Clément Béra <clementbera@google.com>
Date: Tue Aug 01 12:57:24 2023
Retarget NavType#fromArgType
Bug:
Change-Id: I9a2b114a00834df67ebe314d9e0e25f79d1fc5d9
M src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
M src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
A src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibRewriterEventConsumer.java
A src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryCfMethods.java
A src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryLibRewriter.java
M src/main/java/com/android/tools/r8/profile/rewriting/ProfileRewritingCfInstructionDesugaringEventConsumer.java
M src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
A src/test/java/com/android/tools/r8/cfmethodgeneration/InstructionTypeMapper.java
A src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryNavTypeTest.java
A src/test/java/com/android/tools/r8/desugar/desugaredlibrary/generation/DesugaredLibraryBridge.java
A src/test/java/com/android/tools/r8/desugar/desugaredlibrary/generation/GenerateDesugaredLibraryBridge.java
M src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
cl...@google.com <cl...@google.com> #14
This is going to be fixed in R8/AGP 8.2 (no backport)
cl...@google.com <cl...@google.com>
ch...@google.com <ch...@google.com> #15
I learned that D8 and R8 will rewrite calls to NavType#fromArgType
when core library desugaring is enabled, so that "desugared library j$
types take precedence over java
types". The code for doing this is in
I wonder if we should instead consider updating NavType#fromArgType
Aurimas, what are your thoughts on this, and do you know who would be the right owners for this?
Description
Navigation
Version used:
2.3.0
Desugaring library:
com.android.tools:desugar_jdk_libs:1.0.9
Devices/Android versions reproduced on:
Nexus_4_API_22 (emulator)
Nexus_6_API_25 (emulator)
emulator version 30.0.12
After upgrade to Gradle version 4.0.0 we've decided to use java.time package to handle work with dates in our project. With the help of desugaring library everything works well. But the corner case was found.
When java.date.LocalDate type is being defined as destination argument type application crashes on launch on devices with API < 26.
On devices with higher API version everything works smoothly. If argument type is defined as org.threeten.bp.LocalDate (backport library for java.time) no crash happened too.
Stacktrace:
2020-07-01 14:34:37.802 2869-2869/com.example.navargsdate E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.navargsdate, PID: 2869
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.navargsdate/com.example.navargsdate.MainActivity}: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class fragment
Caused by: java.lang.RuntimeException: Exception inflating com.example.navargsdate:navigation/nav_graph line 24
at androidx.navigation.NavInflater.inflate(NavInflater.java:97)
at androidx.navigation.NavController.setGraph(NavController.java:551)
at androidx.navigation.NavController.setGraph(NavController.java:533)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:238)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2684)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:280)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1175)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:109)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:335)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:777)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)
at com.example.navargsdate.MainActivity.onCreate(MainActivity.kt:16)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: java.time.LocalDate
at androidx.navigation.NavType.fromArgType(NavType.java:181)
2020-07-01 14:34:37.802 2869-2869/com.example.navargsdate E/AndroidRuntime: at androidx.navigation.NavInflater.inflateArgument(NavInflater.java:191)
at androidx.navigation.NavInflater.inflateArgumentForDestination(NavInflater.java:155)
at androidx.navigation.NavInflater.inflate(NavInflater.java:128)
at androidx.navigation.NavInflater.inflate(NavInflater.java:141)
at androidx.navigation.NavInflater.inflate(NavInflater.java:88)
... 33 more
Caused by: java.lang.ClassNotFoundException: java.time.LocalDate
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:400)
at java.lang.Class.forName(Class.java:326)
at androidx.navigation.NavType.fromArgType(NavType.java:169)
... 38 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDate" on path: DexPathList[[zip file "/data/app/com.example.navargsdate-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.navargsdate-1/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 42 more