Android WebView学习

权限:

<uses-permission android:name=“android.permission.INTERNET”
/>

在WebView中使用JavaScript

WebView myWebView = (WebView) findViewById(R.id.webview);

WebSettings webSettings = myWebView.getSettings();webSettings.setJavaScriptEnabled(true);

绑定JavaScript代码到Android源代码

public class JavaScriptInterface {
Context mContext;
/** Instantiate the interface and set the context */
JavaScriptInterface(hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+context" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">Context c) {
mContext = c;
}
/** Show a toast from the web page */
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
 
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");

这段代码会创建一个名称为“Android”的JavaScript接口并执行在WebView其中。在这里。你的Web应用会接入到JavaScriptInterface类。比如,以下为Html何JavaScript代码,它会在用户点击button的时候使用新的接口创建一个Toast消息。

<input type="button" value="Say hello" onClick="Android.showToast('Hello Android!')" />
备注:在JavaScript中绑定的对象会执行在还有一个线程,它和创建它的线程是不同的线程。

处理页面导航

WebView myWebView = (WebView) findViewById(R.id.webview);

myWebView.setWebViewClient(new WebViewClient());


完毕,如今用户点击的全部链接都会在WebView中打开。假设你想要在点击链接并加载网页的时候做很多其它的操作,请创建自己的WebViewClient 并重写java.lang.String) shouldOverrideUrlLoading()方法。比如:

private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("www.example.com")) {
//这是我的网页,所以不要重写,让我的WebView加载它
return false;
}
// 假设不是我的网页,则启动另外的Activity来处理该URL
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}

操作网页历史

当你的WebView重写URL的加载。它会自己主动累积訪问过的网页历史。你能够使用goBack()方法和goForward()方法操纵回退和向前功能。
比如,以下是Activity使用返回button操作“回退”功能

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+keyevent" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">KeyEvent.KEYCODE_BACK) && myWebView.canGoBack() {
myWebView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}

fragment中webview的历史操作

webview.setOnKeyListener(new OnKeyListener() {
 
@Override
public boolean onKey(View v, int keyCode, hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+keyevent" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) { //表示按返回键 时的操作
webview.goBack(); //后退
return true; //已处理
}
}
return false;
}
});

webview.loaddata乱码解决

loadData()中的html data中不能包括'#', '%', '\', '?

'四中特殊字符。出现这样的字符就会出现解析错误,显示找不到网页还有部分html代码。须要怎样处理呢?我们须要用UrlEncoder编码为%23, %25, %27, %3f 。

能够使用下面两种代码,data为string类型的html代码

1、webView.loadData(URLEncoder.encode(data, “utf-8”), “text/html”, “utf-8”);这样一些背景效果什么的都不怎么好看了。不推荐。

2、webView.loadDataWithBaseURL(null,data, “text/html”, “utf-8”, null);

这样就会完美解析了。

编辑

webview中文乱码解决:

方式一:
//webView.loadData(htmlData, "text/html", "UTF-8");//API提供的标准使用方法。无法解决乱码问题
webView.loadData(htmlData, "text/html; charset=UTF-8", null);//这样的写法能够正确解码
方式二
//先调用这句然后再载入数据
webView.getSettings().setDefaultTextEncodingName("UTF-8");//设置默觉得utf-8
webView.loadData(htmlData, "text/html; charset=UTF-8", null);//这样的写法能够正确解码
方式三:推荐
webView.getSettings().setDefaultTextEncodingName("UTF-8");//设置默觉得utf-8
webView.loadDataWithBaseURL(null,data, "text/html", "utf-8", null);

WebView不载入图片问题

loadData不能载入图片内容,假设要载入图片内容或者获得更强大的Web支持请使用loadDataWithBaseURL

android_webview中内容获取

在程序中常常会用到webView来显示网页,但假设可以得到网页中的内容呢

//定义java的js交互接口,这个类将会被js操纵。
class WebViewContent{
@JavascriptInterface
public void getContent(hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">String data){
webViewContent=data;
 
}
}
//定义WebView并开启、绑定与JS的交互,以便获取webview中的html内容。 WebSettings settings = webView.getSettings();
//开启缩放支持
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
//启用JS
settings.setJavaScriptEnabled(true);
//默认对缩放比例有限制。导致用户体验不好。所以须要设置为使用随意比例缩放。 settings.setUseWideViewPort(true);
//使页面之间能够点击链接导航
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
//初始页面一般过大。我们设置为75%
// webView.setInitialScale(75);
//设置默觉得utf-8,否则会出现乱码现象
webView.getSettings().setDefaultTextEncodingName("UTF -8");
//使用loadDataWithBaseURL替代loadData以提供更好的体验和防止乱码。
webView.loadDataWithBaseURL(null, model.getSummary(), "text/html", "UTF-8", null);
//将JS接口类WebViewContent进行绑定,绑定到js中的handler对象
webView.addJavascriptInterface(new WebViewContent(),"handler");
//通过WebViewClient操作。 webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">String url) {
// 页面载入完毕获取内容,通过js代码就可以获取数据到绑定的js接口对象的相应方法中。
view.loadUrl("javascript:window.handler.getContent('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
super.onPageFinished(view, url);
}
});

