【问题标题】:Get json object in android在android中获取json对象
【发布时间】:2020-02-11 10:14:36
【问题描述】:

我有文章视图,我的每篇文章都会显示详细信息(将其视为博客文章),但我无法解析数据,因此我关闭了我的应用程序而不是我的文章的详细信息。

代码

ArticlesAdapter.kt

class ArticlesAdapter(val article : ArrayList<Article>) : RecyclerView.Adapter<ArticlesAdapter.ViewHolder>() {

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

    override fun getItemCount(): Int {
        return article.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = article.get(position).name

        Glide.with(holder.aImage.context)
            .load(article.get(position).image)
            .placeholder(R.drawable.placeholder2)
            .error(R.drawable.placeholder2)
            .fallback(R.drawable.placeholder2) // if load was null
            .into(holder.aImage)

        Log.e("ImageURL", "URL = " + article.get(position).image)
    }


    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var textView: TextView
        var aImage: ImageView

        init {
            textView = itemView.findViewById(R.id.text_name)
            aImage = itemView.findViewById(R.id.a_image)
        }
    }
}

ArticlesDetail.tk (my activity)

class ArticlesDetail : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.article_details)

        callAPIDemo()
    }

    // api code
    private fun callAPIDemo() {
        val mySlugValue: String = intent.getStringExtra("my_slug")
        Log.d("myslug in:", mySlugValue)
        // Instantiate the RequestQueue.
        val queue = Volley.newRequestQueue(this)
        val url = "https://example.com/api/articles/$mySlugValue"

        // Request a string response from the provided URL.
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            Response.Listener<String> { response ->

                val list: ArrayList<Article> = ArrayList()
                getPosts(response,list)

                // here you will have the complete list of data in your "list" variable
                article_det.layoutManager = LinearLayoutManager(this)
                Log.d("my list", list.toString())
                article_det.adapter = ArticlesAdapter(list)
            },
            Response.ErrorListener { error ->
                //displaying the error in toast if occurrs
                Toast.makeText(applicationContext, error.message, Toast.LENGTH_SHORT)
                    .show()
            })
        // Add the request to the RequestQueue.
        queue.add(stringRequest)
    }


    fun getPosts(response: String,list:ArrayList<Article>) {

        var jsonObject = JSONObject(response)
        val jsonArray = jsonObject.getJSONArray("article")

        for (i in 0 until jsonArray.length()) {
            val jsonObject1 = jsonArray.getJSONObject(i)
            var listingObject = Article(
                jsonObject1.getInt("id"),
                jsonObject1.getString("name"),
                jsonObject1.getString("slug"),
                jsonObject1.getString("image"),
                jsonObject1.getString("body"),
                jsonObject1.getString("icon"),
                jsonObject1.getString("quote"),
                jsonObject1.getString("video"),
                jsonObject1.getString("user"),
                jsonObject1.getString("created_at"),
                jsonObject1.getString("updated_at")

            )
            list.add(listingObject)

        }
    }
}

Article.kt (my class)

data class Article (
    val id: Int,
    val name: String?,
    val slug: String?,
    val image: String?,
    val body: String?,
    val icon: String?,
    val quote: String?,
    val user: String?,
    val video: String?,
    val created_at: String?,
    val updated_at: String?
)

那么对于视图,我有这 2 个文件:

article_details.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/article_det"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_articles.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">

    <ImageView
        android:id="@+id/a_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:contentDescription="@string/image"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/a_image"
        app:layout_constraintStart_toEndOf="@+id/a_image"
        app:layout_constraintTop_toTopOf="@+id/a_image" />

</androidx.constraintlayout.widget.ConstraintLayout>

很明显,这最后一个 xml 文件将来会被编辑以获得更多 我的文章的详细信息,例如正文或用户等,但现在要测试 返回的数据我认为有文章的名称和图像就足够了。

数据

这就是我在此活动中返回的数据的样子,

错误

    Caused by: org.json.JSONException: No value for article
    at org.json.JSONObject.get(JSONObject.java:392)
    at org.json.JSONObject.getJSONArray(JSONObject.java:587)
    at ui.ArticlesDetail.ArticlesDetail.getPosts(ArticlesDetail.kt:63)
    at ui.ArticlesDetail.ArticlesDetail$callAPIDemo$stringRequest$1.onResponse(ArticlesDetail.kt:43)
    at ui.ArticlesDetail.ArticlesDetail$callAPIDemo$stringRequest$1.onResponse(ArticlesDetail.kt:18)

我的第 63 行:val jsonArray = jsonObject.getJSONArray("article")

我的第 43 行:getPosts(response,list)

