WebView使用总结
闲话(可直接无视
好久都没有上博客写点东西,总结下最近的学习情况了,又是课程设计又是项目的,都快被弄成XX了。最近又接了个锅,做一个能社交的游记应用,游记的内容由用户编辑好之后上传给服务器,由前端写好不同模板后将图片放入模板,前段还是很溜的,写出来的模板都蛮好看的呢(射鸡湿也很厉害呢,Android这边需要通过WebView去浏览已经处理好的游记。第一次接触到了WebView,感觉好激动好神秘,下面就把使用WebView的一些经验给大家呈上来orz。好久都没上来写点东西了,一上来就大片废话(
1. 简介
国际惯例咯,先看看google推销它自己东西的。
public class
WebView
extends AbsoluteLayout
implements ViewTreeObserver.OnGlobalFocusChangeListener ViewGroup.OnHierarchyChangeListener
java.lang.Object
? android.view.View
? android.view.ViewGroup
? android.widget.AbsoluteLayout
? android.webkit.WebView
A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.
Note that, in order for your Activity to access the Internet and load web pages in a WebView, you must add the INTERNET permissions to your Android Manifest file:
<uses-permission android:name="android.permission.INTERNET" />
附上我的渣渣翻译orz:
WebView是用来显示网页的控件,这个类能作为你制作自己的浏览器或者仅仅在activity中显示一些网络上内容的基础,它采用了WebKit渲染引擎来显示网页并且能够在历史记录中显示上一页和下一页,放缩以及对网页上的文字进行查询等功能。
需要注意的是,为了让WebView能够访问网络,应该在AndroidManifest.xml文件里面加入下面的权限(上面那一行).....如果是直接访问本地的html,是不用加上的,但本地有什么好玩的,最好还是加上把,忘记了就game over了。
说白了就是用来显示网页的,之前小达只知道能访问网络上的东西,不知道还可以访问本地的html文件,后面会给大家一一呈上来。
2. 简单使用
了解了大概之后现在来实战一下。
2.1 从网络加载
最开始的时候看着官方文档上是这么写的
webview.loadUrl("http://slashdot.org/");
看到这个瞬间惊呆了,就在想这么流弊么。传入url就可以访问网站了?接着动手试了一下,创建一个Activity,布局文件里面只放一个WebView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_display_template_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ldx.microtravelnotes.ui.activity.DisplayTemplateActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
掉头去Activity里面对WebView进行设置,需要说明的是,直接mWebView.setXXX()什么都找不到,什么也设置不了,WebView里面有一个WebSetting,相当于用于配置当前WebView的一个类,里面可以设置是否支持JavaScript等内容,其他的自己去探索咯…..
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAllowFileAccessFromFileURLs(true);
mWebView.loadUrl("http://www.baidu.com");
之后我就发现,是真的这么流弊(没图你bb),上图:
关键点在loadUrl这个函数,上面的例子将baidu的url传给了webview加载,能够直接浏览baidu的主页,但是还不能实现像浏览器一样的点击,那些需要进一步的处理。从网络加载内容没什么坑的地方,需要注意的就是记得添加应用的权限,记得配置一下WebSetting就可以了。
2.2 从本地加载
接触了WebView初步使用之后,小达很快就和前端对上了,成功的显示出了前端制作的效果,上一张图,各路大神求轻喷Orz:
但是在这之后,需要将一些模板(html,css,js组成)从服务器下载到本地之后预览出来。也就涉及到了WebView加载本地文件,在实现的过程中碰到了一些坑,呈上来和大家分享一下。布局文件也是像上面的.xml一样没有变化。唯一需要变化的就是传给WebView的url,改成获取本地的文件即可。
mWebView.loadUrl("file:///android_assert/demo.html");
demo.html只是一个放在asserts资源文件夹下面的html文件,内容如下:
<html>
<head>
<script type="text/javascript">
function updateHtml(){
document.getElementById("content").innerHTML =
"you have invoke javascript method";
}
</script>
</head>
<body>
this is my html
<span id="content"></span>
</body>
</html>
关于这个WebView调用本地文件,花了一点时间,原因是在调用本地文件的时候会报错,andorid Not allowed to load local resource: file:///android_asset/
啥啥啥的后面跟着一些。找了半天问题,发现自己还真是个外行人orz,连asserts文件夹的位置都给放错了,正确的姿势应该如下,如果不小心放到了res文件夹下面是不行的(除了报错还是报错):
--|build
--|src
---|assets
---|gen
---|java
---|res
如果文件夹的位置也没问题,代码什么都没问题,一万个怀疑是自己的机器出了毛病,官方文档上面还有一个方法:
public void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
参数列表
baseUrl 如果是网络资源,即网络资源的url, 如果是本地资源,该参数填写本应用的根目录. 默认为‘about:blank‘.
data 给WebView加载的一段数据
mimeType the MIMEType of the data, e.g. ‘text/html‘. If null, defaults to ‘text/html‘.
encoding the encoding of the data
historyUrl the URL to use as the history entry. If null defaults to ‘about:blank‘. If non-null, this must be a valid URL.
3. 相互调用
WebView仅仅能显示网页怎么可以,不能实现交互也没什么用,光看看不能碰怎么行。而且根据项目的要求,需要用java调用javascript函数来将本地的图片文件放入js里面,这样才能预览出来,于是又在网络上各种搜索。
3.1 Java调用JavaScript
3.1.1 调用JavaScript无参函数
看到上面加载到WebView中的.html文件中,定义了一个无参数的js函数updateHtml(),这个函数即我们需要再Java代码中手动调用的,一行代码就够了
mWebView.loadUrl("javascript:updateHtml()");
只需要给一个按钮加上一个监听,点击后执行上面这个语句就能够调用js里面的函数了。
3.1.2 调用JavaScript带参函数
但是对于有参数的js函数就不同了。我们将上面的demo.html文件进行小小的修改,让updataHtml()函数变成有一个参数的,代码如下:
<html>
<head>
<script type="text/javascript">
function updateHtml(num){
document.getElementById("content").innerHTML =
"you have invoke javascript method, " + "the num is " + num;
}
</script>
</head>
<body>
this is my html
<span id="content"></span>
</body>
</html>
比较有趣的是,调用js带参函数的传参过程有点厉害,竟然是直接将参数准备好了,和函数名组成一整个字符串,再一起给WebView,当时看到之后吓到了(原谅我的无知orz,乡下来的没见过世面)。上面的Java调用代码如下:
mWebView.loadUrl("javascript:updateHtml(" + 3 + ")");
3.2 Java调用JavaScript
JavaScript反过来调用Java函数相对麻烦一点,需要通过调用WebView的addJavascriptInterface()方法来给js和java之间建立一个调用接口。这个函数有两个参数:
- object the Java object to inject into this WebView’s JavaScript context. Null values are ignored.
- name the name used to expose the object in JavaScript
先定义一个Java和JavaScript之间的接口:
package com.ldx.microtravelnotes.ui.activity;
import android.content.Context;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
/**
* USER: xiaoxiaoda
* DATE: 15-7-29
* EMAIL: [email protected]
* PROJECT: MicroTravelNotes
*/
public class WebViewInterface {
Context mContext;
WebViewInterface(Context context) {
mContext = context;
}
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show();
}
}
这个公共接口里面的方法如果需要被JavaScript调用,需要用@JavascriptInterface打上注解,因为可能会在HTML和JavaScript中包含了有威胁性的代码。所以Android 4.1,API 17,也就是JELLY_BEAN 开始,只有被JavascriptInterface 注解标识的公有方法可以被JS代码访问。
接着再修改以下demo.html里面的代码,让里面的点击事件调用上面定义的公共接口代码:
<html>
<head>
<script type="text/javascript">
function updateHtml(num){
document.getElementById("content").innerHTML =
"you have invoke javascript method, " + "the num is " + num;
}
function startFunction(msg) {
Android.showToast(msg);
}
</script>
</head>
<body>
this is my html <a onClick="startFunction(‘js invoke java success‘)" href="";>invoke java</a>
<span id="content"></span>
</body>
</html>
可以看到点击之后会触发startFunction()方法,进而调用Android.showToast(msg)方法,后面这个语句中的Android是一个在Java代码中自定义的名称,后面会提到的,并不是固定的。而showToast方法则是我们定义的公共接口中的方法。
Java中需要改动的代码如下,也很简单:
mWebView.addJavascriptInterface(new WebViewInterface(this), "Android");
这里的Android就是上面提到的可以自定义的公共接口名称。按照上面的步骤即可完成JavaScript调用Java的功能了。
4. 使用小技巧
Java里面的WebView还是很厉害的,毕竟用起来这么方便,但是在处理有很多图片和动画的网页方面还是会有些卡顿,怎么办呢0.0,毕竟不能一直卡下去呀,到处问各路大神,貌似没有找到很好的解决办法,倒是学到了一些能帮上一点小忙的小技巧。
4.1 启动一个新的进程
给WebView所在的Activity启动一个新的进程,WebView搞不好就崩掉了,你应该不希望WebView随时把你的App弄崩掉吧,给它启动一个新的进程,然后对它说:“要崩你自己崩去吧,不要拉上我orz“。启动的方法很简单,在AndroidManifest.xml文件里面找到所在的Activity,添加上下面的代码就可以了:
android:process="packagename.web"
4.2 尽量动态添加WebView
尽量不要在.xml文件里面直接添加一个WebView控件,动态的Add进去比较好一些,因为在销毁Activity的过程中,可以提前对WebView做一些处理,例如及时的清理掉WebView占用的内存(WebView内存泄漏貌似有点严重的咧,我也就听大神们说的orz),另外需要注意创建webview需要使用applicationContext而不是activity的context。在Activity或者Fragment的onDestory()方法中应该对WebView做一些处理:
mWebView.stopLoading();
mWebView.removeAllViews();
mWebView.destroy();
mWebView = null;
还有一些更加高端的优化和使用技巧暂时没有用上,链接也呈上来,Android WebView开发问题及优化汇总。
以上就是个人在使用WebView时候的一些看法,抽了点时间总结一下,以后也方便自己看看。继续默默的赶项目去了orz……….
版权声明:本文为博主原创文章,未经博主允许不得转载。