【问题标题】:Android - Activity and Fragment initializationAndroid - Activity 和 Fragment 初始化
【发布时间】:2021-12-14 02:50:56
【问题描述】:

按照 Google 的建议,我有一个由一个活动和几个片段组成的应用程序。其他详情here。我想保持菜单静止并在中心的容器中切换我的片段。

activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:someProperties="propertiesValues">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:someProperties="propertiesValues" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/navigation_map"
        />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:someProperties="propertiesValues" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

主要活动

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        println("Activity creation")
        val binding = ActivityMainBinding.inflate(layoutInflater)
        println("Activity creation part 2")
        setContentView(binding.root)
        setSupportActionBar(binding.toolbar)

        User.initSharedPref(this)
    }

片段

private lateinit var mylist: MutableList<String>>
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    println("Fragment creation")

    mylist = User.loadScenarioList()
}

用户

object User
{
  private lateinit var sharedPref : SharedPreferences

  fun initSharedPref(context: Context){
    sharedPref = context.getSharedPreferences("JeuDePisteKtPreferenceFileKey",Context.MODE_PRIVATE)
  }

  fun loadList(): MutableList<String>> {
      val json = sharedPref.getString(KEY_LIST, "") ?: ""
      if (json == "") return mutableListOf()
      return Json.decodeFromString(json)
  }

}

遇到的问题

当我启动活动时,它会初始化一个变量sharedPref ,如代码所示。

但是当我在片段 onCreate 中使用此变量 (mylist = User.loadScenarioList()) 时,活动中的绑定行失败并显示 Binary XML file line #31: Error inflating class androidx.fragment.app.FragmentContainerView,如下面的 logcat 所示

Logcat 和错误

这是完整的 logcat,我们可以看到第二个 sout 丢失了,但此时没有抛出错误。

【问题讨论】:

  • 没有错误消息的崩溃永远不会发生。检查以确保 Logcat 正常工作并且不会过滤您的日志。您链接的问题与活动无关。这是在 Activity 中扩展视图的正确位置,并且您的代码看起来不错。
  • 想详细说明menu 这里是ActionBar 菜单还是那些fab 按钮?
  • 崩溃实际上发生在以后,因为我在我的 Activity.OnCreate() 结束时初始化的 Lateinit 属性在我的 Fragment.OnCreate() 中使用。对于调试,我还添加了打印,无法到达,但没有错误。我用 logcat 在上面添加了它
  • 我更准确地发现了问题,并用它改变了问题。真正的错误与片段错误混合在一起,但我在ActivityMainBinding.inflate(layoutInflater) 行之前做了一个断点,然后评估它,它返回Binary XML file line #31: Error inflating class androidx.fragment.app.FragmentContainerView

标签: android kotlin android-fragments layout-inflater


【解决方案1】:

这里的问题来自于创建调用的顺序

我们可以在更正后的代码logcat中看到

首先调用活动 onCreate,但第一次膨胀调用片段 OnCreate,然后再恢复活动 OnCreate。

所以片段onCreate中使用的每个变量都应该在inflate调用之前初始化

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 2015-05-09
    相关资源
    最近更新 更多