mWbRealize.loadUrl("http://652857502.scene.eqxiu.com/s/vknb0n8W?eqrcode=1&from=singlemessage&isappinstalled=0");
//支持javascript
web.getSettings().setJavaScriptEnabled(true);
// 設置可以支持縮放
web.getSettings().setSupportZoom(true);
// 設置出現縮放工具
web.getSettings().setBuiltInZoomControls(true);
//擴大比例的縮放
web.getSettings().setUseWideViewPort(true);//讓webview讀取網頁設置的viewport,pc版網頁
//自適應屏幕
web.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//適應屏幕,內容將自動縮放
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);//適應內容大小
web.getSettings().setLoadWithOverviewMode(true);
settings.setDomStorageEnabled(true);//打開DOM儲存API
settings.setBlockNetworkImage(true);//攔截圖片的加載
web.setInitialScale(25);//為25%,最小縮放等級
// 設置緩存模式:不使用緩存
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 設置啟動緩存
webView.getSettings().setDefaultTextEncodingName("utf-8");
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
postUrl
//需要訪問的網址
String url = "http://www.cqjg.gov.cn/netcar/FindThree.aspx";
//post訪問需要提交的參數
String postDate = "txtName=zzz&QueryTypeLst=1&CertificateTxt=dsds";
//由于webView.postUrl(url, postData)中 postData類型為byte[] ,
//通過EncodingUtils.getBytes(data, charset)方法進行轉換
webView.postUrl(url, EncodingUtils.getBytes(postDate, "UTF-8"));
EncodingUtils是 HttpCore里面的,要加依賴
compile 'org.apache.httpcomponents:httpcore:4.4.4'
網頁只加載出一部分,下面就不加載了?
● I/chromium(27693): [INFO:CONSOLE(8)] “Uncaught TypeError: Cannot call method ‘getItem’ of null”, source: url
網頁加載不完成并報出如上錯誤時,有可能是你的DOM儲存API沒有打開,在代碼中加上一行:
mWebView.getSettings().setDomStorageEnabled(true);
如果希望點擊鏈接由自己處理,而不是新開Android的系統browser中響應該鏈接。給WebView加一個事件監聽對象(WebViewClient)并重寫其中的一些方法:shouldOverrideUrlLoading:對網頁中超鏈接按鈕的響應。當按下某個連接時WebViewClient會調用這個方法,并傳遞參數:按下的url。
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url); //在當前的webview中跳轉到新的url
//如果不需要其他對點擊鏈接事件的處理返回true,否則返回false
return true;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) { //http和https協議開頭的執行正常的流程
return super.shouldInterceptRequest(view, url);
} else { //其他的URL則會開啟一個Acitity然后去調用原生APP
if (url.contains("mqqwpa")){
if (OthersUtil.isQQClientAvailable(mContext)){
Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(in);
return null;
}else {
// Toast.makeText(mContext, "您的手機未安裝手機QQ", Toast.LENGTH_SHORT).show();
// return super.shouldInterceptRequest(view, url);
return null;
}
}
Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(in);
return null;
}
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// showErrorPage();//顯示錯誤頁面
hideErrorPage();
};
public void onPageFinished(WebView view, String url) {//處理網頁加載成功時
// loading_over.setVisibility(View.GONE);
// hideErrorPage();
}
//監聽webview界面切換
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (url.contains("https://www.hzjr.com/Mobile/Index/customer?token=")){
mCloseService.setVisibility(View.GONE);
}
}
});
加載html標簽
mWebView.loadDataWithBaseURL(null, stringHtml, "text/html", "utf-8", null);
onReceivedError 不能捕捉失敗的回調???
onReceivedError 有兩個重載的方法,要重寫第二個
1、public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
2、 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
setWebChromeClient
setWebChromeClient主要處理解析,渲染網頁等瀏覽器做的事情
WebChromeClient是輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等
onCloseWindow(關閉WebView)
onCreateWindow()
onJsAlert (WebView上alert不能彈出來的,要WebChromeClient處理)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
setWebViewClient
WebViewClient是幫助WebView處理各種通知、請求事件的
onLoadResource
onPageStart
onPageFinish
onReceiveError
onReceivedHttpAuthRequest
點擊超鏈接啟動QQ
mWebView = (ProgressWebView) findViewById(R.id.baseweb_webview); mWebView.getSettings().setJavaScriptEnabled(true); String url ="http://wpa.qq.com/msgrd?v=3&uin=748895431&site=qq&menu=yes"; mWebView.loadUrl(url); mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url); return true;
}
@Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) {
//http和https協議開頭的執行正常的流程 return super.shouldInterceptRequest(view, url);
} else {
//其他的URL則會開啟一個Acitity然后去調用原生APP Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(in); return null;
}
}
});
滑動監聽
自定義webview重寫onScrollChanged方法,利用接口回調
public class HzjrWebView extends WebView {
private OnScrollChangedCallback mOnScrollChangedCallback;
public HzjrWebView(Context context) {
super(context);
}
public HzjrWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HzjrWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onScrollChanged(final int l, final int t, final int oldl,
final int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedCallback != null) {
mOnScrollChangedCallback.onScroll(l , oldl, t , oldt);
}
}
// public OnScrollChangedCallback getOnScrollChangedCallback() {
// return mOnScrollChangedCallback;
// }
public void setOnScrollChangedCallback(
final OnScrollChangedCallback onScrollChangedCallback) {
mOnScrollChangedCallback = onScrollChangedCallback;
}
/**
* Impliment in the activity/fragment/view that you want to listen to the webview
*/
public interface OnScrollChangedCallback {
void onScroll(int l,int oldl,int t, int oldt);
}
}
頁面關閉之后,視頻或者音頻還在播放的問題
方法1:
調用
webView.loadUrl("about:blank");
這個方法會 銷毀所有的video和audio 包括js的所有正在運行的function
方法2:
@Override
public void onPause() {
super.onPause();
myWebView.onPause();
myWebView.pauseTimers();
}
@Override
public void onResume() {
super.onResume();
myWebView.resumeTimers();
myWebView.onResume();
}
@Override
protected void onDestroy() {
myWebView.destroy();
myWebView = null;
super.onDestroy();
}
復寫生命周期的方法;最好的方法;(有時會掛 java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController$1@3ed4bcc7)
要在銷毀之前把根布局的所有子布局remove
mLlH5.removeAllViews();
回退時回到上一個頁面,而不是退出WebView
mWebView.goBack(); //后退
mWebView.goForward();//前進
mWebView.reload(); //刷新
public class MainActivity extends Activity {
private WebView webview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//2、在Activity中實例化WebView
setContentView(R.layout.activity_main);
webview = (WebView) findViewById(R.id.webview);
//第2步也可以替換為下面這兩句,就不要R.layout.activity_main布局文件了
//mwebview = new WebView(this); //實例化WebView對象
//setContentView(mwebview);
// 設置WebView屬性,能夠執行Javascript腳本
webview.getSettings().setJavaScriptEnabled(true);
//3、 加載需要顯示的網頁
webview.loadUrl("http://www.baidu.com/");
///4、設置響應超鏈接,在安卓5.0系統,不使用下面語句超鏈接也是正常的,但在MIUI中安卓4.4.4中需要使用下面這條語句,才能響應超鏈接
webview.setWebViewClient(new HelloWebViewClient());
}
@Override
// 設置回退
// 5、覆蓋Activity類的onKeyDown(int keyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
//按下返回鍵并且webview界面可以返回
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack(); // goBack()表示返回WebView的上一頁面
return true;
}
return super.onKeyDown(keyCode,event);
}
// Web視圖
private class HelloWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
設置cookie
ATTENTION:
要在webView設置setting之后,loadUrl之前調用此方法,否則無效
關于設置cookie失效的問題,在5.0以下可能會有失效的情況,sync是異步操作。
失效的原因是在removeSessionCookie之后立馬setCookie可能會是設置之后又被清除了,可以加個延遲。
在5.0以上官方回調了同步方法。
具體介紹參考博客:https://blog.csdn.net/b275518834/article/details/51004237
/**
* 給WebView同步Cookie
*
* @param context 上下文
* @param url 可以使用[domain][host]
*/
private void syncCookie(Context context, String url) {
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
// cookieManager.removeSessionCookie();// 移除舊的[可以省略]
cookieManager.setCookie(url,cookie);
CookieSyncManager.getInstance().sync();// To get instant sync instead of waiting for the timer to trigger, the host can call this.
}
還有權限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
H5與Android交互
首先最重要最容易忽略的網絡權限
public class MainActivity extends AppCompatActivity {
/***************************************************************
* H5和Android通信三種方式
* 1.android主動調用js:javascript:方法名(參數)
* 2.js主動調用Android
* 3.js callback式調用Android,來源(解耦H5只關心H5,客戶端只關心android)
* ***************************************************************
*/
private WebView mWebview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//設置webview
WebSettings settings = mWebview.getSettings();
settings.setJavaScriptEnabled(true);
//頁面加載完成調用js方法
//重新瀏覽器內核對象
initWebClient();
//js和Android兩種不同開發語言,不認識
//核心方法:設置js和Android通信橋梁接口(簡而言之,就是設置通信橋梁類)
JavascriptMethos jsMethos = new JavascriptMethos(this, mWebview);
//參數1:提供給js調用的方法的對象, 參數2:參數1的映射字符串(第一個參數的別名),因為字符串再所有開發一樣通用
mWebview.addJavascriptInterface(jsMethos, JavascriptMethos.JSINTERFACE);
//顯示
mWebview.loadUrl("http:/10.0.3.2:8080/html35/index.html");
}
private void initWebClient() {
mWebview.setWebChromeClient(new WebChromeClient());
mWebview.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
//頁面加載完成調用該方法
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//調用js 方法
//WebView.loadUrl("javascript:方法名(參數)")
JSONObject json = new JSONObject();
try {
json.put("name", "android");
json.put("msg", "你好,我是Android,加個蠔友");
mWebview.loadUrl("javascript:receiveMessage("+json.toString()+")");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
private void initView() {
mWebview = (WebView) findViewById(R.id.webview);
}
}
/**
* 統一管理所有js和Android通信
*
*/
public class JavascriptMethos {
public static String JSINTERFACE = "jsInterface";
private Context mContext;
private WebView mWebView;
public JavascriptMethos(Context mContext, WebView mWebView) {
this.mContext = mContext;
this.mWebView = mWebView;
}
/**
* 給js調用的彈出toast方法
* 為什么要添加注解:android4.2以上(包含),如果不加注解,
* js無法調用Android方法,因為4.2之前js和android通信有安全問題,如果不加上該注解,4.2以上js無法調用Android方法
*
* @param json
*/
@JavascriptInterface
public void showToast(String json) {
Toast.makeText(mContext, json, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void getHotelData(String json) throws JSONException {
//解析callbak方法名
JSONObject jsJson = new JSONObject(json);
final String callback = jsJson.optString("callback");
System.out.println("接收到js傳遞callback參數=" + json);
//模擬訪問網絡
//返回json
final JSONObject callbackJson = new JSONObject();
try {
callbackJson.put("name", "8天連鎖酒店");
callbackJson.put("hotel", "99");
callbackJson.put("phone", "075588888888");
//調用js方法
//mWebView.loadUrl("javascript:方法名(參數)");默認Android調用js獨立運行在一個進程WebViewCoreThread
mHandler.post(new Runnable() {
@Override
public void run() {
//mWebView.loadUrl("javascript:receiveHotelData(" + callbackJson.toString() + ")");
mWebView.loadUrl("javascript:"+callback+"(" + callbackJson.toString() + ")");
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
private Handler mHandler = new Handler();
}
demo
https://github.com/jiaweizeng/H5AndAndroid
control是java對象名稱,toastMessage是方法名稱,雙方約定俗成,寫死。
<body>
<button type="button" id="button" onclick="toastMessage('js調用了android方法')">js訪問android中方法</button>
<script>
function toastMessage(message) {
window.control.toastMessage(message)
}
</script>
</body>
public class MainActivity extends AppCompatActivity {
@SuppressLint({"JavascriptInterface", "AddJavascriptInterface", "SetJavaScriptEnabled"})
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = findViewById(R.id.wv);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webView.loadUrl("http://192.168.1.38/hzjrH5/jiaohu.html");
//js訪問android,定義接口
webView.addJavascriptInterface(this, "control");
}
@JavascriptInterface
public void toastMessage(String s){
Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
finish();
}
}