Kotlin开发故事书App遇lateinit未初始化错误(HomeFragment)求助
问题描述
我是Kotlin编程新手,正在开发一款故事书App,计划在HomeFragment中通过本地JSON文件(从Assets加载)结合Glide加载数据,但运行时出现错误:lateinit property itemsList has not been initialized,附上相关代码,请求帮助解决。
错误信息
lateinit property itemsList has not been initialized
HomeFragment 代码
class HomeFragment : Fragment() { private lateinit var bookAdapter: BookAdapter private lateinit var recyclerView: RecyclerView private lateinit var itemsList: ArrayList<BooksData> override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.fragment_home, container, false) // Initialize the RecyclerView recyclerView = view.findViewById(R.id.bookRecyclerView) recyclerView.layoutManager = GridLayoutManager(requireContext(), 2) bookAdapter = BookAdapter(this@HomeFragment, itemsList) recyclerView.adapter = bookAdapter recyclerView.setHasFixedSize(true) itemsList = ArrayList<BooksData>() loadData() return view } private fun loadData() { val jsonString = loadJson("contents.json") val items = parseJson(jsonString) bookAdapter.setData(items) } private fun loadJson(contents: String): String { val inputStream = requireContext().assets.open(contents) val size = inputStream.available() val buffer = ByteArray(size) inputStream.read(buffer) inputStream.close() return String(buffer) } private fun parseJson(jsonString: String): ArrayList<BooksData> { val jsonArray = JSONArray(jsonString) val items = ArrayList<BooksData>() for (i in 0 until jsonArray.length()) { val jsonObject = jsonArray.getJSONObject(i) val imageUrl = jsonObject.getString("imageUrl") val bookName = jsonObject.getString("bookName") items.add(BooksData(imageUrl, bookName)) }; return items } }
数据类代码
data class BooksData(val bookName:String, val imageUrl:String){ }
适配器类代码
class BookAdapter(var context: HomeFragment, private var dataList: ArrayList<BooksData>) : RecyclerView.Adapter<BookAdapter.BookViewHolder>() { inner class BookViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { var bookNameTextView: TextView = itemView.findViewById(R.id.bookName) var bookImageView: ImageView = itemView.findViewById(R.id.imageUrl) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.book_category_item, parent, false) return BookViewHolder(view) } override fun getItemCount(): Int = dataList.size fun setData(data: ArrayList<BooksData>) { dataList.clear() dataList.addAll(data) notifyDataSetChanged() } override fun onBindViewHolder(holder: BookViewHolder, position: Int) { val item = dataList[position] holder.bookNameTextView.text = item.bookName Glide.with(context).load(item.imageUrl).placeholder(R.drawable.ic_launcher_background) .error(R.drawable.vec_quiz).into(holder.bookImageView) } }
JSON文件内容
{ "items": [ { "bookName": "Basic Grammar", "imageUrl": "https://drive.google.com/uc?id=1_eVoTO4IeTW1gAbNBb_0-GWASecBNGgS" } , { "bookName": "Basic Grammar", "imageUrl": "https://drive.google.com/uc?id=1_eVoTO4IeTW1gAbNBb_0-GWASecBNGgS" } ] }
修复方案
1. 解决itemsList未初始化的核心问题
错误根源是创建BookAdapter时,itemsList还没被初始化——你先调用了BookAdapter(this@HomeFragment, itemsList),之后才给itemsList赋值,违反了lateinit变量必须先初始化再使用的规则。
调整onCreateView中的代码顺序,先初始化itemsList再创建适配器:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.fragment_home, container, false) // 先初始化itemsList itemsList = ArrayList<BooksData>() // 初始化RecyclerView相关 recyclerView = view.findViewById(R.id.bookRecyclerView) recyclerView.layoutManager = GridLayoutManager(requireContext(), 2) bookAdapter = BookAdapter(this@HomeFragment, itemsList) recyclerView.adapter = bookAdapter recyclerView.setHasFixedSize(true) loadData() return view }
2. 修复JSON解析错误
你的JSON外层是包含items数组的对象,但当前parseJson方法直接把整个JSON字符串当作数组解析,会抛出格式异常。修改解析逻辑:
private fun parseJson(jsonString: String): ArrayList<BooksData> { val rootObj = JSONObject(jsonString) val jsonArray = rootObj.getJSONArray("items") val items = ArrayList<BooksData>() for (i in 0 until jsonArray.length()) { val itemObj = jsonArray.getJSONObject(i) val bookName = itemObj.getString("bookName") val imageUrl = itemObj.getString("imageUrl") // 注意BooksData构造参数顺序是bookName在前,避免传反 items.add(BooksData(bookName, imageUrl)) } return items }
3. 优化适配器上下文传递(可选)
适配器直接持有HomeFragment实例存在内存泄漏风险,建议改为传递Context:
- 修改适配器构造函数:
class BookAdapter(var context: Context, private var dataList: ArrayList<BooksData>) : RecyclerView.Adapter<BookAdapter.BookViewHolder>() {
- 创建适配器时传入上下文:
bookAdapter = BookAdapter(requireContext(), itemsList)
4. 避免lateinit潜在风险(可选)
如果不想使用lateinit,可以直接初始化itemsList:
private var itemsList: ArrayList<BooksData> = arrayListOf()
这样就无需担心未初始化问题。
内容的提问来源于stack exchange,提问作者Anoop Moji
相关产品推荐
相关产品推荐

