Fixed
Status Update
Comments
ku...@google.com <ku...@google.com>
ku...@google.com <ku...@google.com> #2
[Comment deleted]
ms...@gmail.com <ms...@gmail.com> #3
[Comment deleted]
to...@gmail.com <to...@gmail.com> #4
Also of note is the adb error when trying to install bad APK: INSTALL_FAILED_DEXOPT
ms...@gmail.com <ms...@gmail.com> #5
load dex files over 5Gb. -> load dex files over 5Mb.
to...@gmail.com <to...@gmail.com> #6
Same here! Looking forward to a solution :)
Android Studio version: 0.8.12
buildToolsVersion 21.0.1
Gradle 1.11
Android Studio version: 0.8.12
buildToolsVersion 21.0.1
Gradle 1.11
ms...@gmail.com <ms...@gmail.com> #7
There is already an option in dx allowing to force generation of smaller dex files:
--set-max-idx-number=<value>
Unfortunately changing the default is not a solution since the linearAlloc limit can be reached at very different levels depending on the classes hierarchy and other criteria.
In addition for most applications, moving to multidex will only help to workaround the linearalloc limit for the installation. But the application will still crash against the same limit at execution. The only working use case where I know multidex can help with linearalloc is when the apk does not contains one application but distinct pieces running in separate process.
--set-max-idx-number=<value>
Unfortunately changing the default is not a solution since the linearAlloc limit can be reached at very different levels depending on the classes hierarchy and other criteria.
In addition for most applications, moving to multidex will only help to workaround the linearalloc limit for the installation. But the application will still crash against the same limit at execution. The only working use case where I know multidex can help with linearalloc is when the apk does not contains one application but distinct pieces running in separate process.
ms...@gmail.com <ms...@gmail.com> #8
Thanks for your quick response.
It's nice to know about that command line option. I do not see it in the output of 'dx --help', might be good to add that.
I'm not very familiar with the 'linearAlloc limit' issue outside of the context of the dexopt step. My sample app is able to run once the lower idx value is set, although I do not actually call into any of the library code that is bundled with the app. I assume it's undefined when/if the 'linearAlloc limit' will be hit in a large application on gb.
I'm a bit confused as to the platform compatibility of multidex given the 'linearAlloc limit' bug. What specific versions of Android are supported? The multidex code implies back to v4 (https://android.googlesource.com/platform/frameworks/multidex/+/master/library/src/android/support/multidex/MultiDex.java ) but it would seem that ICS is the earliest supported platform. Is this correct?
It's nice to know about that command line option. I do not see it in the output of 'dx --help', might be good to add that.
I'm not very familiar with the 'linearAlloc limit' issue outside of the context of the dexopt step. My sample app is able to run once the lower idx value is set, although I do not actually call into any of the library code that is bundled with the app. I assume it's undefined when/if the 'linearAlloc limit' will be hit in a large application on gb.
I'm a bit confused as to the platform compatibility of multidex given the 'linearAlloc limit' bug. What specific versions of Android are supported? The multidex code implies back to v4 (
to...@gmail.com <to...@gmail.com> #9
The option is not documented in --help because it was designed for testing and we're not capable of documenting a reliable way to use it as a workaround of the linearalloc limit.
The linearalloc limit is reached when loading classes. At install time dexopt is loading all classes contained in the dex so it's facing the limit immediately. At execution the limit may be reached after some delay dependending of the usage you have of the packaged classes. If you face it at install time but not at execution, this means you never trigger the loading of some classes. In a real application those never loaded classes should have been shrinked away manually or by Proguard. The exception is when there are different groups of classes in the dex files used in separate process.
About multidex library supported versions I've merged recently a change to try to be clearerhttps://android-review.googlesource.com/#/c/108023/
The summary is that the library should work down to API 4 (Donut), but below ICS applications will probably be hit by the linearalloc limit
The linearalloc limit is reached when loading classes. At install time dexopt is loading all classes contained in the dex so it's facing the limit immediately. At execution the limit may be reached after some delay dependending of the usage you have of the packaged classes. If you face it at install time but not at execution, this means you never trigger the loading of some classes. In a real application those never loaded classes should have been shrinked away manually or by Proguard. The exception is when there are different groups of classes in the dex files used in separate process.
About multidex library supported versions I've merged recently a change to try to be clearer
The summary is that the library should work down to API 4 (Donut), but below ICS applications will probably be hit by the linearalloc limit
il...@google.com <il...@google.com> #10
for Android studio use:
dexOptions {
additionalParameters = ['--multi-dex', '--set-max-idx-number=40000']
}
dexOptions {
additionalParameters = ['--multi-dex', '--set-max-idx-number=40000']
}
to...@gmail.com <to...@gmail.com> #11
I still have this issue and it's driving me nuts
to...@gmail.com <to...@gmail.com> #14
Well you missunderstood it's about the current functionality that will be lost.
Currently active fragment will load, then finish it's load then other offscreen fragments will start their loading. This is not related to threads limits or anything, this is being sure active fragment have more ressources and load before the unseen ones.
If you remove #1 then all fragments will start at the same time, meaning all loaders too, without any guaranteed order. Imagine a 1 core device (or multiple cores but multiple loaders per fragment) then without luck the offscreen fragments will load before the main that will be delayed until a thread is free.
Providing an API to allow users to keep that way of acting for low end devices or heavy / long loaders should be thought before removing #1. I was just proposing a more global approach as alternative, but at least there's need to have something that ensure active fragments loaders start first to avoid problems.
Currently active fragment will load, then finish it's load then other offscreen fragments will start their loading. This is not related to threads limits or anything, this is being sure active fragment have more ressources and load before the unseen ones.
If you remove #1 then all fragments will start at the same time, meaning all loaders too, without any guaranteed order. Imagine a 1 core device (or multiple cores but multiple loaders per fragment) then without luck the offscreen fragments will load before the main that will be delayed until a thread is free.
Providing an API to allow users to keep that way of acting for low end devices or heavy / long loaders should be thought before removing #1. I was just proposing a more global approach as alternative, but at least there's need to have something that ensure active fragments loaders start first to avoid problems.
to...@gmail.com <to...@gmail.com> #15
About your side note: Calling restart on return from a child fragment that can have modified any number of data if often wanted and normal.
Specially when we are dealing with those viewpager and child fragments.
ViewPager backed by cursor, click open detail views that you can swipe to see any number of details, in each details view you can change things -> on reenter to viewpager fragment you restart the loader to have the uptodate data, even if the query have not changed.
Specially when we are dealing with those viewpager and child fragments.
ViewPager backed by cursor, click open detail views that you can swipe to see any number of details, in each details view you can change things -> on reenter to viewpager fragment you restart the loader to have the uptodate data, even if the query have not changed.
il...@google.com <il...@google.com> #16
Fragments with setUserVisibleHint=true will still start before those with it set to false (it is a two step process). While the Loader specific delay between the two steps is being removed, the ordering of creation/starting is not.
to...@gmail.com <to...@gmail.com> #17
Can't edit but viewpager = recyclerview :)
to...@gmail.com <to...@gmail.com> #18
Ok thanks for the detail.
Will this be released as a fast .X release or in the next normal scheduled cycle? (Just to have an idea if I should already start again using it to find other issues or have time for that).
Will this be released as a fast .X release or in the next normal scheduled cycle? (Just to have an idea if I should already start again using it to find other issues or have time for that).
il...@google.com <il...@google.com> #19
This has been fixed for the next release, almost certainly as part of a fast .X release
to...@gmail.com <to...@gmail.com> #20
So doing some more tests I see other differences in loaders behavior from before :(
Like onLoadFinished is being called when returning to fragment when it was not the case before (before any call to reload or init made)
And much more important a change in how onLoaderReset is now called.
The documentation of restartLoader Says: "If a loader with the same id has previously been started it will automatically be destroyed when the new loader completes its work. The callback will be delivered before the old loader is destroyed."
But new implementation does not that at all. It calls onLoaderReset then onCreateLoader then onLoadFinished. (Previous implementation was sometimes broken and never called onLoaderReset but at least there was no long duration where we have no data to display).
This is a major change because this means you can't keep the previous data during the load as it's invalidated but you have nothing to display since the new loader is not finished. Meaning empty screen on reload = quite bad UX.
Like onLoadFinished is being called when returning to fragment when it was not the case before (before any call to reload or init made)
And much more important a change in how onLoaderReset is now called.
The documentation of restartLoader Says: "If a loader with the same id has previously been started it will automatically be destroyed when the new loader completes its work. The callback will be delivered before the old loader is destroyed."
But new implementation does not that at all. It calls onLoaderReset then onCreateLoader then onLoadFinished. (Previous implementation was sometimes broken and never called onLoaderReset but at least there was no long duration where we have no data to display).
This is a major change because this means you can't keep the previous data during the load as it's invalidated but you have nothing to display since the new loader is not finished. Meaning empty screen on reload = quite bad UX.
ta...@gmail.com <ta...@gmail.com> #21
The onLoaderReset problem described in #20 makes working with CursorLoader and CursorAdapter suddenly very cumbersome in 27.1.0.
In order to avoid the "empty data" period of time after onLoaderReset, my extremely hacky workaround is to create a second identical loader, with a separate Loader ID, and flip between the two Loaders with each call to restartLoader, so that the previous Cursor remains alive until the next onLoadFinished callback.
In order to avoid the "empty data" period of time after onLoaderReset, my extremely hacky workaround is to create a second identical loader, with a separate Loader ID, and flip between the two Loaders with each call to restartLoader, so that the previous Cursor remains alive until the next onLoadFinished callback.
to...@gmail.com <to...@gmail.com> #22
ja...@gmail.com <ja...@gmail.com> #23
Before 27.1.0, loaders initialized with getSupportLoaderManager() used to receive a call to onStartLoading() while the activity was executing super.onStart(). This allowed synchronous loaders to initialize resources before the remaining body of onStart() executed. In 27.1.0, loaders no longer start loading until some time after onStart(). This change caused a few NPEs in our onStart() methods. Is this 27.1.0 behavior a violation of the "between onStart/onStop" contract?
I thinkhttps://issuetracker.google.com/issues/73976255#comment13 is referencing this same guarantee which appears to be broken.
I think
ja...@gmail.com <ja...@gmail.com> #24
With a bit more digging I found https://issuetracker.google.com/issues/74225064 which appears to reference and fix the exact issue that I mentioned in #23. Sorry for the noise.
sa...@gmail.com <sa...@gmail.com> #25
please update your support libraries with 27.1.1
kk...@google.com <kk...@google.com> #26
This bug has been fixed in Support Library 27.1.1.
sa...@gmail.com <sa...@gmail.com> #27
(Program type already present: android.arch.lifecycle.LiveData$LifecycleBoundObserver Message{kind=ERROR, text=Program type already present: android.arch.lifecycle.LiveData$LifecycleBoundObserver, sources=[Unknown source file], tool name=Optional.of(D8)})
solv this problam
solv this problam
Description
Since support library 27.1.0 when using a FragmentStatePagerAdapter in a viewPager the offscreen fragment lifecycle have changed.
Before onStart / onResume where called on those fragment and it's no more the case. The offscreen fragments have the lifecycle stopping at onActivityCreated.
After a screen rotation those lifecycle are called correctly. So it's more a bug on first creation of the fragments than a wanted API change it seems.
If it's a normal wanted API change please confirm.