在Android中获取JSON对象 [英] Get json object in android

查看:86
本文介绍了在Android中获取JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have article view where each post of mine will show details (think of it as blog post) but i cannot parse the data so i get my app closed instead of details of my articles.

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个文件:

then for views i have this 2 files:

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文件将在以后进行编辑以获取更多信息 我的文章的详细信息,例如正文或用户等,但现在需要测试 返回的数据,我认为拥有文章的名称和图像就足够了.

Obviously this last xml file will be edited in future to get more details of my articles such as body or user etc. but for now to test returned data i think having name and image of article is enough.

数据

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

Data

this is how my returned data in this activity looks like,

    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. 我该如何解决?
  1. Any idea which part of my callAPIDemo() function or getPosts() function causing error?
  2. how can I fix it?

更新

我的json数据:

Update

my json data:

{
  "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"
}

推荐答案

实际上,您的数组名称是类别,而不是文章

Actually the name of your Array is categories not article

因此在代码val jsonArray = jsonObject.getJSONArray("article")的这一行中,您无需添加文章,而只需添加类别

so in this line of your code val jsonArray = jsonObject.getJSONArray("article"), instead of article you need to add categories

类似下面的

val jsonArray = jsonObject.getJSONArray("categories")

-

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

As discussed your article_details.xml will be like below

在这里您可以根据需要更改sizemargins

Here you can change size and margins, as you want

<?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接收数据时就可以在它们上设置值

Now just do the findfindViewById in your ArticlesDetail class so you can set values on them when you receive data from your API

-

现在,您的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!!)


    }


}

这篇关于在Android中获取JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