安卓中查看JSON中的图片:从解析到显示的完整指南
在安卓开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,常用于前后端数据交互,而图片作为常见的资源,也常以Base64编码或URL链接的形式存储在JSON中,本文将详细介绍如何在安卓应用中解析JSON数据,并正确显示其中的图片内容,涵盖从数据解析到图片显示的全流程。
明确JSON中图片的存储方式
在开始解析前,首先需要明确JSON中图片数据的存储形式,这直接影响后续的解析和显示逻辑,常见的图片存储方式有两种:
Base64编码字符串
Base64是一种将二进制数据转换为文本字符串的编码方式,可直接嵌入JSON中,无需额外请求资源。
{
"imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k=",
"imageDesc": "风景图片"
}
特点:数据直接包含在JSON中,无需网络请求,但编码后数据量会增大(约增大33%),适合小图片或离线场景。
图片URL链接
图片以网络链接的形式存储在JSON中,需要通过HTTP/HTTPS请求获取。
{
"imageUrl": "https://example.com/images/landscape.jpg",
"imageDesc": "网络图片"
}
特点:数据量小,适合大图片或动态更新的内容,但依赖网络,需处理加载失败、缓存等问题。
安卓中解析JSON数据
安卓提供了多种JSON解析库,如原生org.json、Google的Gson、Square的Moshi等,这里以最常用的Gson和org.json为例,介绍如何解析JSON中的图片字段。
添加依赖
首先在app/build.gradle中添加解析库依赖(以Gson为例):
implementation 'com.google.code.gson:gson:2.10.1'
定义数据模型
根据JSON结构创建对应的Kotlin/Java数据类(以Kotlin为例):
data class ImageData(
val imageUrl: String,
val imageDesc: String
)
解析JSON字符串
(1)使用Gson解析
import com.google.gson.Gson
fun parseJsonWithGson(jsonString: String): ImageData? {
return try {
Gson().fromJson(jsonString, ImageData::class.java)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
(2)使用org.json解析
import org.json.JSONObject
fun parseJsonWithOrgJson(jsonString: String): ImageData? {
return try {
val jsonObject = JSONObject(jsonString)
ImageData(
imageUrl = jsonObject.getString("imageUrl"),
imageDesc = jsonObject.getString("imageDesc")
)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
根据图片存储方式显示图片
解析出imageUrl后,需根据其存储方式(Base64或URL)选择不同的显示方法。
显示Base64编码图片
Base64字符串需先解码为字节数组,再转换为Bitmap,最后显示在ImageView中。
(1)Base64转Bitmap
import android.graphics.Bitmap
import android.util.Base64
fun base64ToBitmap(base64String: String): Bitmap? {
return try {
val decodedBytes = Base64.decode(base64String, Base64.DEFAULT)
BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
注意:
- Base64字符串需包含前缀(如
data:image/jpeg;base64,),解码时需去除前缀(可通过split(",")[1]获取编码部分)。 - 大图片解码可能导致内存溢出(OOM),需提前对图片进行压缩(如
BitmapFactory.Options设置inSampleSize)。
(2)显示到ImageView
import android.widget.ImageView
fun displayBase64Image(imageView: ImageView, base64String: String) {
val bitmap = base64ToBitmap(base64String)
bitmap?.let {
imageView.setImageBitmap(it)
}
}
显示URL图片
URL图片需通过网络请求获取输入流,解码为Bitmap或使用图片加载库(如Glide、Picasso)简化操作。
(1)原生方式(不推荐,需手动处理线程和缓存)
import android.graphics.BitmapFactory
import android.os.Handler
import android.os.Looper
import java.net.HttpURLConnection
import java.net.URL
fun loadImageFromUrl(imageView: ImageView, urlString: String) {
// 子线程请求网络
Thread {
try {
val url = URL(urlString)
val connection = url.openConnection() as HttpURLConnection
connection.doInput = true
connection.connect()
val inputStream = connection.inputStream
val bitmap = BitmapFactory.decodeStream(inputStream)
// 主线程更新UI
Handler(Looper.getMainLooper()).post {
imageView.setImageBitmap(bitmap)
}
} catch (e: Exception) {
e.printStackTrace()
}
}.start()
}
缺点:需手动处理线程切换(网络请求不能在主线程)、图片缓存、加载失败等问题,代码复杂。
(2)使用图片加载库(推荐)
图片加载库(如Glide、Picasso)可简化网络请求、缓存、线程管理等操作,是安卓开发的首选,这里以Glide为例:
① 添加Glide依赖
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
② 加载图片到ImageView
import com.bumptech.glide.Glide
fun loadImageWithGlide(imageView: ImageView, urlString: String) {
Glide.with(imageView.context)
.load(urlString)
.placeholder(R.drawable.placeholder) // 加载中的占位图
.error(R.drawable.error) // 加载失败的占位图
.into(imageView)
}
优点:
- 自动处理线程(网络请求在子线程,UI更新在主线程)。
- 支持内存缓存和磁盘缓存,减少重复请求。
- 支持图片 transformations(如圆角、裁剪)、动画等高级功能。
完整代码示例(Kotlin)
以下是一个完整的Activity示例,展示从JSON字符串解析到图片显示的全流程:
布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<ImageView
android:id="@+id/ivImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/tvDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"/>
</LinearLayout>
MainActivity.kt
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Base64
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.google.gson.Gson
import org.json.JSONObject
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val ivImage = findViewById<ImageView>(R.id.ivImage)
val tvDesc = findViewById<TextView>(R.id.tvDesc)
// 示例JSON(Base64和URL两种形式)
val base64Json = """
{
"imageUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABA


还没有评论,来说两句吧...