amr*_*mrz 1 android dependency-injection android-fragments android-jetpack dagger-hilt
我正在尝试创建一个简单的新闻应用程序,但是当我@Inject constructor在片段中使用 of 时,导航组件不起作用并显示以下错误...而在使用注入之前,它的工作没有任何问题
我要做什么来修复这个错误?非常感谢你的帮助
新闻活动:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import com.example.simplenewsapp.R
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.android.synthetic.main.activity_news.*
@AndroidEntryPoint
class NewsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news)
bottomNavigationView.setupWithNavController(newsNavHostFragment.findNavController())
}
}
Run Code Online (Sandbox Code Playgroud)
突发新闻片段:
class BreakingNewsFragment @Inject constructor(
val newsItemAdapter: NewsAdapter,
var viewModel: MainViewModel? = null
) : Fragment(R.layout.fragment_breaking_news) {
...
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.simplenewsapp, PID: 8558
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.simplenewsapp/com.example.simplenewsapp.ui.NewsActivity}: android.view.InflateException: Binary XML file line #17: Binary XML file line #17: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.view.InflateException: Binary XML file line #17: Binary XML file line #17: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #17: Error inflating class fragment
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.simplenewsapp.ui.fragments.BreakingNewsFragment: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:625)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:71)
at androidx.navigation.NavGraphNavigator.navigate(NavGraphNavigator.java:28)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.onGraphCreated(NavController.java:639)
at androidx.navigation.NavController.setGraph(NavController.java:592)
at androidx.navigation.NavController.setGraph(NavController.java:557)
at androidx.navigation.NavController.setGraph(NavController.java:539)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:248)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2936)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:472)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:141)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:313)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:292)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:780)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:866)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at android.view.LayoutInflater.inflate(LayoutInflater.java:374) E/AndroidRuntime: at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.example.simplenewsapp.ui.NewsActivity.onCreate(NewsActivity.kt:26)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor0(Class.java:2327)
at java.lang.Class.getConstructor(Class.java:1725)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:610)
... 47 more
Run Code Online (Sandbox Code Playgroud)
在 com.example.simplenewsapp.ui.NewsActivity.onCreate(NewsActivity.kt:26) 处 是:
Run Code Online (Sandbox Code Playgroud)setContentView(R.layout.activity_news)
所有提供的答案都是错误的,因为片段构造函数不必为空!您可以轻松地在片段中构造函数注入依赖项,但您必须使用片段工厂才能执行此操作。
这是一个供您参考的示例:
@AndroidEntryPoint
class BreakingNewsFragment(
val newsItemAdapter: NewsAdapter,
) : Fragment(R.layout.fragment_breaking_news) {
...
}
Run Code Online (Sandbox Code Playgroud)
class MainFragmentFactory @Inject constructor(
private val newsAdapter: NewsAdapter
// your dependencies
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment = when(className) {
BreakingNewsFragment::class.java.name -> BreakingNewsFragment(newsAdapter)
// here you can add every other fragment
else -> super.instantiate(classLoader, className)
}
}
Run Code Online (Sandbox Code Playgroud)
@AndroidEntryPoint
class MainNavHostFragment : NavHostFragment() {
@Inject lateinit var mainFragmentFactory: MainFragmentFactory
override fun onAttach(context: Context) {
super.onAttach(context)
childFragmentManager.fragmentFactory = mainFragmentFactory
}
}
Run Code Online (Sandbox Code Playgroud)
然后为了使用新的 NavHostFragment,您必须更改 Activity_main.xml
<fragment
android:id="@+id/fragment_container"
android:name="yourPath.MainNavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_main" />
Run Code Online (Sandbox Code Playgroud)
重要的一行在这里“android:name =“yourPath.MainNavHostFragment”或例如“android:name =“com.example.app.ui.MainNavHostFragment”
这样你就可以将构造函数注入到你的片段中。
你不能构造函数注入你的视图模型!您还应该小心使用此方法和构造函数注入适配器,因为它们可能会导致内存泄漏。对于适配器,我建议您现场注入它们
| 归档时间: |
|
| 查看次数: |
1872 次 |
| 最近记录: |