第一篇博客,最近在做关于WebView的项目,因为现在的开发为了减小安装包的大小,经常采用H5和原生安卓的混合开发模式,所以也研究了一下关于android网页的一些特性。同时也是为了方便以后开发是遇到的难点进行总结,避免走弯路。
总体的一些问题我就大概分为以下几点:
一、WebView的常用配置
首先我们先想到WebView的配置,在这里我也不多说了,直接上代码,写个通用的WebView。
package com.fryp.frnewweb.web;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebSettings.RenderPriority;
import android.webkit.WebView;
import java.lang.reflect.Method;
public class SGWebView extends WebView {
public SGWebView(Context context) {
super(context);
init();
}
public SGWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SGWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
requestFocusFromTouch();
setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
//支持javascript
this.getSettings().setJavaScriptEnabled(true);
//设置支持获取手势焦点。
this.requestFocusFromTouch();
this.getSettings().setDefaultTextEncodingName("UTF-8");
this.getSettings().setRenderPriority(RenderPriority.HIGH);
this.getSettings().setAllowFileAccess(true);
// 设置可以支持缩放
this.getSettings().setSupportZoom(false);
this.getSettings().setLoadsImagesAutomatically(true);
// this.getSettings().setPluginsEnabled(true);
//扩大比例的缩放
this.getSettings().setUseWideViewPort(true);
//自适应屏幕
this.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
this.getSettings().setLoadWithOverviewMode(true);
//提高网页加载速度,暂时阻塞图片加载,然后网页加载好了,在进行加载图片
this.getSettings().setBlockNetworkImage(true);
//开启缓存机制
this.getSettings().setAppCacheEnabled(true);
if (Integer.parseInt(Build.VERSION.SDK) < 11) {
this.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
} else {
this.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
}
}
@SuppressWarnings("rawtypes")
@Override
public void destroy() {
try {
Class localClass = super.getClass();
Method localMethod = localClass.getMethod("freeMemory", new Class[0]);
localMethod.invoke(this, new Object[0]);
super.destroy();
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的代码中,是设置WebView的一些通用的属性,为了方便查看,我这里又找了一些WebView的配置加了注释的方便查看,基本上需要什么属性主要还是看自己的需求,以上代码的配置基本够用。
http://www.tuicool.com/articles/zy263q
http://www.th7.cn/Program/Android/201211/110963.shtml
二、初始化WebView
以为之前已经写了一个继承WebView所有在使用的时候会用到SGWebView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_p50"
android:orientation="vertical">
<com.fryp.frnewweb.web.SGWebView
android:id="@+id/main_webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
LinearLayout>
以下是在Activity或者Fragment的主要代码,我在这里先贴全部代码,之后再分开来说明
public void initViews() {
mainWebview.setWebViewClient(new MyWebViewClient());
mainWebview.setWebChromeClient(new MyWebChromeClient());
// mainWebview.setWebChromeClient(new WebChromeClientUtil(getActivity(), handler));
mainWebview.addJavascriptInterface(new JsToBrowser(getActivity(), handler), "local_obj");
mainWebview.loadUrl("http://www.xianhua.com.cn/m/");
}
class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
//此处注释的代码是监听网页加载进度的
// if (SimpleHUD.hud != null) {
// SimpleHUD.hud.setProgress(newProgress);
// SimpleHUD.hud.setDetailsLabel(newProgress + "%");
// }
super.onProgressChanged(view, newProgress);
}
}
final class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d("WebView", "shouldOverrideUrlLoading");
view.loadUrl(url);
return true;
}
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// SimpleHUD.showProgressLoading(getActivity(), KProgressHUD.Style.PIE_DETERMINATE);
Log.d("WebView", "onPageStarted");
Log.d("WebView", "url=="+url);
nowUrl=url;
super.onPageStarted(view, url, favicon);
}
public void onPageFinished(WebView view, String url) {
Log.d("WebView", "onPageFinished ");
//网页加载完成后移除不需要的节点,“fudong”和“xiazaiapp”为网页的id
view.loadUrl("javascript:window.local_obj.remove(document.getElementById('fudong').remove());");
view.loadUrl("javascript:window.local_obj.remove(document.getElementById('xiazaiapp').remove());");
//更改网页指定内容,如下的javascript是修改网页中所有标签为“h1”的值。
view.loadUrl("javascript:window.local_obj.remove(document.getElementsByTagName('h1')[0].innerHTML='新标题');");
// SimpleHUD.dismiss();
super.onPageFinished(view, url);
}
}
public Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:// 已认证
Toast.makeText(getActivity(), "网页传过来的值", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
进行交互的时候用到的类
package com.fryp.frnewweb.web;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.webkit.JavascriptInterface;
public class JsToBrowser {
private Handler handler;
Context mContext;
public JsToBrowser(Context m,Handler h) {
mContext=m;
handler=h;
}
//javascript中需要调用该方法
@JavascriptInterface
public void remove(String html){
Log.d("HTML", html);
}
}
好了,代码贴完,对于只需要使用的同学直接在粘贴就行了。接下来分析一下代码的内容,简单了解一下。
首先初步配置的那些我们就不说明了。直接说重点
1、mainWebview.setWebViewClient(new MyWebViewClient());
在设置WebViewClient的时候主要看如下代码中重写的方法:
shouldOverrideUrlLoading
onPageStarted
onPageFinished
在第一次进入网页时,只进入 onPageStarted , onPageFinished
之后再进入时则是有:shouldOverrideUrlLoading onPageStarted onPageFinished,进入方法的顺序亦是如此。因此当我们需要改变网页的内容时,必须等网页加载完成,即onPageFinished写类似view.loadUrl(“javascript:window.local_obj.remove(document.getElementById(‘fudong’).remove());”);的代码。不然会报空指异常。
2、 mainWebview.addJavascriptInterface(new JsToBrowser(this, handler), “local_obj”);
要进行网页的交互必不可少的就是网页调用客户端的方法。”local_obj”即是自己写的类似网页需要调用的接口。remove则是类似调用到该接口的方法。当然了方法是自己定义了,也可以传指定的参数,类似 add(String str) 等。
总结:关于这类内容的话,毕竟自己理解的还不是很深,所以只能告诉你们,把代码复制粘贴进去,别问为什么。有些东西是真的没有原因的。如果你觉得自己自己还是个菜鸟,那更不需要去深刻体会那些问题了。就像有这么一句话“书读百遍,其义自见”。道理皆可用。多敲几遍,其义自见。