WebView你真的熟悉吗?看了才晓得。Android中WebView的开发。

每当Android手机中置了相同款高性能webkit内核浏览器,在SDK中查封装为一个誉为WebView组件。下面总结一下使webview遇到的那些从、那些坑。

每当Android手机中置放了一如既往慢慢悠悠大性能webkit内核浏览器,在SDK中查封装为一个称作WebView组件。下面总结一下施用webview

目录

平、webview的基本以办法

如出一辙、webview的为主采用方法
1.
补充加权限:AndroidManifest.xml中装置权限”android.permission.INTERNET”,否则会出Web
page not available错误。

2. 于苟Activity中生成一个WebView组件:WebView webView = new
WebView(this);或者好以activity的layout文件里上加webview控件

3. 装置WebView基本信息:

仲、webview与js的互动(附上示例项目整体源码)

1.js与android的交互
2.android调用js无参无返回值函数
3.android调用js有参无返回值函数
4.android调用js有参有返回值函数(4.4事先)
5.android调用js有参有返回值函数(4.4事后)
6.赢得网页图片展开推广

 mWebView = (WebView) findViewById(R.id.wb);
 mWebView.getSettings().setJavaScriptEnabled(true);//支持javascript
 mWebView.requestFocus();//触摸焦点起作用    
 mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);//取消滚动条
 mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置允许js弹出alert对话框

 mWebView.addJavascriptInterface(new JsInteration(), "control");//js访问android,定义接口
   //设置了Alert才会弹出,重新onJsAlert()方法return true可以自定义处理信息
 mWebView.setWebChromeClient(new WebChromeClient() {    
@Override    
  public boolean onJsAlert(WebView view, String url, String message, JsResult result)
  {        
  //return super.onJsAlert(view, url, message, result);        
  Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();        
  return true;  
  }
  });

老三、webview遇到的那些坑和缓解智**