Android 中Webview 自适应屏幕

方式一:在HTML页面中使用Viewport Metadata

<head>
<title>Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</head>

上文仅仅是一个仅仅有两个viewport属性样例,下文描写叙述了全部支持的viewport属性及其同意的值类型。

<meta name="viewport"
content="
height = [pixel_value | device-height] ,
width = [pixel_value | device-width ] ,
initial-scale = float_value ,
minimum-scale = float_value ,
maximum-scale = float_value ,
user-scalable = [yes | no] ,
target-densitydpi = [dpi_value | device-dpi |
high-dpi | medium-dpi | low-dpi]
" />

自己主动调整尺寸

<meta name=“viewport” content=“width=device-width”
/>

提前定义viewport缩放

viewport的缩放值定义了页面所同意的缩放范围。

viewport属性同意您通过下面方式指定您的页面缩放:

initial-scale

页面的初始缩放。这个值是一个指示您的页面相对于屏幕大小倍数的float值。比如,假设您设置初始缩放为“1.0”那么页面将依据目标密度1比1的显示。假设设置为“2.0”那么页面将放大2倍。

为了将网页与viewport尺寸匹配,默认初始缩放是计算过的。

由于默认viewport 是800像素宽。假设设备屏幕推断为小于800像素宽,初始缩放将以小于1.0的某个值为默认值,以便在屏幕上匹配一个800像素宽的页面。

minimum-scale

同意的最小缩放。这个值是一个指示您的页面相对于屏幕大小最小倍数的float值。比如,假设您设置为1.0。那么由于最小大小和目标密度是1:1的,页面就不能缩小。

maximum-scale

同意的最大缩放。这个值是一个指示您的页面相对于屏幕大小最大倍数的float值。比如您设置此值为2.0,那么您就不能放大超过2倍。

user-scalable

是否同意用户缩放此页面。

设置为yes同意缩放,no为不同意缩放。默认值是yes。假设您设置此值为no,那么minimum-scale和maximum-scale将会被忽略。由于缩放不可用。

所以的缩放值必须在0.01到10之间。

<meta name=“viewport” content=“initial-scale=1.0” />

这个metadata设置初始缩放为相对于viewport目标密度的原始大小。

提前定义viewport匹配密度

设备屏幕的密度基于屏幕决定。由每英寸的像素数(dpi)定义。有三种Android支持的密度:高(hdpi)、中(mdpi)和低(ldpi)

您能够通过使用viewport属性target-densitydpi来为您的网页改变目标密度。它同意下面的值:

device-dpi - 使用设备本地的dpi作为目标dpi。默认缩放将不会起作用。

high-dpi - 使用hdpi作为目标dpi。 中和低密度的屏幕将会适当缩小。

.

medium-dpi - 使用mdpi作为目标dpi。

高和低密度的屏幕将会分别放大和缩小。这是默认的密度值。

low-dpi - 使用ldpi作为目标dpi。 中和高密度的屏幕将会适当放大。

<value> - 指定一个dpi值作为目标dpi。该值必须在70-400之间。

比如,您能够通过设置viewport的target-densitydpi属性,来阻止Android浏览器和WebView为不同的分辨率缩放网页。而这个页面会以当匹配前屏幕的密度的大小显示。

在本例中,您相同应该定义viewport的宽以匹配设备宽度。这样您的页面才会自然适合屏幕大小。比如:

<meta name=“viewport” content=“target-densitydpi=device-dpi, width=device-width”
/>

方式二:用JavaScript适配设备密度

Android浏览器和WebView支持同意您请求当前设备的屏幕密度的DOM属性 - DOM属性 window.devicePixelRatio。这个属性的值 指定当前设备使用的比例系数。比如,假设window.devicePixelRatio的值是“1.0”。那么这个设备被觉得是中等密度而且默认情况下不缩放;假设这个值是“1.5”,那么这个设备被觉得是高密度而且默认情况下放大1.5x。假设这个值是“0.75”。那么这个设备被觉得是低密度而且默认情况下缩小0.75x。默认匹配的是中等密度,可是您能够改变这个密度匹配来改变不同屏幕密度下您网页的缩放。

