【问题标题】:Passing different values for Shared Preferences为共享首选项传递不同的值
【发布时间】:2023-03-20 05:22:01
【问题描述】:

我在这里是一个没有经验的 Android 学习者!

所以我在学习,在我的项目中,我必须使用url和shared preferences (Volley)来显示Recycler View中的项目。

所以categoriesuser_idapi_key作为参数,然后subcategoriesuser_idcat_idapi_key作为参数参数。

我使用 JSONObject 来解析类别,并尝试将 类别 ids 保存在shared preferences

所以在SubcategoryFragment之后,我再次调用shared preferences,它运行了。但我注意到,对于所有类别项目,只有一个 id 用于子类别。所以基本上多个类别都在调用同一个子类别。

我认为是因为在我的SubcategoryFragment 代码中,我只调用了一次共享首选项的编辑器,而在 CategoryFragment 中,我将编辑器放在了 JSON 数组的 for 循环中。

请告诉我你的想法。我很欣赏它!

我保存categoryID的CategoryFragment:


    var catList = ArrayList<CategoryItem>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        // Inflate the layout for this fragment
        var view =  inflater.inflate(R.layout.fragment_main_act, container, false)

        //Recycler view
        view.recyclerViewCat.layoutManager = LinearLayoutManager(context)

        var sp: SharedPreferences = this.activity!!.getSharedPreferences("chamber", Context.MODE_PRIVATE)
        var editor = sp.edit()


        var iD = sp.getString("user_id", "Default")
        var apiKey = sp.getString("user_apikey", "Default")

        val url = "XXXX.php?cust_category.php?api_key=$apiKey&user_id=$iD"

        var stringRequest = StringRequest(Request.Method.GET, url,

            Response.Listener {

                var jsonObject = JSONObject(it)

                var jsonArrayCats =jsonObject.getJSONArray("category")

                for(i in 0 until jsonArrayCats.length()){

                    var cats =jsonArrayCats.getJSONObject(i)

                    var cID = cats.getString("cid")
                    var cName = cats.getString("cname")
                    var cDes = cats.getString("cdiscription")
                    var cImg = cats.getString("cimagerl")

                    catList.add(CategoryItem(cID, cName, cDes, cImg))

                    editor.putString("cat_id", cID)
                    editor.putString("cat_name", cName)
                    editor.putString("cat_des", cDes)
                    editor.putString("cat_Img", cImg)

                }
                editor.apply()

                val adapter = CatAdapter(catList, view.context)
                view.recyclerViewCat.adapter = adapter

            },
            Response.ErrorListener {
                Toast.makeText(view.context, "invalid api key or user id", Toast.LENGTH_SHORT).show()
            }

        )

        Volley.newRequestQueue(view.context).add(stringRequest)

        return view
    }

还有我使用它的SubcategoryFragment

    var scatList = ArrayList<SubCategoryItem>()

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

        view.recyclerViewSubCat.layoutManager = LinearLayoutManager(context)

        var sp: SharedPreferences = this.activity!!.getSharedPreferences("chamber", Context.MODE_PRIVATE)
        var editor = sp.edit()

        var catId = sp.getString("cat_id", "Default")
        var apiKey = sp.getString("user_apikey", "Default")
        var userId = sp.getString("user_id", "Default")

        val url = "XXXXX.php?Id=$catId&api_key=$apiKey&user_id=$userId"

        var stringReq = StringRequest(Request.Method.GET, url,
            Response.Listener {

                var jsonObject = JSONObject(it)
                var jsonArraySCat = jsonObject.getJSONArray("subcategory")

                for(i in 0 until jsonArraySCat.length()){

                    var scats = jsonArraySCat.getJSONObject(i)

                    var scID = scats.getString("scid")
                    var scName = scats.getString("scname")
                    var scDes = scats.getString("scdiscription")
                    var scImg = scats.getString("scimageurl")

                    editor.putString("scat_id", scID)
                    editor.putString("scat_name", scName)
                    editor.putString("scat_des", scDes)
                    editor.putString("scat_Img", scImg)

                    scatList.add(SubCategoryItem(scID, scName, scDes, scImg))

                }

                editor.commit()

                val adapter = SubCatAdapter(scatList, view.context)
                view.recyclerViewSubCat.adapter = adapter

            },

            Response.ErrorListener {
                Log.e("ERROR", it.message.toString())
                Toast.makeText(view.context, "No data", Toast.LENGTH_SHORT).show()
            }

        )

        Volley.newRequestQueue(view.context).add(stringReq)

【问题讨论】:

    标签: android json kotlin sharedpreferences android-volley


    【解决方案1】:

    这是因为SharedPreferences 覆盖了具有相同键的值。 例如,您的“房间”SharedPreferences 中的键“scid”只有一个值 -

    所以如果你做这样的事情 -

    for(i in 0 until jsonArraySCat.length()){
        editor.putString("scat_id", scID)
    }
    

    每次调用时都会覆盖键“scat_id”的值。

    溶胶。 - 您可以将完整的 JSONObject 保存为 String 在您的 SharedPreferences 中,例如 -

    editor.putString("jsonResponse", jsonObject.toString())
    

    然后解析和重用它。

    更新:

    像这样更新你的代码 -

    Response.Listener {
      var stringReq = StringRequest(Request.Method.GET, url,
    
    //Save in SharedPref
        editor.putString("api_response", it)
        editor.commit()
    
    //Use a common parsing function
    scatList = getParsedData(it)          //it or from SharedPref
    
    val adapter = SubCatAdapter(scatList, view.context)
    view.recyclerViewSubCat.adapter = adapter
    
    }
    

    // 解析数据的常用函数

    fun getParsedData(strResponse: String?): List<SubCategoryItem>{
      if(!strResponse.isNullOrEmpty()){
        try{
          val list = ArrayList<SubCategoryItem>()
          var jsonObject = JSONObject(it)
          var jsonArraySCat = jsonObject.getJSONArray("subcategory")
    
    repeat(jsonArraySCat.length()){                    //use repeat than for loop
      jsonArraySCat.getJSONObject(it).run{
        SubCategoryItem(getString("scid"), scats.getString("scname"), scats.getString("scdiscription"), scats.getString("scimageurl")).also{
          list.add(it)
        }
      }
    }
    return list    //return parsed data list
    }catch(e: JSONException){
      Log.d(TAG, "Parse Exception $e")  
    }
    }
    return ArrayList()  //return empty list
    }
    

    【讨论】:

    • 谢谢!所以基本上通过这样做,我将json作为一个String,在另一个片段中调用它,然后再次解析json?
    • 谢谢!所以我这样做了,在下一个片段中调用共享首选项,并使用 for 循环来解析 json 数组。然后我还将url和整个字符串请求放在for循环中,我得到了错误java.lang.RuntimeException: java.lang.reflect.InvocationTargetExceptionCaused by: java.lang.reflect.InvocationTargetExceptionCaused by: org.json.JSONException: End of input at character 0 of
    • 您收到此异常是因为您尝试转换为 json 的字符串为空。在解析 json 数据时,也始终使用带有 JSONException 的 try/catch。
    • 答案已更新@HumbleHermit
    • 非常感谢您的宝贵时间!我从来不知道有“重复”的事情
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多