cmp*_*rog 15 android android-jetpack dagger-hilt
BroadcastReceiver使用 Hilt内部的依赖注入不起作用。我尝试BroadcastReceiver使用警报调用 aMainActivity并且我得到UninitializedPropertyAccessException. 根据文档,它应该像向@AndroidEntryPoint接收器添加注释一样简单,但不是。
示例代码:
应用程序.kt:
@HiltAndroidApp
class App: Application() {
override fun onCreate() {
super.onCreate()
Log.d(App::class.simpleName, "onCreate: Application")
}
}
Run Code Online (Sandbox Code Playgroud)
TestHiltInjection.kt:
class TestHiltInjection @Inject constructor() {
operator fun invoke() {
Log.d(TestHiltInjection::class.java.simpleName, "invoke called.")
}
}
Run Code Online (Sandbox Code Playgroud)
HiltBroadcastReceiver.kt:
@AndroidEntryPoint
class HiltBroadcastReceiver : BroadcastReceiver() {
@Inject lateinit var testHiltInjection: TestHiltInjection
override fun onReceive(context: Context?, intent: Intent?) {
testHiltInjection()
}
}
Run Code Online (Sandbox Code Playgroud)
主活动.kt:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val manager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pending = PendingIntent
.getBroadcast(this, 0, Intent(this, HiltBroadcastReceiver::class.java), 0)
manager.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
15000, 15000,
pending
)
}
}
Run Code Online (Sandbox Code Playgroud)
输出日志:
kotlin.UninitializedPropertyAccessException: lateinit property testHiltInjection has not been initialized
Run Code Online (Sandbox Code Playgroud)
更新
问题已经在 2.29.1 版本解决,直接使用 @AndroidEntryPoint
Val*_*kov 28
更新:根据问题,问题应该在Dagger Hilt 2.29.1版本中修复。因此,只需使用 version2.29.1-alpha或更高版本。不要忘了更新hilt-android-gradle-plugin版本,以及。
原始答案:存在 GitHub问题和解决方法。似乎注入不起作用,因为它实际上发生在onReceive()生成的父类的方法内部。问题是你不能调用 super 方法,因为它是抽象的。但是你可以创建一个简单的包装类来解决这个问题:
abstract class HiltBroadcastReceiver : BroadcastReceiver() {
@CallSuper
override fun onReceive(context: Context, intent: Intent) {}
}
@AndroidEntryPoint
class MyBroadcastReceiver : HiltBroadcastReceiver() {
@Inject lateinit var testHiltInjection: TestHiltInjection
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent) // <-- it's the trick
...
}
}
Run Code Online (Sandbox Code Playgroud)
使用 Hilt 的稳定版本。你可以轻松地注入任何这样的变量
@AndroidEntryPoint
public class SMSReceiver extends BroadcastReceiver {
@Inject
public DataManager dataManager;
@Override
public void onReceive(final Context context, Intent intent) {
}
}
Run Code Online (Sandbox Code Playgroud)
我认为 hilt 目前不支持 BroadcastReceiver。在https://dagger.dev/hilt/android-entry-point 中说
注意:Hilt 目前仅支持扩展 ComponentActivity 的 Activity 和扩展 androidx 库 Fragment 的 Fragment,不支持 Android 平台中的(现已弃用)Fragment。
内部工作原理:Hilt 为带@AndroidEntryPoint注释的组件(Activity、Fragment、BroadcastReceiver 等)创建抽象类,并且您的 BroadcastReceiver 将生成的类扩展为字节码转换中的基类。在基类onReceive方法中注入对象。但是在生成的字节码类onReceive中没有调用超类方法。这就是为什么你的对象没有被注入。testHiltInjection()在HiltBroadcastReceiver课堂之前测试添加以下代码。顺便说一下,它仍然处于Alpha模式。
((HiltBroadcastReceiver_GeneratedInjector) BroadcastReceiverComponentManager.generatedComponent(context)).injectHiltBroadcastReceiver(UnsafeCasts.<HiltBroadcastReceiver>unsafeCast(this));
Run Code Online (Sandbox Code Playgroud)
更新:现在问题已在版本中修复2.29.1-alpha。也不要忘记将hilt-android-gradle-plugin版本升级到2.29.1-alpha或最新。有关版本的更多信息。
修复 #1918:通过 @AndroidEntryPoint 转换支持 BroadcastReceiver。(ede018b)
| 归档时间: |
|
| 查看次数: |
5166 次 |
| 最近记录: |