Android 可视化预览及编辑Json
Android 可视化编辑json JsonPreviewer
项目中涉及到广告开发, 广告的配置是从API动态下发, 广告配置中,有很多业务相关参数,例如关闭或开启、展示间隔、展示时间、重试次数、每日最大显示次数等。
开发时单个广告可能需要多次修改配置来测试,为了方便测试,广告配置的json文件,有两种途径修改并生效
- 每次抓包修改配置
- 本地导入配置,从磁盘读取
但两种方式都有一定弊端
- 首先测试时依赖电脑修改配置
- 无法直观预览广告配置
考虑到开发时经常使用的Json格式化工具,既可以直观的预览Json, 还可以在线编辑
那么就考虑将Json格式化工具移植到项目测试模块中
web网页可以处理Json格式化,同理在Android webView 中同样可行, 只需要引入处理格式化的JS代码即可。
查找资料,发现一个很实用的文章可视化编辑json数据——json editor
开始处理
首先准备好WebView的壳子
//初始化
@SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
binding.webView.settings.apply {
javaScriptEnabled = true
javaScriptCanOpenWindowsAutomatically = true
setSupportZoom(true)
useWideViewPort = true
builtInZoomControls = true
}
binding.webView.addJavascriptInterface(JsInterface(this@MainActivity), "json_parse")
}
//webView 与 Android 交互
inner class JsInterface(context: Context) {
private val mContext: Context
init {
mContext = context
}
@JavascriptInterface
fun configContentChanged() {
runOnUiThread {
contentChanged = true
}
}
@JavascriptInterface
fun toastJson(msg: String?) {
runOnUiThread { Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show() }
}
@JavascriptInterface
fun saveConfig(jsonString: String?) {
runOnUiThread {
contentChanged = false
Toast.makeText(mContext, "verification succeed", Toast.LENGTH_SHORT).show()
}
}
@JavascriptInterface
fun parseJsonException(e: String?) {
runOnUiThread {
e?.takeIf { it.isNotBlank() }?.let { alert(it) }
}
}
}
加载json并在WebView中展示
viewModel.jsonData.observe(this) { str ->
if (str?.isNotBlank() == true) {
binding.webView.loadUrl("javascript:showJson($str)")
}
}
WebView 加载预览页面
binding.webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
viewModel.loadAdConfig(this@MainActivity)
}
}
binding.webView.loadUrl("file:///android_asset/preview_json.html")
Json 预览页, preview_json.html实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="jquery.json-viewer.css"
rel="stylesheet" type="text/css">
</head>
<style type="text/css">
#json-display {
margin: 2em 0;
padding: 8px 15px;
min-height: 300px;
background: #ffffff;
color: #ff0000;
font-size: 16px;
width: 100%;
border-color: #00000000;
border:none;
line-height: 1.8;
}
#json-btn {
display: flex;
align-items: center;
font-size: 18px;
width:100%;
padding: 10;
}
#format_btn {
width: 50%;
height: 36px;
}
#save_btn {
width: 50%;
height: 36px;
margin-left: 4em;
}
</style>
<body>
<div style="padding: 2px 2px 2px 2px;">
<div id="json-btn" class="json-btn">
<button type="button" id="format_btn" onclick="format_btn();">Format</button>
<button type="button" id="save_btn" onclick="save_btn();">Verification</button>
</div>
<div>
<pre id="json-display" contenteditable="true"></pre>
</div>
<br>
</div>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.json-viewer.js"></script>
<script>
document.getElementById("json-display").addEventListener("input", function(){
console.log("json-display input");
json_parse.configContentChanged();
}, false);
function showJson(jsonObj){
$("#json-display").jsonViewer(jsonObj,{withQuotes: true});//format json and display
}
function format_btn() {
var my_json_val = $("#json-display").clone(false);
my_json_val.find("a.json-placeholder").remove();
var jsonval = my_json_val.text();
var jsonObj = JSON.parse(jsonval); //parse string to json
$("#json-display").jsonViewer(jsonObj,{withQuotes: true});//format json and display
}
function save_btn() {
var my_json_val = $("#json-display").clone(false);
my_json_val.find("a.json-placeholder").remove();
var jsonval = my_json_val.text();
var saveFailed = false;
try {
var jsonObj = JSON.parse(jsonval); //parse
} catch (e) {
console.error(e.message);
saveFailed = true;
json_parse.parseJsonException(e.message); // throw exception
}
if(!saveFailed) {
json_parse.saveConfig(jsonval);
}
}
</script>
</body>
</html>
这其中有两个问题需注意
- 如果value的值是url, 格式化后缺少引号
从json-viewer.js源码可以发现,源码中会判断value是否是url,如果是则直接输出
处理方式:在json 左右添加上双引号
if (options.withLinks && isUrl(json)) {
html += '<a href="' + json + '" class="json-string" target="_blank">' + '"' +json + '"' + '</a>';
} else {
// Escape double quotes in the rendered non-URL string.
json = json.replace(/"/g, '\\"');
html += '<span class="json-string">"' + json + '"</span>';
}
- 如果折叠后json-viewer会增加
<a>
标签,即使使用text()方法获取到纯文本数据,这里面也包含了“n items”的字符串,那么该如何去除掉这些字符串呢?
var my_json_val = $("#json-display").clone(false);
my_json_val.find("a.json-placeholder").remove();
总结
使用时只需将json文件读取,传入preview_json.html的showJson方法
编辑结束后, 点击Save 即可保存
示例代码 Android 可视化编辑json JsonPreviewer
(可视化编辑json数据——json editor)[blog.51cto.com/u_56500