Парсинг JSON с удалённого сервера (Kotlin)
Есть RecyclerView, в который парсится JSON с удалённого сервера.
UPD MainActivity.kt:
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException
import okhttp3.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val client = OkHttpClient()
val list = ArrayList<ListItem>()
val rcView = findViewById<RecyclerView>(R.id.rv_content)
rcView.layoutManager = LinearLayoutManager(this)
rcView.adapter = MyAdapter(list, this)
rcView.hasFixedSize()
val request: Request = Request.Builder()
.url("http://some_link/api/")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
val strResponse = response.body!!.string()
try {
val episodeArray = JSONArray(strResponse)
for (i in 0 until episodeArray.length()) {
val episodeDetails = episodeArray.getJSONObject(i)
list.add(
ListItem(
episodeDetails.getString("pub_date"),
episodeDetails.getString("title"),
episodeDetails.getString("description"),
episodeDetails.getString("youtube_link"),
)
)
}
rcView.adapter?.notifyDataSetChanged()
} catch (e: JSONException) {
e.printStackTrace()
}
}
})
}
}
MyAdapter.kt:
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
class MyAdapter(
listArray: ArrayList<ListItem>, context: Context
) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
var listArrayR = listArray
var contextR = context
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvData = view.findViewById<TextView>(R.id.tv_data)
val tvTitle = view.findViewById<TextView>(R.id.tv_title)
val tvDescription = view.findViewById<TextView>(R.id.tv_description)
val tvYoutube = view.findViewById<TextView>(R.id.tv_youtube)
fun bind(listItem: ListItem, context: Context) {
tvData.text = listItem.episodeData
tvTitle.text = listItem.titleText
tvDescription.text = listItem.contentText
tvYoutube.text = listItem.youtubeFrame
itemView.setOnClickListener() {
val intent = Intent(context, ContentActivity::class.java).apply {
putExtra("data", tvData.text.toString())
putExtra("title", tvTitle.text.toString())
putExtra("description", tvDescription.text.toString())
putExtra("youtube", tvYoutube.text.toString())
}
context.startActivity(intent)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(contextR)
return ViewHolder(inflater.inflate(R.layout.item_layout_main, parent, false))
}
override fun getItemCount(): Int {
return listArrayR.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
var listItem = listArrayR[position]
holder.bind(listItem, contextR)
}
}
UPD Логи:
2024-06-13 20:24:55.058 15679-15775 AndroidRuntime ru.aspavlov.theoaesthetics E FATAL EXCEPTION: OkHttp Dispatcher
Process: ru.aspavlov.theoaesthetics, PID: 15679
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8399)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1496)
at android.view.View.requestLayout(View.java:24786)
at android.view.View.requestLayout(View.java:24786)
at android.view.View.requestLayout(View.java:24786)
at android.view.View.requestLayout(View.java:24786)
at android.view.View.requestLayout(View.java:24786)
at android.view.View.requestLayout(View.java:24786)
at androidx.constraintlayout.widget.ConstraintLayout.requestLayout(ConstraintLayout.java:3605)
at android.view.View.requestLayout(View.java:24786)
at androidx.recyclerview.widget.RecyclerView.requestLayout(RecyclerView.java:4412)
at androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5541)
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:12253)
at androidx.recyclerview.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7354)
at ru.aspavlov.theoaesthetics.MainActivity$onCreate$1.onResponse(MainActivity.kt:53)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
UPD Проблема: приложение крэшится при запуске.
Ответы (1 шт):
Автор решения: Alexey Pavlov
→ Ссылка
Всё, разобрался. В последнем случае приложение крэшилось из-за проблем с зависимостями. Сделал даунгрейд, указав в build.gradle.kts (app)
более раннюю версию OkHttp:
implementation ("com.squareup.okhttp3:okhttp:4.2.1")
После этого завелось.
Низкий поклон всем, кто принял участие в дискуссии! В особенности благодарю woesss за то, что помог правильно прописать обработку массива JSON.