这是与 LiveData 相关的错误吗
Is this a bug relating to LiveData
我已经分离出显示此问题的代码。
我在片段中有一个 recyclerview。我还有 LiveData 和 MutableLiveData。
在 ViewModel.kt 代码中有以下两行,并且工作正常:
private val mMLD = MutableLiveData<OneLine>()
var mLD : LiveData<OneLine> = getMLD()
如果我倒序,即
var mLD : LiveData<OneLine> = getMLD()
private val mMLD = MutableLiveData<OneLine>()
程序崩溃。
这是一个错误吗?
我正在使用 Android Studio Chipmunk 2021.2.1
这是我的代码:
class Adapter(private var mList: List<OneLine>) : RecyclerView.Adapter<Adapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.one_line, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val DisplayViewModel = mList.get(position)
holder.textView.text = DisplayViewModel.text
}
override fun getItemCount(): Int {
return mList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val textView: TextView = itemView.findViewById(R.id.textView)
}
}
class Fragment : Fragment() {
private lateinit var adapter : Adapter
private lateinit var viewModel: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment, container, false)
viewModel = ViewModelProvider(requireActivity()).get(ViewModel::class.java)
viewModel.Initialize()
enableRecyclerView(view)
viewModel.mLD.observe(viewLifecycleOwner, Observer {
adapter.notifyDataSetChanged()
})
return view
}
fun enableRecyclerView(view:View){
var mRecyclerView: RecyclerView? = null
mRecyclerView = view.findViewById(R.id.recycler_view)
val linearLayoutManager = LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)
mRecyclerView.layoutManager = linearLayoutManager
adapter = Adapter(viewModel.rvData) // This will pass the ArrayList to our Adapter
mRecyclerView.adapter = adapter
}
}
class MainActivity : AppCompatActivity() {
private lateinit var operator_display: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
data class OneLine(val text: String) {
}
class ViewModel : ViewModel(){
var mLD : LiveData<OneLine> = getMLD() // observer watches this variable
private val mMLD = MutableLiveData<OneLine>()
private fun getMLD():MutableLiveData<OneLine>{return mMLD}
var rvData = ArrayList<OneLine>()
fun Initialize(){
rvData.add(OneLine("Item A"))
rvData.add(OneLine("Item B"))
rvData.add(OneLine("Item C"))
}
}
private val _thing = "hi"
val wow = getThing() // _thing already assigned
fun getThing():String { return _thing }
fun main() {
println(wow)
}
> hi
val wow = getThing() // _thing not assigned yet
private val _thing = "hi"
fun getThing():String { return _thing } // called when assigning wow, _thing not assigned yet
fun main() {
println(wow)
}
> null
当您通过函数初始化属性时,您可以 运行 遇到这样的问题,其中声明顺序很重要,或者编译器无法判断变量肯定在某处初始化。所以在这里,您有效地跳到了一个在变量被赋值之前引用该变量的函数
由于尚未分配,因此处于默认状态,即 null。另请注意,即使函数的 return 类型为 non-null String
,它仍为 null - 此时 null 检查系统无法帮助您。
你没有 post 你的实际错误,但猜测它是 运行 进入那个 null 并且当你尝试调用 [=14= 时崩溃 NullPointerException
] 在上面,或者 null 检查器看到你将它分配给不应该为 null 的东西,并且它会“等待第二个伙伴”
我已经分离出显示此问题的代码。
我在片段中有一个 recyclerview。我还有 LiveData 和 MutableLiveData。
在 ViewModel.kt 代码中有以下两行,并且工作正常:
private val mMLD = MutableLiveData<OneLine>()
var mLD : LiveData<OneLine> = getMLD()
如果我倒序,即
var mLD : LiveData<OneLine> = getMLD()
private val mMLD = MutableLiveData<OneLine>()
程序崩溃。
这是一个错误吗?
我正在使用 Android Studio Chipmunk 2021.2.1
这是我的代码:
class Adapter(private var mList: List<OneLine>) : RecyclerView.Adapter<Adapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.one_line, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val DisplayViewModel = mList.get(position)
holder.textView.text = DisplayViewModel.text
}
override fun getItemCount(): Int {
return mList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val textView: TextView = itemView.findViewById(R.id.textView)
}
}
class Fragment : Fragment() {
private lateinit var adapter : Adapter
private lateinit var viewModel: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment, container, false)
viewModel = ViewModelProvider(requireActivity()).get(ViewModel::class.java)
viewModel.Initialize()
enableRecyclerView(view)
viewModel.mLD.observe(viewLifecycleOwner, Observer {
adapter.notifyDataSetChanged()
})
return view
}
fun enableRecyclerView(view:View){
var mRecyclerView: RecyclerView? = null
mRecyclerView = view.findViewById(R.id.recycler_view)
val linearLayoutManager = LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)
mRecyclerView.layoutManager = linearLayoutManager
adapter = Adapter(viewModel.rvData) // This will pass the ArrayList to our Adapter
mRecyclerView.adapter = adapter
}
}
class MainActivity : AppCompatActivity() {
private lateinit var operator_display: ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
data class OneLine(val text: String) {
}
class ViewModel : ViewModel(){
var mLD : LiveData<OneLine> = getMLD() // observer watches this variable
private val mMLD = MutableLiveData<OneLine>()
private fun getMLD():MutableLiveData<OneLine>{return mMLD}
var rvData = ArrayList<OneLine>()
fun Initialize(){
rvData.add(OneLine("Item A"))
rvData.add(OneLine("Item B"))
rvData.add(OneLine("Item C"))
}
}
private val _thing = "hi"
val wow = getThing() // _thing already assigned
fun getThing():String { return _thing }
fun main() {
println(wow)
}
> hi
val wow = getThing() // _thing not assigned yet
private val _thing = "hi"
fun getThing():String { return _thing } // called when assigning wow, _thing not assigned yet
fun main() {
println(wow)
}
> null
当您通过函数初始化属性时,您可以 运行 遇到这样的问题,其中声明顺序很重要,或者编译器无法判断变量肯定在某处初始化。所以在这里,您有效地跳到了一个在变量被赋值之前引用该变量的函数
由于尚未分配,因此处于默认状态,即 null。另请注意,即使函数的 return 类型为 non-null String
,它仍为 null - 此时 null 检查系统无法帮助您。
你没有 post 你的实际错误,但猜测它是 运行 进入那个 null 并且当你尝试调用 [=14= 时崩溃 NullPointerException
] 在上面,或者 null 检查器看到你将它分配给不应该为 null 的东西,并且它会“等待第二个伙伴”