Android - Activity 和 Fragment 初始化

Posted

技术标签:

【中文标题】Android - Activity 和 Fragment 初始化【英文标题】:Android - Activity and Fragment initialization 【发布时间】: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_
    android:layout_
    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_
        android:layout_
        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 【参考方案1】:

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

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

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

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

【讨论】:

以上是关于Android - Activity 和 Fragment 初始化的主要内容,如果未能解决你的问题,请参考以下文章

Fragment基础操作

android camera2连拍

Android - Grow Heap (Frag Case) - Byte Allocation.. 不加载任何位图

安卓APP_ Fragment—— Activity与Fragment的通信

Fragment中无法选择GridView项

c_cpp openFrameworks内联着色器模板(仅限vert和frag)