H5示例代碼
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" charset="utf-8"/>
<script type="text/javascript">
//加購
function addcart(){
let goodsModel = {
"inventory" : 100,
"name": "12112112121",
}
//path是js交互的協(xié)議路徑
var message = {
'path' : 'add_cart_function_native',
'params' : {"selectSku":6452,"goodsModel":goodsModel},
};
postMessage(message);
}
//發(fā)起網(wǎng)絡請求
function requestData(){
}
//埋點數(shù)據(jù)
function tranceLogAction(){
var message = {
path : "trace_log_function_native",
params : {
dpType :"home_page",
eventType :"advertise",
type :"click",
tranceLogParams : {
page :1,
position :2
}
}
};
postMessage(message);
alert("上傳埋點成功");
}
//打開新頁面
function openPage(){
var message = {
'path' : "open_control_native",
'params' : {
"deepLink":"xxx",
"deepLinkParam": {}
},
};
postMessage(message);
}
//購物車商品數(shù)量
function cartNumber(){
window.cacheResult = function(result){
let p = JSON.parse(result);
if (p.code == 200){
alert("購物車數(shù)量" + JSON.stringify(p.params["carGoodsNum"]));
}
}
let list = ["carGoodsNum"]
var message = {
'path' : "get_cache_function_native",
'params' : {
"callback":"cacheResult(params)",
"cacheNameList": list
},
};
postMessage(message);
}
function getToken(){
window.observeToken = function(result){
let p = JSON.parse(result);
if (p.code == 200){
alert(p.params.access_token);
return "p.params.access_token"
}
}
var message = {
'path' : "user_token_function_native",
'params' : {"callback":"observeToken(params)"},
};
postMessage(message);
}
function postMessage(message){
var system = isIosOrAndroid()
if (system == 1) {
// 安卓
window.local_android.setMessage(JSON.stringify(message));
}else if (system == 2) {
// iOS
window.webkit.messageHandlers.local_ios.postMessage(JSON.stringify(message));
}
}
//判斷安卓或者iOS系統(tǒng)
function isIosOrAndroid() {
var u = navigator.userAgent
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android終端
if (isAndroid) {
return 1
}
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
if (isiOS) {
return 2
}
return 0
}
</script>
<title></title>
</head>
<body>
<p align="center"> <input style="font-size: 18px;" type="button" value="快速加購" onClick="addcart()"></p>
<p align="center"> <input style="font-size: 18px;" type="button" value="獲取登錄態(tài)" onClick="getToken()"></p>
<p align="center"> <input style="font-size: 18px;" type="button" value="獲取購物車數(shù)量" onClick="cartNumber()"></p>
<p align="center"> <input style="font-size: 18px;" type="button" value="埋點" onClick="tranceLogAction()"></p>
<p align="center"> <input style="font-size: 18px;" type="button" value="網(wǎng)絡請求" onClick="requestData()"></p>
<p align="center"> <input style="font-size: 18px;" type="button" value="打開新頁面" onClick="openPage()"></p>
</body>
</html>
android代碼(基類)
abstract class BaseWebViewActivity : BaseAppActivity() {
lateinit var activityWebView : WebView
lateinit var commonbase_activity_appbar_left:ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.commonbase_activity_web_view)
activityWebView = findViewById(R.id.activityBaseWebView)
commonbase_activity_appbar_left=activityWebViewTitleInclude.findViewById(R.id.commonbase_activity_appbar_left)
setWebWs()
}
@SuppressLint("JavascriptInterface")
private fun setWebWs() {
val ws: WebSettings? = activityWebView?.settings
//這寫注釋先不要刪掉
//ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);//自適應屏幕 //導致4.4以下?lián)u錢樹只顯示背景和標題
// ws.setLoadWithOverviewMode(true);//自適應屏幕,使用后字體變小,
// ws.setAllowFileAccess(false);// 設置允許訪問文件數(shù)據(jù)
// ws.setJavaScriptCanOpenWindowsAutomatically(false);//自動打開窗口
// ws.setAppCacheEnabled(false);
// ws.setSupportZoom(true);// 設置支持縮放
// ws.setBuiltInZoomControls(true);// 設置支持縮放
// ws.setDisplayZoomControls(false);//顯示縮放按
ws?.setAllowFileAccess(true);// -> 是否允許訪問文件
ws?.setDomStorageEnabled(false); //-> 是否節(jié)點緩存
ws?.setDatabaseEnabled(false);// -> 是否數(shù)據(jù)緩存
ws?.setAppCacheEnabled(false);// -> 是否應用緩存
ws?.loadWithOverviewMode = true
ws?.builtInZoomControls = true
ws?.displayZoomControls = false
//? ws.setAllowFileAccessFromFileURLs(false);
//? ws.setAllowFileAccessFromFileURLs(false);
ws?.useWideViewPort = true //圖片被縮放后顯示不全的問題
ws?.javaScriptEnabled = true
ws?.savePassword = false
ws?.blockNetworkImage = false
ws?.loadsImagesAutomatically = true
var oldUA = ws?.userAgentString
//UA都是跟h5約定好提供什么參數(shù)
val addAgent =
" AppName/(${ChicvUserAgentDataManager.getAppName()}) LanguageId/($language_id) Language/($language_code) Currency/($currency_code) CurrencyId/($country_id) WappBrowser/1.2.6 ChannelId/(1) PlatformId/(1) LastLoginTime/ Version/(${
getVersionName(MyApplication.getInstance())
}) SystemVersion/(${ChicvUserAgentDataManager.getOsVersion()})"
ws?.userAgentString = oldUA + addAgent
val timecurrentTimeMillis = System.currentTimeMillis()
val sign = MD5Util.getMD5("SECRET")
val language_id = language_id
val language_code = language_code
val currency_code = currency_code
val country_id = currencyCountry_id.toString()
activityWebView?.addJavascriptInterface(this, "local_android");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0以上默認不允許http和https混合模式, 需手動開啟
ws?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}
// activityWebView.webChromeClient = BaseWebChromeClient()
// activityWebView.webViewClient = BaseWebViewClient(activityWebViewProgressbar)
//設置cookie
syncCookie()
val token = if (GlobalFunc.hasLogin()) GlobalFunc.getAccountToken() else ""
var cookies = if (token.isNullOrEmpty()) "currency=$currency_code;language=$language_id;language-code=$language_code" else "access_token=$token;currency=$currency_code;language=$language_id;language-code=$language_code"
//設置header,給后端使用
val headerMap = mapOf(
"x-origin-client" to "Android",
)
if (getLoadUrl() != null) activityWebView?.loadUrl(getLoadUrl(), headerMap)
}
protected abstract fun getLoadUrl(): String
open fun syncCookie(): Boolean {
var url = getLoadUrl()
val cookieManager = CookieManager.getInstance()
cookieManager.setAcceptCookie(true)
cookieManager.removeSessionCookies(null)
cookieManager.removeAllCookies(null)
val token = if (GlobalFunc.hasLogin()) GlobalFunc.getAccountToken() else ""
val currency = currency_code
val language = language_id
var cookies = if (token.isNullOrEmpty()) "currency=$currency;language=$language;language-code=$language_code" else "access_token=$token;currency=$currency;language=$language;language-code=$language_code"
url.logW("currency_code2")
cookies.logW("currency_code2")
cookieManager.setCookie(url, cookies)
val newCookie = cookieManager.getCookie(url)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
val cookieSyncManager = CookieSyncManager.createInstance(mContext)
cookieSyncManager.sync()
} else {
cookieManager.flush()
}
return if (!newCookie.isNullOrEmpty()) false else true
}
}
子類
class SpecialWebViewActivity : BaseWebViewActivity() {
override val pageTag: String
get() = TraceDpType.WebView.value
var isShowCartBtn = 0//0 hidden 1 show
var isShowTopBtn = 0//0 hidden 1 show
var goodsDetailsReturRl : RelativeLayout? = null
var merchandiseCustomerRl : RelativeLayout? = null
var commonbase_num_bg : RelativeLayout? = null
var commonbase_num : TextView? = null
override fun getLoadUrl(): String {
var dataMap = intent.getSerializableExtra("param") as Map<String, Objects>?
if (!dataMap.isNullOrEmpty() && dataMap!!.containsKey(GlobalVariable.WEB_URL)) {
return dataMap!!.get(GlobalVariable.WEB_URL) as String
} else return ""
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setWebViewClient()
setUI()
EventBusUtil.register(this)
}
override fun onDestroy() {
super.onDestroy()
EventBusUtil.unregister(this)
}
fun setUI() {
goodsDetailsReturRl = findViewById(R.id.goodsDetailsReturWebViewRl)
merchandiseCustomerRl = findViewById(R.id.merchandiseCustomerRl)
commonbase_num_bg = findViewById(R.id.commonbase_num_bg)
commonbase_num = findViewById(R.id.commonbase_num)
merchandiseCustomerRl?.setOnClickListener {
if (LocalAppSettings.localProviderSettingsData.value!!.cart_need_login == "0") {
DeepPathLinkUtil.deepPathHome(
this,
DeepPath.cart,
"cart",
"",
null,
""
)
} else {
GlobalFunc.isLoginAndGo(mContext) {
if (it) {
DeepPathLinkUtil.deepPathHome(
this,
DeepPath.cart,
"cart",
"",
null,
""
)
}
}
}
}
goodsDetailsReturRl?.setOnClickListener {
scrollToTop(true)
}
//判斷sku有沒有更新 以及存儲sku信息
val cartNum = UserSPUtils.getInstance().getString(GlobalVariable.CARTNUM)
cartNum.logW("cartNum")
if (!TextUtils.isEmpty(cartNum) && "0" != cartNum) {
commonbase_num_bg?.visibility = View.VISIBLE
commonbase_num?.text = Tools.change99(cartNum)
} else {
commonbase_num_bg?.visibility = View.INVISIBLE
}
}
fun setWebViewClient() {
val webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
}
override fun onReceivedTitle(view: WebView, title: String) {
super.onReceivedTitle(view, title)
//這里面可以賦值給到title
title.logW("qqqqqqqq")
setWebViewTitle(title,view)
}
override fun onJsAlert(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
ToastUtils.showShort("123")
return super.onJsAlert(view, url, message, result)
}
override fun onJsPrompt(
view: WebView?,
url: String?,
message: String?,
defaultValue: String?,
result: JsPromptResult?
): Boolean {
ToastUtils.showShort("1234")
return super.onJsPrompt(view, url, message, defaultValue, result)
}
}
val webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
}
override fun onPageFinished(view: WebView?, url: String?) {
val cookieManager = CookieManager.getInstance()
cookieManager.getCookie(url).logW("currency_code3")
super.onPageFinished(view, url)
}
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) {
super.onReceivedSslError(view, handler, error)
handler?.proceed()
}
}
activityWebView?.webChromeClient = webChromeClient
activityWebView?.webViewClient = webViewClient
}
@JavascriptInterface
fun setMessage(msg: String) {
/*
*add_cart_function_native > GlobalVariable.SpecialPath.addCart.value 快速加購
*user_token_function_native 獲取登錄態(tài)
* webView.loadUrl("observeToken('')"); */
LogUtils.e("qqqqqqqq", msg)
val specialModel = JsonUtils.StringToObject(msg, SpecialModelDTO::class.java)
specialModel.toString().logW()
if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.addCart.value) {//加入購物車
specialModel.params.let {
it.handle.let { it1 ->
goodsListDetails(it1, it.selectSku)
}
}
} else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.token.value) {//獲取token
val tokenStr = if (GlobalFunc.hasLogin()) GlobalFunc.getAccountToken() else "123"
var tokenMap: Map<String, String>? = null
tokenStr?.let { tokenMap = mapOf<String, String>("access_token" to it) }
var json = JSONObject()
json.put("code", 200)
json.put("message", "成功")
val param = tokenMap?.let {
json.put("params", tokenMap)
// mapOf<String,Any>("code" to 200, "message" to "成功", "params" to it.toString())
}
// activityWebView?.loadUrl("javascript:observeToken('${param.toString()}')");
var result = "服務器返回的數(shù)據(jù)"
//調(diào)用js方法必須在主線程
callBackFunction(specialModel.params.callback, json.toString())
} else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.cartGoodsNum.value) {//購物車數(shù)量
val cartNum = UserSPUtils.getInstance().getString(GlobalVariable.CARTNUM)
var tokenMap: Map<String, String>? = null
var json = JSONObject()
json.put("code", 200)
json.put("message", "成功")
json.put("params", mapOf("carGoodsNum" to cartNum.toInt()).toString())
callBackFunction(specialModel.params.callback, json.toString())
} else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.traceLog.value) {//埋點
var tranceLogParams: TranceLogParams? = specialModel?.params?.tranceLogParams
} else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.openView.value) {//打開新界面
specialModel.params.deepLink?.apply {
var retMap = UriParams.getUriParams(this)
DeepPathLinkUtil.deepPathHome(mContext, this, null, null, retMap, null)
}
}
else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.floatCart.value) {//展示購物車浮窗/置頂按鈕
isShowTopBtn =
if (specialModel.params.alertType == 2 && specialModel.params.isShow == 1) 1 else 0
isShowCartBtn =
if (specialModel.params.alertType == 1 && specialModel.params.isShow == 1) 1 else 0
merchandiseCustomerRl?.visibility = if (isShowCartBtn == 1) View.VISIBLE else View.INVISIBLE
goodsDetailsReturRl?.visibility = if (isShowTopBtn == 1) View.VISIBLE else View.GONE
commonbase_num_bg?.visibility = if (isShowCartBtn == 1) View.VISIBLE else View.INVISIBLE
}else if (!specialModel.path.isNullOrEmpty() && specialModel.path == GlobalVariable.SpecialPath.jsFunction.value) {//強制跑腳本(轉(zhuǎn)ar模式)
MyCoroutineScope().runWithMain {
activityWebView.loadUrl("javascript:$('html').addClass('rtl-wrapper')")
}
callBackFunction(specialModel.params.jsString, "")
}
}
private fun callBackFunction(methodName: String, message: String?) {
MyCoroutineScope().runWithMain {
var method = methodName.replace("params", "'$message'")
activityWebView.loadUrl("javascript:$method")
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onCartNumEvent(event: CartNumEvent?) {
if (event == null) return
commonbase_num_bg?.visibility = if (event.cartNum == 0) View.INVISIBLE else View.VISIBLE
commonbase_num?.text = Tools.change99(event.cartNum)// event.cartNum.toString() + ""
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && activityWebView.canGoBack()) {
activityWebView.goBack()// 返回前一個頁面
return true
}
return super.onKeyDown(keyCode, event)
}
}