在App与H5交互时,有一个调原生分享的需求,交互方面没有问题,因为分享需要多值,所以采用json进行传递,在app接收进行解析时遇到了这个解析异常 Value of type java.lang.String cannot be converted to JSONObject`
这可能是一个持续积累的过程,期待一起进步~
- JSONException:Value of type java.lang.String cannot be converted to JSONObject (String无法转换为JSONObject )
- 网上各位遇到的场景(解决)
- 我遇到该问题的场景(解决)
JSONException:Value of type java.lang.String cannot be converted to JSONObject (String无法转换为JSONObject )
这个异常其实很常见,但是导致这种异常的场景可能各有不同 ~
网上各位遇到的场景(解决)
由于utf-8
的 bom
头引起的问题,需去掉bom
头(有人也尝试过在本地进行处理 json
字符串,将 bom
头去掉)= 无效,无兴趣可跳过!!!
json
字符串格式也没问题,所以 可以肯定的是json字符内部有无法识别或者未知的字符
,有人做了如下处理(根据json数据不同,过滤条件也不同
)
String jsonStr = httpTools.doGet("URL接口地址",paramsBaseList);
String json = jsonStr.substring(jsonStr.indexOf("{"), jsonStr.lastIndexOf("}") + 1);
或 如下处理
public String JSONTokener(String in) {
// consume an optional byte order mark (BOM) if it exists
if (in != null && in.startsWith("\ufeff")) {
in = in.substring(1);
}
return in;
}
JSONObject obj = new JSONObject(JSONTokener(jsonStr));
个人结论:首先我还没去了解这个 bom
头是啥… 其次这里有一点是有用的 → json字符内部有无法识别或者未知的字符
最终 如下的处理方式帮到了我!!! 不过要注意是否处理下过期方法...
- Kotlin
val parser = JsonParser()
val retVal: String = parser.parse(it).asString
- Java
JsonParser parser = new JsonParser();
String retVal = parser.parse(param).getAsString();
Look Here :然后再使用JSONObject解析 retVal 即可
我遇到该问题的场景(解决)
首先说明一下我分享相关的伪代码
- app 提供给前端的方法
/**
* 分享
*/
val shareInfo = MutableLiveData<String>()
@Keep
@JavascriptInterface
fun appShare(param: String?, callbackId: String?) {
Timber.e("appShare---> callbackId -->${callbackId} --param-->${param}")
if (param.isNullOrEmpty()) return
shareInfo.postValue(param.string())
}
- js 调用 app 后的逻辑,主要看
jsonObject
解析部分
javascriptMethod.shareInfo.observe(viewLifecycleOwner) { params ->
val jsonObject = JSONObject(params)
val url: String = jsonObject.optString("url", "")
val title: String = jsonObject.optString("title", "")
val desc: String = jsonObject.optString("desc", "")
val icon: String = jsonObject.optString("icon", "")
activity?.let { ShareService.service?.share(it, url, title, desc, icon) }
}
- app 获取到的 json 串
这样的json串和我们平时接口返回的json串有所不同,但它也是正常的json串,所以需要处理内部的特殊字符,如 \ 、"" 等
"{\"url\":\"https://baidu.com\",\"title\":\"测试JS方法\",\"desc\":\"测试H5调用APP分享页功能~~~\",\"icon\":\"https://mobile.baidu.com.cn/actapp/files/upload/images/32c72f230622.png\"}"
图示
- 处理特殊json串,解决问题
/**
* 分享
*/
val shareInfo = MutableLiveData<Map<String, String?>>()
@Keep
@JavascriptInterface
fun appShare(param: String?, callbackId: String?) {
Timber.e("appShare---> callbackId -->${callbackId} --param-->${param}")
if (param.isNullOrEmpty()) return
try {
val startIndex = if (param.startsWith("\"")) 1 else 0
val endIndex = if (param.endsWith("\"")) param.length - 1 else param.length
val result = param.substring(startIndex, endIndex).replace("\\", "")
val jsonObject = JSONObject(result)
val url = jsonObject.optString("url")
val title = jsonObject.optString("title")
val desc = jsonObject.optString("desc")
val icon = jsonObject.optString("icon")
if (url.isNullOrEmpty()) return
shareInfo.postValue(mapOf("url" to url, "title" to title, "desc" to desc, "icon" to icon))
} catch (throwable: Throwable) {
Timber.e(throwable)
}
}