我的第 18 行:class ArticlesDetail : AppCompatActivity() {

问题

  1. 知道我的callAPIDemo() 函数或getPosts() 的哪一部分 导致错误的函数?
  2. 我该如何解决?

更新

我的 json 数据:

{
  "id": 4,
  "user": "...",
  "name": "...",
  "slug": "...",
  "image": "...",
  "body": "...",
  "icon": null,
  "quote": null,
  "video": null,
  "categories": [
    {
      "id": 10,
      "name": "...",
      "slug": "...",
      "icon": "..",
      "body": "...",
      "image": "...",
      "created_at": "2019-11-23 05:35:31",
      "updated_at": "2019-11-26 11:25:17"
    }
  ],
  "created_at": "2019-11-23 07:34:10",
  "updated_at": "2019-11-23 07:37:52"
}

【问题讨论】:

  • 您能否添加您的 JSON 数据作为示例。我要检查结构。
  • @AtishAgrawal 当然
  • 为什么不使用改造或 volley 之类的库?
  • @SinaMN75 我正在使用 volley 查看我的callAPIDemo() 功能

标签: android kotlin


【解决方案1】:

实际上,您的 Array 的名称是 categories 而不是 article

所以在这行代码 val jsonArray = jsonObject.getJSONArray("article") 中,您需要添加 categories

而不是文章

类似下面的东西

val jsonArray = jsonObject.getJSONArray("categories")

编辑 1:-

如上所述,您的article_details.xml 将如下所示

您可以在此处随意更改sizemargins

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/article_image"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_marginStart="15dp"
        android:layout_marginEnd="15dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="30dp"
        android:layout_marginTop="15dp"
        android:maxLines="1"
        android:text="userName"
        android:textSize="14sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/article_image" />


    <TextView
        android:id="@+id/article_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="30dp"
        android:layout_marginTop="5dp"
        android:maxLines="1"
        android:text="Article name"
        android:textSize="18sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/username" />


    <TextView
        android:id="@+id/article_body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="15dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="15dp"
        android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. "
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/article_name" />

</androidx.constraintlayout.widget.ConstraintLayout>

现在只需在 ArticlesDetail 类中执行 findfindViewById,以便在从 API 接收数据时设置它们的值

编辑 2:-

现在你的ArticlesDetail 会像

class ArticlesDetail : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration


    var username: TextView? = null
    var articleName: TextView? = null
    var articleBody: TextView? = null
    var articleImage: ImageView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        username = findViewById(R.id.username)
        articleName = findViewById(R.id.article_name)
        articleBody = findViewById(R.id.article_body)
        articleImage = findViewById(R.id.article_image)

        callAPIDemo()
    }

    // api code
    private fun callAPIDemo() {
        val mySlugValue: String = intent.getStringExtra("my_slug")
        Log.d("myslug in:", mySlugValue)
        // Instantiate the RequestQueue.
        val queue = Volley.newRequestQueue(this)
        val url = "https://example.com/api/articles/$mySlugValue"

        // Request a string response from the provided URL.
        val stringRequest = StringRequest(
                Request.Method.GET, url,
                Response.Listener<String> { response ->


                    parseAndSetValues(response)

                },
                Response.ErrorListener { error ->
                    //displaying the error in toast if occurrs
                    Toast.makeText(applicationContext, error.message, Toast.LENGTH_SHORT)
                            .show()
                })
        // Add the request to the RequestQueue.
        queue.add(stringRequest)
    }


    private fun parseAndSetValues(response: String) {


        val jsonObject = JSONObject(response)


        username!!.text = jsonObject.getString("user")
        articleName!!.text = jsonObject.getString("name")
        articleBody!!.text = jsonObject.getString("body")
        Glide.with(this).load(jsonObject.getString("image")).into(articleImage!!)


    }


}

【讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 你好,我刚刚测试了你的更新它正在工作,但有一个小问题,因为我的文章正文来自网络版本数据库,它包含 html 标签,例如 &lt;p&gt;, &lt;div&gt;, &lt;h1&gt; etc. 这显示正文部分所有这些 html 标签,我怎样才能让它读取标签而不是仅仅打印它们? screenshotibb.co/yWWsj9z
【解决方案2】:

您的响应 JSON 中没有名为“article”的 JSONArray。这就是它导致错误的原因 删除这部分

 val jsonArray = jsonObject.getJSONArray("article")

        for (i in 0 until jsonArray.length()) {
            val jsonObject1 = jsonArray.getJSONObject(i)
            var listingObject = Article(
                jsonObject1.getInt("id"),
                jsonObject1.getString("name"),
                jsonObject1.getString("slug"),
                jsonObject1.getString("image"),
                jsonObject1.getString("body"),
                jsonObject1.getString("icon"),
                jsonObject1.getString("quote"),
                jsonObject1.getString("video"),
                jsonObject1.getString("user"),
                jsonObject1.getString("created_at"),
                jsonObject1.getString("updated_at")

            )
            list.add(listingObject)

        }

添加这个

               Int id = jsonObject.getInt("id"),
               String name =  jsonObject.getString("name"),
               String slug =  jsonObject.getString("slug"),
               String image =  jsonObject.getString("image"),
               String body =  jsonObject.getString("body"),
               String icon =  jsonObject.getString("icon"),
               String quote =  jsonObject.getString("quote"),
               String video =  jsonObject.getString("video"),
               String user = jsonObject.getString("user"),
               String created_at =  jsonObject.getString("created_at"),
               String updated_at =  jsonObject.getString("updated_at")

 ``

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2014-10-16
    • 2015-09-10
    • 2013-03-05
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多