And*_*oid 4 android nullpointerexception kotlin
使用 Kotlin 编写程序并使用 Fragment 来显示从 Firebase 填充 RecyclerView 但有时会出现 NullPointerException 的用户列表,发布日志和代码
日志:
java.lang.NullPointerException
at com.fb.hc.fragments.UsersFragment$retrieveAllUser$1.onDataChange(UsersFragment.kt:108)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.3.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.3.0:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.3.0:55)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7807)
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:1047)
Run Code Online (Sandbox Code Playgroud)
代码:
class UsersFragment : Fragment() {
private var userAdapter: UsersAdapter? = null
private var mUsers: List<Users>? = null
....
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view: View = inflater.inflate(R.layout.fragment_users, container, false)
mUsers = ArrayList()
retrieveAllUser()
return view
}
private fun retrieveAllUser() {
val firebaseUserID = FirebaseAuth.getInstance().currentUser!!.uid
val refUser = FirebaseDatabase.getInstance().reference.child("Users")
refUser.addValueEventListener(object : ValueEventListener{
override fun onDataChange(p0: DataSnapshot)
{
(mUsers as ArrayList).clear()
if (topicCompleteView.text.toString() == "") {
for (snapshot in p0.children)
{
val user: Users? = snapshot.getValue(Users::class.java)
if (!(user?.getUID()).equals(firebaseUserID) && user != null) {
(mUsers as ArrayList<Users>).add(user)
}
}
if (mUsers.isNullOrEmpty()) {
} else {
// error line
userAdapter = UsersAdapter(context!!, mUsers as ArrayList<Users>, false)
recyclerView.adapter = userAdapter
}
}
}
Run Code Online (Sandbox Code Playgroud)
您直接在片段中执行异步 I/O。然后,您尝试在该工作完成后更新片段的 UI。
问题是有时您的片段会在工作完成之前被销毁(例如,用户按下“后退”按钮)。在这种情况下,context将会是null并且context!!将会是……很糟糕。
战术修复是仅在有上下文的情况下更新 UI:
activity?.let {
userAdapter = UsersAdapter(it, mUsers as ArrayList<Users>, false)
recyclerView.adapter = userAdapter
}
Run Code Online (Sandbox Code Playgroud)
更好的解决方法是完全从片段中获取此 I/O。如果用户触发配置更改(旋转屏幕、切换暗模式等),您的新片段将无法从原始片段获取 I/O 结果。最好将此 I/O 移动到ViewModel您的片段使用的 I/O 中,在其中通过一个或类似的机制提供这些结果LiveData。您的片段将观察LiveData并应用结果。这不仅修复了崩溃,而且还可以更好地处理配置更改。
| 归档时间: |
|
| 查看次数: |
1009 次 |
| 最近记录: |