'Android Hilt throw IllegalStateException even stated Custom Application in Manifest.xml
I have a few real devices and also tested with Android studio's emulator and did not find any similar crash.
My problem is that I published the app and received crash reports from real users.
Google Play Console Crash Report
Type java.lang.RuntimeException
...
Caused by: java.lang.IllegalStateException:
at dagger.hilt.android.internal.managers.ActivityComponentManager.createComponent (ActivityComponentManager.java:76)
at dagger.hilt.android.internal.managers.ActivityComponentManager.generatedComponent (ActivityComponentManager.java:66)
at MyApp.Hilt_FirstEntryPage.generatedComponent (Hilt_FirstEntryPage.java:45)
at MyApp.Hilt_FirstEntryPage.inject (Hilt_FirstEntryPage.java:67)
at MyApp.Hilt_FirstEntryPage$1.onContextAvailable (Hilt_FirstEntryPage.java:38)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable (ContextAwareHelper.java:99)
at androidx.activity.ComponentActivity.onCreate (ComponentActivity.java:322)
at androidx.fragment.app.FragmentActivity.onCreate (FragmentActivity.java:249)
at MyApp.FirstEntryPage.onCreate (FirstPage.java:68)
at android.app.Activity.performCreate (Activity.java:8207)
...
ActivityComponentManager.java:76
Hilt Activity must be attached to an @HiltAndroidApp Application. Did you forget to specify your Application's class name in your
manifest's <application />'s android:name attribute?
I did check other stack overflow questions, I already did add my custom application into Manifest and run successfully in my testing devices.
My app has only one module and only one application, and also some several ContentProvider, BroadcastReceiver, AppWidgetProvider, WorkManager, JobIntentService, not sure they could affect the normal initialization of application to lead the crash.
For the FirstEntryPage activity, I did not inject any things. It is very simple activity page just like Hello World example. Therefore there could not be any component conflict. In addition, FirstEntryPage activity can be opened by PendingIntent from BroadcastReceiver and also notification.
The previous version did not apply hilt, and this version is the first time to bring hilt to real users.
AndroidManifest.xml
<application
android:name=".MyApplication"
MyApplication.java
@HiltAndroidApp
public final class MyApplication extends MultiDexApplication implements Configuration.Provider
FirstEntryPage.java
@AndroidEntryPoint
public final class FirstEntryPage extends FragmentActivity implements OnClickListener, DialogInterface.OnClickListener
build.gradle
dependencies {
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.40.1'
}
apply plugin: 'dagger.hilt.android.plugin'
dependencies {
implementation 'androidx.hilt:hilt-work:1.0.0'
implementation 'com.google.dagger:hilt-android:2.38.1'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
kapt 'com.google.dagger:hilt-compiler:2.38.1'
}
Solution 1:[1]
You also need to declare @AndroidEntryPoint
in your parent activity of your FirstEntryPage
Fragment Activity.
Solution 2:[2]
After searching answer in the Internet, I found the answer in the dagger Github https://github.com/google/dagger/issues/2798. I also tested by myself and there is no more such crash report in my Google Play Console after related code changes.
Here is the short answer:
When using hilt, you cannot use Android Auto Backup (android:allowBackup="true"
without android:backupAgent
), otherwise your app will crash.
If your app needs backup, with hilt, you must use Key/Value Backup (Android Backup Service) instead of Android Auto Backup.
That is, add these (and with your implementation of MyBackupAgent) in your AndroidManifest.xml
android:allowBackup="true"
android:backupAgent="MyBackupAgent"
android:fullBackupOnly="false"
If you app does not need backup, with hilt, just set android:allowBackup="false"
in your AndroidManifest.xml
Solution 3:[3]
The cases are all notionally the same if you rank "has a status" as eg 1 and "doesn't have a status" as 2 and then order by this preferentially over the date
As such it seems we could have:
items.GroupBy(
i => (i.Id, i.Version),
(k, g) => g.OrderBy(i => i.Status.HasValue ? 1 : 2).ThenByDescending(i => i.DateModified).First()
);
This groups items on a tuple of id and version, then uses the overload of group by that processes it's own groupings after it's made them. The items in the group are sorted first by whether status has a value (and any status of any value takes priority over any non status item) then the modified date is used to split any ties
This form of GroupBy is essentially
items.GroupBy(i => (i.Id, i.Version))
.Select(g =>
g.OrderBy(i => i.Status.HasValue ? 1 : 2)
.ThenByDescending(i => i.DateModified)
.First()
);
which you may prefer
Solution 4:[4]
You can use Linq
statements. Use Min
if you want the earliest date. I didn't know what you mean by the status is "Empty" so the code below is assuming that status is a string
and "Empty" in this case means that the string
IsNullOrWhiteSpace
.
var itemsWithStatus = items.Where(item => string.IsNullOrWhiteSpace(item.Status));
if (itemsWithStatus.Any())
{
return itemsWithStatus.Max(item => item.Date);
}
return items.Max(item => item.Date);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Kishan Mevada |
Solution 2 | meor9zcu12 |
Solution 3 | |
Solution 4 |