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 初始化的主要内容,如果未能解决你的问题,请参考以下文章
Android - Grow Heap (Frag Case) - Byte Allocation.. 不加载任何位图