if (window.devicePixelRatio == 1.5) {
alert("This is a high-density screen");
} else if (window.devicePixelRatio == 0.75) {
alert("This is a low-density screen");
}

方式三:使用代码方式

本人測试还是存在问题

关键代码:

settings.setUseWideViewPort(true); 

settings.setLoadWithOverviewMode(true);

    WebSettings settings = webView.getSettings();
 
settings.setSupportZoom(true);//开启缩放支持
settings.setBuiltInZoomControls(true);//开启缩放支持
settings.setJavaScriptEnabled(true);
settings.setDisplayZoomControls(false); //隐藏webview缩放button
//默认对缩放比例有限制。导致用户体验不好。所以须要设置为使用随意比例缩放。
settings.setUseWideViewPort(true);
//设置webView自适应手机屏幕
settings.setLoadWithOverviewMode(true);
settings.setDefaultTextEncodingName("UTF -8");//设置默觉得utf-8
//使页面之间能够点击链接导航
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());

參考:http://www.cnblogs.com/bluestorm/archive/2013/04/15/3021996.html

方式四:综合方式-强烈推荐

參考:http://www.cppblog.com/WhiteDummy/archive/2013/06/25/201300.aspx

假设想要得到正常的倍率,是须要配合网页端的。

(这里仅讨论html5的场合,跨平台嘛)

个人觉得,由网页方面写死一个宽,再提供一个js的缩放函数(包含图片。字体),依据不同设备的分辨率来调用,是比較理想的。(当然,也能够用穷举法,一个分辨率进一个网页。用不同css和不同大小资源 =_=!)

如果宽定位1280,则html5方面必须有:

<meta name=“viewport” content=“width=1280, initial-scale=1.0,maximum-scale=2.0, minimum-scale=0.5,
user-scalable=no,target-densitydpi=device-dpi” />


当中,target-densitydpi是最重要的,它将配合android端的下面代码使用。

  //use html5 viewport attribute
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);

表示我们的代码支持html5网页自适应。所谓杀什么畜生用什么刀。网页的事情。dpi适应什么的,就交给html5去做好了 = =。不用我们在更外面一层蛋疼。

这样做之后。1280宽的图片不管在什么设备的分辨率都是正常的尺寸,不会被做倍数不明的拉伸,方便我们控制。

最后我採取的策略:

<meta name=“viewport” content=“width=device-width, initial-scale=1.0, user-scalable=yes,target-densitydpi=device-dpi”>

  //use html5 viewport attribute
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);

实例:自己开发简易脱机浏览器

google android sdk离线文档打开的时候特别慢。据说是要从谷歌官网拉取一些东西导致的。脱机浏览能够解决该问题。PC端能够使用firefox。

可是Android端貌似没有支持脱机工作的浏览器。这让我非常伤心。决定开发一个简易的脱机浏览器以便在手机端高速查看sdk文档。

设计到的知识点主要为:WebView的初始化以及缩放问题;将应用程序加入到文件打开方式中。

废话不多说:下面为代码部分:

do=export_code&id=android:android_webview%E5%AD%A6%E4%B9%A0&codeblock=13" title="下载片段" class="mediafile mf_" style="color:rgb(51,122,183); text-decoration:none; padding:0px 0px 0px 18px">MainActivity

package net.xby1993.simpleexplorer;
 
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
 
 
public class MainActivity extends Activity {
private static final String TAG=MainActivity.class.getSimpleName();
private WebView webView;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏无标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.webView);
WebSettings settings= webView.getSettings();
//开启缩放支持
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
settings.setJavaScriptEnabled(true);
//默认对缩放比例有限制。导致用户体验不好,所以须要设置为使用随意比例缩放。
settings.setUseWideViewPort(true);
//设置编码。防止乱码
settings.setDefaultTextEncodingName("UTF-8");
//使页面之间能够点击链接导航
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
//初始页面一般过大,我们设置为75%
webView.setInitialScale(75);
Intent intent=getIntent();
//提取文件管理器打开方式传送的文件地址
if(intent.getAction().equals(Intent.ACTION_VIEW)){
String strUri=intent.getDataString();
Log.d(TAG,TAG);
Log.d(TAG,strUri);
Log.d(TAG,Uri.encode(strUri));
//webView.loadUrl(strUri); 为避免乱码别使用它
webView.loadDataWithBaseURL(strUri,null, "text/html", "utf-8", null);
}
 
}
 
