在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)
        }
    }



















