Open ksc91u opened 4 years ago
Yeah that's not going to work as the regular threetenbp jar will initialize itself with the embedded tzdb and then the application will try to initialize it with the asset version. threetenabp is not a dependency of threetenbp (it's the other way around) so your exclude isn't actually doing anything. There's really not a good way to set this up, I don't think.
I do not understand why adding threetenbp to unit test would effect my app on only some devices.
now my configuration is
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
try {
AndroidThreeTen.init(this)
} catch (e: Exception) {
Timber.e(e)
}
I removed that testImplementation but ZoneRulesException: No time-zone data files registered
still happen on some devices.
It should have no effect on the app. It will cause tests to always fail though.
Thank you, I will just try D8 java time then.
I got this too with 1.2.2
Caused by java.lang.IllegalStateException: Already initialized
at org.threeten.bp.zone.ZoneRulesInitializer.setInitializer(ZoneRulesInitializer.java:74)
at com.jakewharton.threetenabp.AndroidThreeTen.init(AndroidThreeTen.java:22)
at com.jakewharton.threetenabp.AndroidThreeTen.init(AndroidThreeTen.java:17)
at com.app.app.MainActivity.onCreate(MainActivity.java:161)
I have the following for release:
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
On the emulator it worked, the crash happened only for the first time I opened my app (after adding this lib). After that it seems to work. This is with my device, still waiting to see if it happens on more devices (a new release).
Did I do something wrong?
And it just happened again, any idea? Thanks
Initialize in application, not activity.
Silly me :)
Same error.
Library versions:
"com.jakewharton.threetenabp:threetenabp:1.2.1"
"org.threeten:threetenbp:1.4.0"
Usage:
class App : Application() {
override fun onCreate() {
super.onCreate()
if (LeakCanary.isInAnalyzerProcess(this)) {
return
}
if (ProcessPhoenix.isPhoenixProcess(this)) {
return
}
Fabric.with(this, crashlyticsKit)
AndroidThreeTen.init(this)
}
}
Error:
org.threeten.bp.zone.ZoneRulesInitializer.setInitializer (ZoneRulesInitializer.java:74)
com.jakewharton.threetenabp.AndroidThreeTen.init (AndroidThreeTen.java:22)
com.jakewharton.threetenabp.AndroidThreeTen.init (AndroidThreeTen.java:17)
com.jakewharton.threetenabp.AndroidThreeTen.init (AndroidThreeTen.java:13)
\\ Error like: App.onCreate (App.java:109)
This error does not always occur. We can not reproduce when testing the application. Errors are logged in Crashlytics. Versions of Android 7, 8, 9, 10. Various device manufacturers Samsung, Xiaomi, HUAWEI and others.
Error investigation
It looks like the ZoneRulesProvider
class is loading before calling the ZoneRulesInitializer.setInitializer()
method.
Documentation for method setInitializer()
:
This can only be invoked before the {@link ZoneRulesProvider} class is loaded.
Class ZoneRulesProvider
has a static initializer:
public abstract class ZoneRulesProvider {
static {
ZoneRulesInitializer.initialize();
}
}
I also got that issue on abp 1.2.3, are there any known workarounds? 1.2.4 seems to only add a Japanese time zone.
The crash happens rather randomly when the app is in background for a long time. There is only an abp dependency in my gradle, no org.threeten:threetenbp. Is that mandatory?
Logcat:
05-09 00:45:48.285 10475 10475 E AndroidRuntime: Caused by: java.lang.IllegalStateException: Already initialized
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at org.threeten.bp.zone.ZoneRulesInitializer.setInitializer(ZoneRulesInitializer.java:74)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at com.jakewharton.threetenabp.AndroidThreeTen.init(AndroidThreeTen.java:22)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at com.jakewharton.threetenabp.AndroidThreeTen.init(AndroidThreeTen.java:17)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at com.example.erik.myroom.Frontend.Activity_Main.onCreate(Activity_Main.java:49)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6684)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
05-09 00:45:48.285 10475 10475 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637)
Code:
Public class Activity_Main extends AppCompatActivity
implements
Fragment_Main.OnCatButtonListener,
Fragment_Main.OnGlobalLIstButtonListener,
Fragment_Main.OnStatisticButtonListener,
Fragment_Main.OnJobListButtonListener,
OnBackToMainListener {
private ActivityMainBinding oBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
//inflates Iconics
LayoutInflaterCompat.setFactory2(getLayoutInflater(), new IconicsLayoutInflater2(getDelegate()));
super.onCreate(savedInstanceState);
//Init Date Framework
AndroidThreeTen.init(this);
//init job
androidx.work.PeriodicWorkRequest periodicWorkRequest = new androidx.work.PeriodicWorkRequest.Builder(
MonthlyWorker.class,
MIN_PERIODIC_INTERVAL_MILLIS, TimeUnit.MILLISECONDS,
MIN_PERIODIC_FLEX_MILLIS, TimeUnit.MILLISECONDS)
.addTag(TAG)
.build();
WorkManager.getInstance(getApplicationContext()).enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
//init Databinding
oBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
setSupportActionBar(oBinding.toolbar);
if(oBinding.mainContainer != null){
//are we restoring the instance state?
if(savedInstanceState != null){
return; //yes - do nothing
}
this.CreateNewFragment(new Fragment_Main());
}
}
We had this crash too. We use Dagger.Hilt and it injects Application
dependencies during super.onCreate()
. We call AndroidThreeTen.init
after super.onCreate()
. However, recently we used OffsetDateTime
in constructor of one of Application
dependencies. Turns out that doing that triggers AndroidThreeTen
initialization internally since we didn't call AndroidThreeTen.init
yet. And after super.onCreate()
we call AndroidThreeTen.init
and get this crash.
@JakeWharton Here AndroidThreeTen.init
is called after super.onCreate()
. Is it ok to call it before super.onCreate()
? If not then we should either stop injecting dependencies into Application
or we should rigorously check constructors of all our dependencies for not using org.threeten.abp
classes. Or maybe there is another way?
This is less error-prone with plain Dagger since you can't inject Application
dependencies in super.onCreate()
. So previously we called super.onCreate()
then AndroidThreeTen.init
and then injected our Application
.
Should be fine
On Wed, Aug 26, 2020, at 3:53 AM, Vladyslav Kasprov wrote:
We had this crash too. We use Dagger.Hilt and it injects
Application
dependencies duringsuper.onCreate()
. We callAndroidThreeTen.init
aftersuper.onCreate()
. But we useOffsetDateTime
in constructor of one ofApplication
dependencies. Turns out that it triggers initialization internally since we didn't callAndroidThreeTen.init
yet. And aftersuper.onCreate()
we callAndroidThreeTen.init
and get this crash.@JakeWharton https://github.com/JakeWharton Is it ok to call
AndroidThreeTen.init
before callingsuper.onCreate()
in Application? Here https://github.com/JakeWharton/ThreeTenABP#usage it is called aftersuper.onCreate()
.If not then we should either stop injecting dependencies into
Application
or we should rigorously check our dependency graph constructors for using org.threeten.abp classes.— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/ThreeTenABP/issues/119#issuecomment-680721122, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQIELGTED5AJVF4YJXVC3SCS5QJANCNFSM4KFDNVLA.
@JakeWharton wdyt about adding fallback with force setting initializer to make sure, that we are not crashing?
try {
AndroidThreeTen.init(application)
} catch (e: Exception) {
forceSetInitializer(application)
}
/**
* Copied logic from [com.jakewharton.threetenabp.AssetsZoneRulesInitializer]
*/
private fun forceSetInitializer(context: Context) {
val assetPath = "org/threeten/bp/TZDB.dat"
val provider: TzdbZoneRulesProvider
var inputStream: InputStream? = null
try {
inputStream = context.assets.open(assetPath)
provider = TzdbZoneRulesProvider(inputStream)
} catch (e: IOException) {
throw IllegalStateException("$assetPath missing from assets", e)
} finally {
if (inputStream != null) {
try {
inputStream.close()
} catch (ignored: IOException) {
}
}
}
try {
ZoneRulesProvider.registerProvider(provider)
} catch (ignored : ZoneRulesException){
// if this exception is thrown - means it is already initialized and we are good
}
}
hi @JakeWharton, just checking if there still isn't a solution for this yet?
We have seen this exception on some devices since last release.
We have tried remove that testImplementation duplicate entry, try/catch that exception and continue. But new exception occurred.
I have seen two library entry in Android Studio,
But only 1.4.0@jar version when run
./gradlew app::dependencies 2>&1 1> log2
I have also clear AndroidStudio & gradle caches. Do you know what might cause this issue? Thank you.