@Override
public boolean onKeyDown(int keyCode,hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+keyevent" style="color:rgb(51,122,183); text-decoration:none; background-color:transparent">KeyEvent event){
//确保能够通过返回键浏览历史页面栈
if(keyCode==event.KEYCODE_BACK&&webView.canGoBack()){
webView.goBack();
return true;
}
return super.onKeyDown(keyCode,event);
}
 
 
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?

>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.xby1993.simpleexplorer" >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 删除联网权限的代码 <uses-permission android:name="android.permission.INTERNET"/> -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
 
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- 这里是为了在文件打开方式中加入本应用 -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/html"/>
</intent-filter>
</activity>
</application>
 
</manifest>

參考:

http://stackoverflow.com/questions/8200945/how-to-get-html-content-from-a-webview

http://veikr.com/201106/android_webview_content-html.html

Android WebView学习的更多相关文章

  1. Android开发学习笔记:浅谈WebView(转)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 ...

  2. Android开发学习笔记:浅谈WebView

    本文转自:http://www.2cto.com/kf/201108/101518.html WebView(网络视图)能加载显示网页,可以将其视为一个浏览器.它使用了WebKit渲染引擎加载显示网页 ...

  3. 转 Android开发学习笔记:浅谈WebView

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 ...

  4. Android Studio 学习笔记(五):WebView 简单说明

    Android中一个用于网页显示的控件,实际上,也可以看做一个功能最小化的浏览器,看起来类似于在微信中打开网页链接的页面.WebView主要用于在app应用中方便地访问远程网页或本地html资源.同时 ...

  5. Android WebView和JavaScript交互

    JavaScript在现在的网页设计中用得很多,Android 的WebView可以载入网页,WebView也设计了与JavaScript通信的桥梁.这篇主要介绍一下WebViewk控件如何和Java ...

  6. webview之如何设计一个优雅健壮的Android WebView?(下)(转)

    转载:https://iluhcm.com/2018/02/27/design-an-elegant-and-powerful-android-webview-part-two/ (这篇文章写得有点晚 ...

  7. 如何设计一个优雅健壮的Android WebView?(下)

    转:如何设计一个优雅健壮的Android WebView?(下) 前言 在上文<如何设计一个优雅健壮的Android WebView?(上)>中,笔者分析了国内WebView的现状,以及在 ...

  8. [WebView学习之三]:使用WebView来创建Apps

    上一篇我们学习了([WebView学习之二]:使用Web Apps 支持不同分辨率屏),今天我们来继续学习. (博客地址:http://blog.csdn.net/developer_jiangqq) ...

  9. Android repo 学习参考

    /*************************************************************************** * Android repo 学习参考 * 说 ...

随机推荐

  1. 洛谷——P1226 取余运算||快速幂

    P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod ...

  2. AGC 025 B - RGB Coloring

    B - RGB Coloring Time limit : 2sec / Memory limit : 1024MB Score : 700 points Problem Statement Taka ...

  3. Codechef ForbiddenSum

    Mike likes to invent new functions. The latest one he has invented is called ForbiddenSum. Let's con ...

  4. 输入格式CombineFileInput

    此输入格式的作用就是可以将来自多个不同文件的物理块作为一个split,然后由一个map进行处理. http://www.blogjava.net/shenh062326/archive/2012/07 ...

  5. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  6. [转][译] 分分钟学会一门语言之 Python 篇

    Python was created by Guido Van Rossum in the early 90's. It is now one of the most popularlanguages ...

  7. HashMap源码-Basic hash bin node

    /** * Basic hash bin node, used for most entries. (See below for * TreeNode subclass, and in LinkedH ...

  8. Saga的实现模式——进化(Saga implementation patterns – variations)

    在之前的几个博客中,我主要讲了两个saga的实现模式: 基于command的控制者模式 基于事件的观察者模式 当然,这些都不是实现saga的唯一方式.我们甚至可以将这些结合起来. 发布者——收集者 回 ...

  9. 7zip File: How to Uncompress 7z files on Ubuntu, Debian, Fedora

    转:http://www.thegeekstuff.com/2010/04/7z-7zip-7za-file-compression/ Question: How do I uncompress a ...

  10. 【spring boot】4.spring boot配置多环境资源文件

    一个spring boot 项目在开发环境.测试环境.生产环境下,好多的配置都是不尽相同的.所以配置多分的资源文件,仅仅在部署在不同环境的时候,选择激活不同的资源文件就可以实现多环境的部署. 项目结构 ...