安卓应用通过Retrofit拉取JSON数据时如何去除HTML标签及特殊字符
解决方案
以下是3种可直接落地的处理方案,你可以根据自己的项目需求选择:
方案1:自定义Gson反序列化器(解析阶段自动处理)
该方案在JSON解析阶段就完成HTML清理,后续无需额外处理,适合全局统一处理该场景:
- 先实现通用的HTML清理工具方法,推荐直接用Android系统自带的
Html类处理,兼容性更好,无需手写正则:
import android.text.Html fun cleanHtml(rawStr: String): String { // 兼容Android 7.0及以上版本 return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { Html.fromHtml(rawStr, Html.FROM_HTML_MODE_LEGACY).toString().trim() } else { @Suppress("DEPRECATION") Html.fromHtml(rawStr).toString().trim() } }
- 自定义
TypeAdapter处理Patent类的反序列化逻辑,对results字段的所有字符串做清理:
class PatentTypeAdapter : TypeAdapter<Patent>() { override fun read(reader: JsonReader): Patent { reader.beginObject() var count = 0 var page = 0 var perpage = 0 var total = 0 var results = emptyList<List<String>>() while (reader.hasNext()) { when (reader.nextName()) { "count" -> count = reader.nextInt() "page" -> page = reader.nextInt() "perpage" -> perpage = reader.nextInt() "total" -> total = reader.nextInt() "results" -> { val outerList = mutableListOf<List<String>>() reader.beginArray() while (reader.hasNext()) { val innerList = mutableListOf<String>() reader.beginArray() while (reader.hasNext()) { val rawStr = reader.nextString() innerList.add(cleanHtml(rawStr)) } reader.endArray() outerList.add(innerList) } reader.endArray() results = outerList } else -> reader.skipValue() } } reader.endObject() return Patent(count, page, perpage, results, total) } override fun write(out: JsonWriter, value: Patent) { // 无需序列化逻辑可留空 } }
- 将自定义适配器注册到Gson,再传给Retrofit:
val gson = GsonBuilder() .registerTypeAdapter(Patent::class.java, PatentTypeAdapter()) .create() val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .build()
方案2:请求响应后统一清理(改动量最小)
该方案不需要修改现有解析逻辑,仅在拿到响应后、传给Adapter前做一次全量清理,适合快速迭代:
override fun onResponse(call: Call<Patent>, response: Response<Patent>) { val rawPatent = response.body() if (rawPatent != null) { // 清理results字段所有HTML标签 val cleanedResults = rawPatent.results.map { innerList -> innerList.map { rawStr -> cleanHtml(rawStr) } } // 生成清理后的Patent对象 val cleanedPatent = rawPatent.copy(results = cleanedResults) adapter = PatentAdapter(this@MainFragment, cleanedPatent, this) recyclerViewItems!!.adapter = adapter } }
方案3:Adapter绑定阶段实时清理(灵活适配部分字段场景)
如果只需要展示部分字段、不需要全量清理,可在ViewHolder绑定时单独处理对应字符串:
override fun onBindViewHolder(holder: PatentHolder, position: Int) { val rawItem = patent.results[position][TARGET_FIELD_INDEX] val cleanedText = cleanHtml(rawItem) holder.targetTextView.text = cleanedText }
内容的提问来源于stack exchange,提问作者Kushal Sharma
相关产品推荐
相关产品推荐

