【问题标题】:Android App crashes when using Args and Room between fragmentsAndroid App 在片段之间使用 Args 和 Room 时崩溃
【发布时间】:2021-10-02 18:49:23
【问题描述】:

我正在测试 Room 数据库,并在我的列表片段和更新片段之间传递信息。列表片段包含按房间存储的 RecyclerView 中的用户列表,更新片段应该允许我编辑按房间存储的用户数据。因此,如果我单击列表片段中的用户,它应该使用 navargs 传递用户对象并提示我进入带有 EditText 视图和 EditText 字段中的用户数据的屏幕。但是,当我这样做时,我的 android 应用程序崩溃了。

这是错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testingroomdatabase, PID: 9192
    java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
     Caused by: java.lang.NoSuchMethodException: java.lang.Object.fromBundle [class android.os.Bundle]
        at java.lang.Class.getMethod(Class.java:2072)
        at java.lang.Class.getMethod(Class.java:1693)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:46)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:34)
        at com.example.testingroomdatabase.realFragments.update.UpdateFragment.getArgs(Unknown Source:4)
        at com.example.testingroomdatabase.realFragments.update.UpdateFragment.onCreateView(UpdateFragment.kt:23)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

这是更新片段:

package com.example.testingroomdatabase.realFragments.update

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.navArgs
import com.example.testingroomdatabase.R
import kotlinx.android.synthetic.main.fragment_update_fragment.*
import kotlinx.android.synthetic.main.fragment_update_fragment.view.*

class UpdateFragment : Fragment() {
    private val args: UpdateFragmentArgs by navArgs()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view =  inflater.inflate(R.layout.fragment_update_fragment, container, false)

        view.updateFirstName_et.setText(args.currentUser.firstName)
        view.updateLastName_et.setText(args.currentUser.lastName)
        view.updateAge_et.setText(args.currentUser.age.toString())

//        view.update_btn.setOnClickListener{}

        return view

    }
}

这是 ListFragment 代码

package com.example.testingroomdatabase.realFragments.list

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.testingroomdatabase.R
import com.example.testingroomdatabase.viewmodel.UserViewModel
import kotlinx.android.synthetic.main.fragment_list.view.*

class listFragment : Fragment() {
    private lateinit var mUserViewModel: UserViewModel
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_list, container, false)

        // Recycler View
        val adapter = listAdapter()
        val recyclerView = view.recyclerview
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(requireContext())

        //UserViewModel
        mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
        mUserViewModel.readAllData.observe(viewLifecycleOwner,Observer{user ->
            adapter.setData(user)
        } )


        view.floatingActionButton.setOnClickListener{
            findNavController().navigate(R.id.action_listFragment_to_addFragment)
        }
        return view
    }
}

编辑

这是 ListAdapter 代码,它是 RecyclerView 的适配器,包含导航到 UpdateFragment 的每个列表项的 onclicklistener。这工作正常,但是当我尝试将用户数据加载到 UpdateFragment 的文本字段中时,错误就开始了。

package com.example.testingroomdatabase.realFragments.list

import android.view.View
import android.view.ViewGroup
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.example.testingroomdatabase.R
import com.example.testingroomdatabase.model.User
import kotlinx.android.synthetic.main.row_item.view.*
import org.jetbrains.anko.layoutInflater


class listAdapter: RecyclerView.Adapter<listAdapter.ViewHolder>(){

    private var userList = emptyList<User>()

    class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
//        return ViewHolder(layoutInflater.from(parent.context).inflate(R.layout.row_item, parent, false))
        val view = parent.context.layoutInflater.inflate(
            R.layout.row_item,
            parent,
            false
        )
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val currentItem = userList[position]
        holder.itemView.id_text.text =currentItem.id.toString()
        holder.itemView.firstName_text.text = currentItem.firstName
        holder.itemView.lastName_text.text = currentItem.lastName
        holder.itemView.age_text.text = currentItem.age.toString()

        holder.itemView.row_layout.setOnClickListener{
            val action = listFragmentDirections.actionListFragmentToUpdateFragment(currentItem)
            holder.itemView.findNavController().navigate(action)
        } //Navigates to Update Fragment

    }

    fun setData(user: List<User>){
        this.userList = user
        notifyDataSetChanged()
    }
    override fun getItemCount(): Int {
        return userList.size
    }

}

我正在关注此代码的教程。如果需要,我可以链接。感谢您的指导。

【问题讨论】:

  • 您介意添加实际触发导航的部分吗? IE。获取navController 并使用它导航的部分。
  • 是的,对不起,我在我的 ListAdapter 中为我的 RecyclerView 显示了列表。我也会添加该代码。
  • @AhmedAnwer 您是否为此项目启用了 proguard?
  • 那是什么以及如何启用它?在我的 build.gradle 中?
  • @AhmedAnwer 这只是一个问题。我已经读过,如果启用了 proguard,那么它会导致这个问题。只需检查您的 build.gradle 中是否有 minifyEnabled trueshrinkResources true

标签: android kotlin android-room


【解决方案1】:

我在生产中的应用程序中遇到了同样的问题。我也使用 navArgs,我做了一些研究,发现了一些关于使用 safeArgs 的信息。现在我从 navArgs 切换到 UpdateFragmentArgs.fromBundle(requireArguments())。

强烈推荐阅读navArgs文档部分。我希望它能帮助你解决你的问题。它解决了我的问题:)

【讨论】:

    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多