4.
安WevView要显示的网页:互联网用:webView.loadUrl(“http://www.google.com”);
本地文件用:webView.loadUrl(“file:///android_asset/XX.html”);
本地文件存放于:assets文件被

5.
若欲点击链接由自己处理,而休是初开Android的系统browser中响应该链接。给WebView添加一个事变监听目标(WebViewClient)并重复写其中的部分计:
shouldOverrideUrlLoading:对网页遭到跨链接按钮的响应。当随下某连接时WebViewClient会调用这个法子,并传递参数

一律、webview的中坚使用办法

1.
续加权限:AndroidManifest.xml中安权限”android.permission.INTERNET”,否则会出Web
page not available错误。

2. 每当如Activity中生成一个WebView组件:WebView webView = new
WebView(this);或者好当activity的layout文件里补充加webview控件

3. 装WebView基本信息:

mWebView = (WebView) findViewById(R.id.wb);
mWebView.getSettings().setJavaScriptEnabled(true);//支持javascript
mWebView.requestFocus();//触摸焦点起作用mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);//取消滚动条
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//设置允许js弹出alert对话框
//load本地
mWebView.loadUrl("file:///android_asset/hellotest.html");
//load在线
//mWebView.loadUrl("http://www.google.com");
//js访问android,定义接口
mWebView.addJavascriptInterface(new JsInteration(), "control");
//设置了Alert才会弹出,重新onJsAlert()方法return true可以自定义处理信息
mWebView.setWebChromeClient(new WebChromeClient() {    
@Override    
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {        
//return super.onJsAlert(view, url, message, result);        
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();        
return true;  
  }});

4.
装置WevView要显得的网页:互联网用:webView.loadUrl(“http://www.google.com”);
本地文件用:webView.loadUrl(“file:///android_asset/XX.html”);
本地文件存放于:assets文件中

5.
要希望点击链接由友好处理,而无是新开Android的网browser中响应该链接。给WebView添加一个轩然大波监听目标(WebViewClient)并再写其中的组成部分方:
shouldOverrideUrlLoading:对网页中过链接按钮的响应。当以下有连接时WebViewClient会调用这个方式,并传递参数

public boolean shouldOverrideUrlLoading(WebView view,String url){
       view.loadUrl(url);
       return true;          
        }

6. 处理https请求
webView默认是无处理https请求的,页面显示空白,需要展开如下设置:

webView.setWebViewClient(new WebViewClient() { 
@Override public void onReceivedSslError(WebView view, 
SslErrorHandler handler, SslError error) { 
handler.proceed(); 
// handler.cancel(); 
// handler.handleMessage(null); } });
onReceivedSslError为webView处理ssl证书设置

个中handler.proceed();表示等证书响应
handler.cancel();表示挂于连年,为默认方式
handler.handleMessage(null);可举行其他处理
另外还出任何组成部分但还写的点子
1,接收至Http请求的风波onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm)
2,载入页面就的事件public void onPageFinished(WebView view, String
url){ }
同样道理,我们明白一个页面载入完成,于是我们可以关闭loading条,切换程序动作。
3,载入页面开始的波public void onPageStarted(WebView view, String url,
Bitmap favicon) { }
此事件便是发端载入页面调用的,通常咱们可在及时设定一个loading的页面,告诉用户程序在待网络响应。
通过就几乎独事件,我们得生自在的主宰次操作,一边用着浏览器显示内容,一边监控正用户操作实现我们用的各种显示方式,同时可防用户发误操作。

7.
若就此webview点链接看了成百上千页后,如果不开另外处理,点击系统“Back”键,整个浏览器会调用finish()而终结自己,如果指望浏览的网页回退而休是退出浏览器,需要在目前Activity中拍卖并花掉该Back事件。
覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。

 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {  
  if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {    
    webView.goBack();// 返回前一个页面   
     return true;   
 }    
return super.onKeyDown(keyCode, event);
}
 public boolean shouldOverrideUrlLoading(WebView view,String url){ view.loadUrl(url); return true; }

老二、webview与js的互动(相互调用参数、传值)

前者网页全部代码,文章最后出示范项目完全源码

<!DOCTYPE html><html><head>    <meta charset="utf-8">    
<title>jaydenxiao遇上了webview</title>    
<script>
function sayHello() {
alert("我是无参无返回toast") 
}
function alertMessage(message) { 
alert(message)  
}
function toastMessage(message) {
window.control.toastMessage(message)
}
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
function sumToJava2(number1, number2) {
return number1 + number2;
}    
</script>
</head><body>
<button type="button" id="button" onclick="toastMessage('js调用了android方法')">js访问android中方法</button>
</body>
</html>

6.
处理https请求
webView默认是免处理https请求的,页面显示空白,需要展开如下设置:

调用示例:

  webView.setWebViewClient(new WebViewClient() { 
    @Override
      public void onReceivedSslError(WebView view, 
     SslErrorHandler handler, SslError error) { 
       handler.proceed(); 
     // handler.cancel(); 
   // handler.handleMessage(null); }
   });
js调用Java

调用格式为window.jsInterfaceName.methodName(parameterValues)
此例中我们用的是control作为注入接口名称。

function toastMessage(message) { 
window.control.toastMessage(message) 
}
 function sumToJava(number1, number2){ 
window.control.onSumResult(number1 + number2)
 }

onReceivedSslError为webView处理ssl证书设置

Java调用JS

webView调用js的中心格式为webView.loadUrl(“javascript:methodName(parameterValues)”)
1. android调用js无参无返回值函数

final String call = "javascript:sayHello()";
mWebView.post(new Runnable() {    
@Override    
public void run() { 
       mWebView.loadUrl(call);    
}});

2. android调用js有参无返回值函数

final String call = "javascript:alertMessage(\"" + "我是android传过来的内容,hey man" + "\")";
mWebView.post(new Runnable() {    
@Override    
public void run() { 
       mWebView.loadUrl(call);    
}});

3. android调用js有参有返回值函数(4.4事先)
Android在4.4之前并无提供直接调用js函数并取值的不二法门,所以在此之前,常用的笔触是
java调用js方法,js方法执行了,再次调用java代码用价值返回。
**(1).android调用js代码 **

final String call = "javascript:sumToJava(1,2)";
mWebView.post(
new Runnable() {  
  @Override   
 public void run() {       
 mWebView.loadUrl(call);   
 }});

(2).js函数处理,并将结果通过调用android方法返回
网页端:

function sumToJava(number1, number2){ 
window.control.onSumResult(number1 + number2) 
} 

(3).android在回调方法被收获js函数返回值

@JavascriptInterfacepublic void onSumResult(int result) {   
Toast.makeText(getApplicationContext(), "我是android调用js方法(4.4前),入参是1和2,js返回结果是" + result, Toast.LENGTH_LONG).show();
}

4. android调用js有参有返回值函数(4.4以上):
Android 4.4之上使用evaluateJavascript即可。这里展示一个粗略的并行示例
具有返回值的js方法

js代码如下:

function sumToJava2(number1, number2) {
return number1 + number2;
}

android代码如下:

@TargetApi(Build.VERSION_CODES.KITKAT)
public void Android2JsHaveParmHaveResult2(View view) { 
 mWebView.evaluateJavascript("sumToJava2(3,4)", new ValueCallback<String>() {
@Override 
public void onReceiveValue(String Str) {   
Toast.makeText(getApplicationContext(), "我是android调用js方法(4.4后),入参是3和4,js返回结果是" + Str, Toast.LENGTH_LONG).show(); 
  }    
});}

里handler.proceed();表示等证书响应handler.cancel();表示挂于连年,为默认方式handler.handleMessage(null);
然做任何处理另外还起另部分而又写的章程
1,接收及Http请求的风波onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm)
2,载入页面就的轩然大波public void onPageFinished(WebView view, String
url){
}同样道理,我们解一个页面载入完成,于是我们可关闭loading条,切换程序动作。
3,载入页面开始之风波public void onPageStarted(WebView view, String url,
Bitmap favicon) {
}这个波就是发端载入页面调用的,通常我们可当当下设定一个loading的页面,告诉用户程序在待网络响应。
通过就几乎独事件,我们可非常自在的支配程序操作,一边用着浏览器显示内容,一边监控正用户操作实现我们用之各种显示方式,同时可防用户发误操作。

4.
假如就此webview点链接看了过多页后,如果非开另外处理,点击系统“Back”键,整个浏览器会调用finish()而收自己,如果想浏览的网页回退而无是离浏览器,需要以当下Activity中处理并花掉该Back事件。
覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。

老三、webview遇到的那些坑和解决智

1. WebView的内存泄露。
斯题材,很不便清晰描述,你于谷歌里搜 webview lead memory 能搜到很多结出
甚至还有为谷歌提交的issue 哈哈,我啊无从给出一个鲜明的答案 在啊时
什么版本那些手机及得会面世内存泄露,
而根据部分monkey结果来拘禁,有时,webview内存泄露的图景还是杀要紧的,尤其是当你加载的页面比较庞大之早晚。解决方案参考下微信以及qq的做法,试了一晃凡是现阶段效能最好之,
就是是 当你若为此webview的下,记得最好 另外单独开一个过程 去采用webview
并且当这 进程结束时,请手动调用System.exit(0)。
立是目前对于webview 内存泄露 最好之化解方案。使用此方法
所有为webview引发的 资源无法自由等题材 全部得解决。

2. getSettings().setBuiltInZoomControls(true) 引发的crush。
夫法调用以后 如果你动手屏幕 弹出非常提示框还没有收敛的时刻
你如果activity结束了 就见面报错了。3.0坐上 4.4以下居多部手机会冒出这种状态
于是为了回避他,我们日常是于activity的onDestroy方法里手动的将webiew设置成
setVisibility(View.GONE)

3.onPageFinished 函数到底发生因此无?
多数开发者都是参照的http://stackoverflow.com/questions/3149216/how-to-listen-for-a-webview-finishing-loading-a-url-in-android
这个上面的高票答案。
唯独实际上根据我自己观察,这个函数并没什么卵用,有的时候是提前结束,有的时候便慢无法收场,你信这个函数
还未若信上帝,甚至于onProgressChanged这个函数
且比onPageFinished
要按照一些。如果你的成品经理坚持而早晚要促成这种效益的话,我建议您
提早了他,否则卡在那么用户迟迟动不了 这种经验不好。
闲的同桌可以和一下源码,onPageFinished 在不同之基本里
调用的空子还无均等。说实话 我也酷醉。。。这个题目 有健全解决方案的
请知会我转。。。

4.后台无法自由js 导致耗电。
本条也许非常少有人知道,你一旦webview加载的html里 有一对js
一直以尽准卡通之类的事物,如果这个刻webview 挂在了后台
这些资源是休会见吃放飞,用户为束手无策感知,导致一直占cpu
耗电特别快,所以大家记住了,如果撞这种景象
请在onstop和onresume里分别把setJavaScriptEnabled();
为安装成false和true。

5.如果实在不思就此开额外经过的道解决webview
内存泄露的题目,那么下面的措施很老程度上得避免这种景象

public void releaseAllWebViewCallback() { 
 if (android.os.Build.VERSION.SDK_INT < 16) { 
 try { 
 Field field = WebView.class.getDeclaredField("mWebViewCore"); 
field = field.getType().getDeclaredField("mBrowserFrame"); 
 field = field.getType().getDeclaredField("sConfigCallback");
field.setAccessible(true); 
 field.set(null, null);
 } catch (NoSuchFieldException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (IllegalAccessException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
  }
 } else {
 try {
 Field sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
 if (sConfigCallback != null) {
 sConfigCallback.setAccessible(true);
 sConfigCallback.set(null, null);
  }
 } catch (NoSuchFieldException e) {
if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (ClassNotFoundException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
 } catch (IllegalAccessException e) {
 if (BuildConfig.DEBUG) {
  e.printStackTrace();
  }
  }
  }
 }

以webview的 destroy方法里 调用者办法就行了。

末附上示例源码,欢迎fork
and star

再次多精彩文章请关注微信公众号”Android经验分享“:这里拿长期也公分享Android高手经验、中外开源项目、源码解析、框架设计和Android好文推荐!

扫一扫加我啊

 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {  
 if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {    
 webView.goBack();// 返回前一个页面   
  return true;   
}    
return super.onKeyDown(keyCode, event);
}

亚、webview与js的相(相互调用参数、传值)
前者网页全部代码,文章最后有示范项目完全源码

<!DOCTYPE html><html><head>    <meta charset="utf-8">    
<title>jaydenxiao遇上了webview</title>    
<script>
function sayHello() {
alert("我是无参无返回toast") 
}
function alertMessage(message) { 
alert(message)  
}
function toastMessage(message) {
window.control.toastMessage(message)
}
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
function sumToJava2(number1, number2) {
return number1 + number2;
}    
</script>
</head><body>
 <button type="button" id="button" onclick="toastMessage('js调用了android方法')">js访问android中方法

</button>
  </body>
  </html>

调用示例:
js调用Java
调用格式为window.jsInterfaceName.methodName(parameterValues)此例中我们使用的凡control作为注入接口名称。

function toastMessage(message) { 
window.control.toastMessage(message) 
}
function sumToJava(number1, number2){ 
window.control.onSumResult(number1 + number2)
 }

Java调用JS
webView调用js的核心格式为webView.loadUrl(“javascript:methodName(parameterValues)”)****1.
android调用js无参无返回值函数

 final String call = "javascript:sayHello()";
 mWebView.post(new Runnable() {    
  @Override    
  public void run() { 
   mWebView.loadUrl(call);    
 }
 });

2. android调用js有参无返回值函数

final String call = "javascript:alertMessage(\"" + "我是android传过来的内容,hey man" + "\")";
 mWebView.post(new Runnable() {    
 @Override    
   public void run() { 
    mWebView.loadUrl(call);    
  }
}
);

3. android调用js有参有返回值函数(4.4事先)
Android在4.4前连从未供第一手调用js函数并获得值的措施,所以在此之前,常用之思绪是
java调用js方法,js方法执行了,再次调用java代码用价值返回。
(1).android调用js代码

   final String call = "javascript:sumToJava(1,2)";mWebView.post(new Runnable() { 
   @Override public void run() { 
   mWebView.loadUrl(call); }
   });

(2).js函数处理,并将结果通过调用android方法返回
网页端:

function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }

(3).android在回调方法被得到js函数返回值

@JavascriptInterfacepublic void onSumResult(int result) { 
  Toast.makeText(getApplicationContext(), "我是android调用js方法(4.4前),入参是1和2,
       js返回结果是" +    result, Toast.LENGTH_LONG).show();
   }

4. android调用js有参有返回值函数(4.4上述):****
Android 4.4之上使用evaluateJavascript即可。这里显得一个简练的彼此示例
具有返回值的js方法
js代码如下:

 function sumToJava2(number1, number2) {return number1 + number2;}

android代码如下:

@TargetApi(Build.VERSION_CODES.KITKAT)
public void Android2JsHaveParmHaveResult2(View view) { 
mWebView.evaluateJavascript("sumToJava2(3,4)", new ValueCallback<String>() {
@Override 
public void onReceiveValue(String Str) {   
 Toast.makeText(getApplicationContext(), "我是android调用js方法(4.4后),入参是3和4,
  js返回结果是" +    Str, Toast.LENGTH_LONG).show(); 
   }    
 } );
}

知识点

1.图片由适应
当自己所以webview直接显示该网页的早晚,图片并无可知由适应,只会亮有。那么什么样形成从适应手机屏幕为?具体见代码:

WebSettings webSettings = view.getSettings(); 
 // User settings           
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);//适应内容大小
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);

专注:对于比较复杂的网页,该方式无自然有效,需要开发者自行测试。

2.收获图片地址

那哪下充斥网页遭到之图纸为?我们可由此webview中之setOnLongClickListener获取HitTestResult对象,通过判断该对象的品种获取点击图片的URL,然后将图片下载到地面。

webwiew.setOnLongClickListener(new View.OnLongClickListener() {      
 @Override     
 public boolean onLongClick(final View v) {             
   final WebView.HitTestResult result = ((WebView) v).getHitTestResult();             
   int type = result.getType();              
   if (type == WebView.HitTestResult.IMAGE_TYPE) {                    
   WebView.HitTestResult result = ((WebView) v).getHitTestResult();           
         String imgurl = result.getExtra();//图片地址                   
       }             
    return false;        
    }     
   });

HitTestResult的种有:

类型 名称 作用
int ANCHOR_TYPE 已经废弃
int EDIT_TEXT_TYPE 打开一个可编辑的区域
int EMAIL_TYPE 邮件
int GEO_TYPE map地址
int IMAGE_ANCHOR_TYPE 已经废弃
int IMAGE_TYPE 图片
int PHONE_TYPE 电话号码
int SRC_ANCHOR_TPE html的a标签,内容是一个http地址
int SRC_IMAGE_ANCHOR_TYPE html的a标签,内容由http及image
int UNKNOW_TYPE 未知内容

相关文章