>

不过它的API却没有很大的改动,这一改动大大提

- 编辑:澳门博发娱乐官网 -

不过它的API却没有很大的改动,这一改动大大提

private boolean isSystemLocationEnable() { LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); boolean gpsLocationEnable = manager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean networkLocationEnable = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); return gpsLocationEnable && networkLocationEnable;}

-

WebView简介

为了便利开采者达成在app内展现网页并与网页交互的必要,Android SDK提供了WebView组件。它继续自AbsoluteLayout,显示网页的同期,也得以在里边归入其他的子View。现近期,Hybrid应用如同私吞的应用程式的主流类型,那么关于WebView的应用就变得更其的要紧。从Android 4.4(KitKat)起始,原来基于WebKit的WebView开头依据Chromium内核,这一改变大大进级了WebView组件的属性以及对HTML5,CSS3,JavaScript的帮助。可是它的API却绝非非常大的转移,在非常低版本的同临时候只援用了少部分新的API,并不需求你做极大的改换。不过有几点改造须要专一,但自个儿尝试着翻译了下,发掘仍然希伯来语原来的书文说得好,所以小编贴链接吧~~~Migrating to WebView in Android 4.4在WebView中,有多少个地点是我们得以应用来定制大家的WebView种种行为的,分别是:WebSettingsJavaScriptInterfaceWebViewClient以及WebChromeClient。那么些作者都会在接下去的篇章中各样介绍。

亲自去做二 JavaScript调用有重回值的Java方法

1.概念二个带重回值的Java方法,并运用@JavaInterface:

@JavaInterface
public String getMessage(){
    return "Hello,boy~";
}

2.添加JavaScript的映射

webView.addJavaScriptInterface(this,"Android");

3.通过JavaScript调用Java方法

function showHello(){
    var str=window.Android.getMessage();
    console.log(str);
}

如上便是Js与WebView交互的一些介绍,希望能对你有帮扶。

WebView加载优化

当WebView的利用频率变得频仍的时候,对于其各地点的优化就变得稳步入眼了起来。能够掌握的是,我们每加载三个H5页面,都会有众多的乞求。除了HTML主UENCOREL本人的央浼外,HTML外部引用的 JS、CSS、字体文件、图片都是三个个独立的HTTP 供给,就算央求是出新的,但当网页全部数据达到自然程度的时候,再加多浏览器分析、渲染的年华,Web全部的加载时间变得十分长。同期呼吁文件更多,消耗的流量也会越来越多。那么对于加载的优化就变得不行重大,那上头的经历笔者也未曾什么其余,大致八个地点:

三个,便是财富本地化的标题

先是能够鲜明的是,以前段时间的网络条件,通过互连网去服务器获取能源的速度是遥远未有从地面读取的。批评种种优化计谋其实恰恰忽略了“要求加载”才是挡住速度升高的最大阻力。所以大家的思绪一,就是将有个别较重的能源比方js、css、图片以至HTML自身实行业地化管理,在历次加载到这么些能源的时候,从本地读取举行加载,可以轻易记忆为“存·取·更”。

实际完成思路为:

  • “存”——将上述重量级能源打包进apk文件,每回加载相应文件时时从本地取就可以。也可不打包,在率先次加载时以及接下来的多少间隔时间里动态下载存款和储蓄,将全部的能源文件都存在Android的asset目录下;
  • “取”——重写WebViewClient的WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)方法,通过一定的鉴别方法(举例正则表明式)拦截相应的恳求,从本地读取相应能源并再次回到;
  • “更”——创建起Cache Control机制,定期或利用API布告的款式调控地方财富的翻新,保障本地财富是最新和可用的。
    此间附上一篇博客链接,相当的棒可供参照他事他说加以考察:caching-web-resources-in-the-android-device

首个,便是缓存的标题

一经你不利用或不完全选择第一条能源本地化的思路,那么你的WebView缓存是必供给拉开的(即使这一思路和第一条有重合的地点)。

WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//开启DOM缓存
settings.setCacheMode(WebSettings.LOAD_DEFAULT);

在互联网健康时,采纳暗中同意缓存战术,在缓存可收获并且未有过期的气象下加载缓存,不然通过互联网获得财富以收缩页面包车型客车网络央浼次数。

此地值得谈起的是,大家日常在app里用WebView体现页面时,并不想让顾客以为他是在做客二个网页。因为如若大家的app里网页相当多,而笔者辈给顾客的以为又都像在拜会网页的话,大家的app便失去了意义。(小编的情趣是为啥顾客不直接利用浏览器呢?)

由此那时候,离线缓存的难题就值得我们注意。大家供给让客商在未曾网的时候,依然能够操作我们的app,而不是面前遭受贰个和浏览器里的互联网错误一样的页面,哪怕他能打开的操作极其零星。

此处小编的思路是,在张开缓存的前提下,WebView在加载页面时检查测试互联网生成,假设在加载页面时顾客的网络溘然断掉,咱们理应更改WebView的缓存战略。

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo.isAvailable()) {
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);//网络正常时使用默认缓存策略
} else {
    settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//网络不可用时只使用缓存
}

既是有缓存,将在有缓存调整,与一相似的是大家也要确立缓存调节机制,定时或收受服务器通告来进行缓存的清空或更新。

其四个,正是延迟加载和实践js

在WebView中,onPageFinished()的回调意味着页面加载的姣好。但该方法会在JavScript脚本施行到位后才会触发,如果我们要加载的页面使用了JQuery,会在拍卖完DOM对象,施行完$(document).ready(function() {})后才会渲染并呈现页面。那是不可接受的,所以大家须要对Js进行延期加载,当然这有的是Web前端的职业。

假如说还也会有哪些

那就是JsBridge一律不得滥用,那么些对页面加载的姣好速度是有非常的大影响的,倘使壹个页面比较多操作都通过JSbridge来决定,再怎么优化也行不通(因为究竟有那么多操作要实际施行)。同期要小心的是,不管你是否对能源开展缓存,都请将能源在劳务器端进行压缩。因为不管财富的获取和翻新,都以要从服务器获取的,所以对于能源文件的滑坡其实是最直白也最应当做的事体之一,然而寻平常衣服务器端都会做好,所以首要正是地方那三件事。

驾驶牌照考试

介绍了如此多,希望能对你有一些扶持。接下来时纯实战时间,小编会将方面所介绍的居多知识点在接下去的代码里实际应用一遍,希望能够带给你越是直观的利用感受。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:theme="@style/ThemeOverlay.AppCompat.Light" />

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <WebView
            android:id="@+id/web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progress_bar"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="center"
            android:visibility="gone" />
        </FrameLayout>
</LinearLayout>

Java部分

public class MainActivity extends AppCompatActivity {

  private WebView mWebView;

  private ProgressBar mProgressbar;
  private Toolbar mToolbar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      initAppBar();//初始化Toolbar

      initWebView();//初始化WebView
      initWebSettings();//初始化WebSettings
      initWebViewClient();//初始化WebViewClient
      initWebChromeClient();//初始化WebChromeClient
  }

  private void initAppBar() {
      mToolbar = (Toolbar) findViewById(R.id.toolbar);
      mToolbar.setTitle("载入中..");
      mToolbar.setTitleTextColor(getResources().getColor(R.color.colorWhite));
      setSupportActionBar(mToolbar);
      getSupportActionBar().setDisplayHomeAsUpEnabled(false);
  }

  private void initWebView() {
      mWebView = (WebView) findViewById(R.id.web_view);
      mProgressbar = (ProgressBar) findViewById(R.id.progress_bar);
      String url = "https://www.google.com";
      mWebView.loadUrl(url);
  }

  private void initWebSettings() {
      WebSettings settings = mWebView.getSettings();
      //支持获取手势焦点
      mWebView.requestFocusFromTouch();
      //支持JS
      settings.setJavaScriptEnabled(true);
      //支持插件
      settings.setPluginState(WebSettings.PluginState.ON);
      //设置适应屏幕
      settings.setUseWideViewPort(true);
      settings.setLoadWithOverviewMode(true);
      //支持缩放
      settings.setSupportZoom(false);
      //隐藏原生的缩放控件
      settings.setDisplayZoomControls(false);
      //支持内容重新布局
      settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
      settings.supportMultipleWindows();
      settings.setSupportMultipleWindows(true);
      //设置缓存模式
      settings.setDomStorageEnabled(true);
      settings.setDatabaseEnabled(true);
      settings.setCacheMode(WebSettings.LOAD_DEFAULT);
      settings.setAppCacheEnabled(true);
      settings.setAppCachePath(mWebView.getContext().getCacheDir().getAbsolutePath());

      //设置可访问文件
      settings.setAllowFileAccess(true);
      //当webview调用requestFocus时为webview设置节点
      settings.setNeedInitialFocus(true);
      //支持自动加载图片
      if (Build.VERSION.SDK_INT >= 19) {
          settings.setLoadsImagesAutomatically(true);
      } else {
          settings.setLoadsImagesAutomatically(false);
      }
      settings.setNeedInitialFocus(true);
      //设置编码格式
      settings.setDefaultTextEncodingName("UTF-8");
  }

  private void initWebViewClient() {
      mWebView.setWebViewClient(new WebViewClient() {

          //页面开始加载时
          @Override
          public void onPageStarted(WebView view, String url, Bitmap favicon) {
              super.onPageStarted(view, url, favicon);
              mProgressbar.setVisibility(View.VISIBLE);
          }


      //页面完成加载时
      @Override
      public void onPageFinished(WebView view, String url) {
          super.onPageFinished(view, url);
          mProgressbar.setVisibility(View.GONE);
      }

      //是否在WebView内加载新页面
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
          view.loadUrl(request.toString());
          return true;
      }

      //网络错误时回调的方法
      @Override
      public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
          super.onReceivedError(view, request, error);
          /**
               * 在这里写网络错误时的逻辑,比如显示一个错误页面
               *
               * 这里我偷个懒不写了
               * */
      }

      @TargetApi(Build.VERSION_CODES.M)
      @Override
      public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
          super.onReceivedHttpError(view, request, errorResponse);
      }
  });
}

private void initWebChromeClient() {

  mWebView.setWebChromeClient(new WebChromeClient() {

      private Bitmap mDefaultVideoPoster;//默认的视频展示图

      @Override
      public void onReceivedTitle(WebView view, String title) {
          super.onReceivedTitle(view, title);
          setToolbarTitle(title);
      }

      @Override
      public Bitmap getDefaultVideoPoster() {
          if (mDefaultVideoPoster == null) {
              mDefaultVideoPoster = BitmapFactory.decodeResource(
                      getResources(), R.drawable.video_default
              );
              return mDefaultVideoPoster;
          }
          return super.getDefaultVideoPoster();
      }
  });
}

  /**
   * 设置Toolbar标题
   *
   * @param title
   */
  private void setToolbarTitle(final String title) {
  Log.d("setToolbarTitle", " WebDetailActivity " + title);
  if (mToolbar != null) {
      mToolbar.post(new Runnable() {
          @Override
          public void run() {
              mToolbar.setTitle(TextUtils.isEmpty(title) ? getString(R.string.loading) : title);
          }
      });
  }
 }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.page_up:
              Toast.makeText(getApplicationContext(), "页面向上", Toast.LENGTH_SHORT).show();
              mWebView.pageUp(true);
          break;
      case R.id.page_down:
          Toast.makeText(getApplicationContext(), "页面向下", Toast.LENGTH_SHORT).show();
          mWebView.pageDown(true);
          break;
      case R.id.refresh:
          Toast.makeText(getApplicationContext(), "刷新~", Toast.LENGTH_SHORT).show();
          mWebView.reload();
      default:
          return super.onOptionsItemSelected(item);
  }
  return super.onOptionsItemSelected(item);
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {

  //如果按下的是回退键且历史记录里确实还有页面
  if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
      mWebView.goBack();
      return true;
  } else {
      Toast.makeText(getApplicationContext(), "考试结束,恭喜您考试合格!", Toast.LENGTH_LONG).show();
  }
  return super.onKeyDown(keyCode, event);
  }
}

一丶WebView常用艺术

(1)loadUrl
加载分界面,其次还会有LoadData和LoadDataWithBase方法

//加载assets目录下的test.html文件
webView.loadUrl("file:///android_asset/test.html");
//加载网络资源(注意要加上网络权限)
webView.loadUrl("http://blog.csdn.net");

(2)setWebViewClient(借使客户安装了WebViewClient,则在点击新的链接以后就不会跳转到系统浏览器了,而是在本WebView中突显。注意:并无需覆盖 shouldOverrideUrlLoading 方法,同样可以兑现全数的链接都在 WebView 中开荒。)

WebViewClient主要用来支援WebView管理各样布告、央求等事件,通过setWebViewClient方法设置。以下是它的二种布满用法:

1> 完成对网页中中国足球球联赛链接的拦截(比方假设是极客导航的主页,则直接堵住转到百度主页):
当点击页面中的链接后,会在WebView加载USportageL前回调shouldOverrideUrlLoading(WebView view, String url)方法,平日点击八个链接此办法调用一次。

webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if("http://www.jikedaohang.com/".equals(url))                   {
        view.loadUrl("https://www.baidu.com/");
    }

                return true;
            }
        });

至于shouldOverrideUrlLoading再次回到值的误区:网络海人民广播广播台大表明是return true代表在本WebView中开采链接,return false代表调用系统浏览器展开链接。其实假诺设置了WebViewClient,则就不会调用系统浏览器。
那正是说shouldOverrideUrlLoading的回到值到底代表怎么样吗?return true,则在开荒新的url时WebView就不会再加载那一个url了,全体拍卖都亟需在WebView中操作,满含加载;return false,则系统就认为上层未有做管理,接下去依然会继续加载那些url的;私下认可return false。具体的区分彰显如下:
加载百度主页,设置WebViewClient后,重写shouldOverrideUrlLoading(WebView view, String url)方法,第一张是回到false的截图(点击后正常跳转),第二章是回来true的截图(点击无影响,假使期待能够跳转,则须求咱们团结举办拍卖):
图片 1

图片 2

还也许有一点索要专心的是,借使大家阻止了某些url,那么return false 和 return true差异很小,所以常常提议 return false。

2> 加载网页时替换有个别财富(举个例子在加载一个网页时,必要加载三个logo图片,而作者辈想要替换那个logo图片,用我们assets目录下的一张图片替代)
大家通晓大家在加载一个网页的还要也会加载js,css,图片等财富,所以会频仍调用shouldInterceptRequest方法,大家得以在shouldInterceptRequest中张开图纸替换。
潜心:shouldInterceptRequest有多少个重载:
①public WebResourceResponse shouldInterceptRequest (WebView view, String url) 【已过时】
②public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
这两种格局首倘诺第3个参数的两样,WebResourceRequest 将能够收获越来越多的新闻,提供了getUrl(),getMethod,getRequestHeaders等艺术。这里根本是为着显得效果,使用了第一种回调方法。达成格局如下:

mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                WebResourceResponse response = null;
                if (url.contains("logo")) {
                    try {
                        InputStream logo = getAssets().open("logo.png");
                        response = new WebResourceResponse("image/png", "UTF-8", logo);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return response;
            }
        });

3> 设置最先加载网页、加载成功、加载错误时管理

webView.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);  
        // 网页加载完成时处理  如:让 加载对话框 消失  
        ...
    }  

    @Override  
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {  
        super.onReceivedError(view, errorCode, description, failingUrl);  
        // 加载网页失败时处理 如:提示失败,或显示新的界面
        ...
    }    
});  

4> 管理https央求,为WebView管理ssl证书设置WebView暗许是不管理https央求的,必要在WebViewClient子类中重写父类的onReceivedSslError函数

webView.setWebViewClient(new WebViewClient() {    

    @Override  
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {  
        handler.proceed();  // 接受信任所有网站的证书  
        // handler.cancel();   // 默认操作 不处理  
        // handler.handleMessage(null);  // 可做其他处理  
    }   
});   

(3)setWebChromeClient
WebChromeClient首要用来协理WebView管理Javascript的对话框、网址Logo、网站标题以及网页加载进程等。通过WebView的setWebChromeClient()方法设置。

1> 呈现页面加载进度在WebChromeClient子类中重写父类的onProgressChanged函数,progress表示近期页面加载的快慢,为1至100的整数

webView.setWebChromeClient(new WebChromeClient() {    

    public void onProgressChanged(WebView view, int progress) {    
        setTitle("页面加载中,请稍候..." + progress + "%");    
        setProgress(progress * 100);    

        if (progress == 100) {    
            //... 
        }    
    }    
});  

2> 加速HTML网页加载成功速度(私下认可情状html代码下载到WebView后,webkit开头深入分析网页各样节点,发掘有表面体制文件或许外界脚本文件时,会异步发起互联网央求下载文件,但借使在那在此以前也是有解析到image节点,那一定也会发起互联网诉求下载相应的图片。在网络状态很糟糕的情景下,过多的网络诉求就能够造成带宽紧张,影响到css或js文件加载成功的年华,产生页面空白loading过久。消除的措施就是报告WebView先不要自行加载图片,等页面finish后再发起图片加载。)

//1.首先在WebView初始化时添加如下代码
if(Build.VERSION.SDK_INT >= 19) {  
/*对系统API在19以上的版本作了兼容。因为4.4以上系统在onPageFinished时再恢复图片加载时,如果存在多张图片引用的是相同的src时,会只有一个image标签得到加载,因而对于这样的系统我们就先直接加载。*/        webView.getSettings().setLoadsImagesAutomatically(true);  
    } else {  
        webView.getSettings().setLoadsImagesAutomatically(false);  
    }  

//2.在WebView的WebViewClient子类中重写onPageFinished()方法添加如下代码: 
 @Override  
public void onPageFinished(WebView view, String url) {  
    if(!webView.getSettings().getLoadsImagesAutomatically()) {  
        webView.getSettings().setLoadsImagesAutomatically(true);  
    }  
}  

(4)setDownloadListener
通常webview渲染的分界面中包括能够下载文件的链接,点击该链接后,应该初露施行下载的操作并保存文件到地点中。

1> 创建DownloadListener

class MyDownloadListenter implements DownloadListener{
      @Override
      public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) {
          //下载任务...,主要有两种方式
          //(1)自定义下载任务
          //(2)调用系统的download的模块
          Uri uri = Uri.parse(url);
          Intent intent = new Intent(Intent.ACTION_VIEW, uri);
          startActivity(intent);
      }
}

2> 给webview到场监听

webview.setDownloadListener(new MyDownloadListenter());

(5)goBack()
回去上一浏览页面,通过重写onKeyDown方法实现点击再次回到键重返上一浏览页面而非退出程序

public boolean onKeyDown(int keyCode, KeyEvent event) {  
//其中webView.canGoBack()在webView含有一个可后退的浏览记录时返回true

        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {       
            webView.goBack();       
            return true;       
        }       
        return super.onKeyDown(keyCode, event);       
    }
}

值得注意的是,其三个参数的装置影响的是整套应用中的 WebView。假诺大家在有个别页面包车型地铁 WebView 中拍卖过贰遍网页的定势央求,并设置第八个参数为 true,即保留状态的动静下,当后一次在其它页面也许依旧那么些页面打开网页时将不再向客商发起定位权限的呼吁,而是径直施行一定操作。

WebChromeClient


即便说WebViewClient是扶助WebView管理各个文告、央浼事件的“内政大臣”的话,那么WebChromeClient正是赞助WebView管理Javascript的对话框,网址Logo,网址title,加载进程等偏外界事件的“外武大臣”。

onProgressChanged(WebView view, int newProgress):当页面加载的速度产生更改时回调,用来告诉主程序当前页面的加载进度。

onReceivedIcon(WebView view, Bitmap icon):用来抽取web页面包车型大巴icon,大家能够在此地将该页面包车型大巴icon设置到Toolbar。

onReceivedTitle(WebView view, String title):用来接过web页面的title,我们可以在那边将页面的title设置到Toolbar。

以下多少个主意是为了帮助web页面步入全屏形式而留存的(例如播放摄像),若是不达成那八个艺术,该web上的剧情便不能进来全屏形式。

onShowCustomView(View view, WebChromeClient.CustomViewCallback callback):该办法在时下页面步向全屏情势时回调,主程序必得提供一个包罗当前web内容(录像or Something)的自定义的View。

onHideCustomView():该措施在当前页面退出全屏情势时回调,主程序应在此刻遮蔽从前show出来的View。

Bitmap getDefaultVideoPoster():当大家的Web页面包括录制时,大家得以在HTML里为它设置三个预览图,WebView会在绘制页面时根据它的宽高为它布局。而当大家处于弱网状态下时,我们从没非常快的获得该图片,那WebView绘制页面时的gitWidth()方法就能够报出空指针非常~ 于是app就crash了。。

此时大家就需求重写该措施,在我们从没获得web页面上的video预览图时,给予它三个本地的图形,制止空指针的发出。

View getVideoLoadingProgressView():重写该方法能够在摄像loading时予以两个自定义的View,能够是加载圆环 or something。

boolean onJsAlert(WebView view, String url, String message, JsResult result):处理Javascript中的Alert对话框。

boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result):处理Javascript中的Prompt对话框。

boolean onJsConfirm(WebView view, String url, String message, JsResult result):处理Javascript中的Confirm对话框

boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams):该办法在客商打开了web上某些供给上传文件的操作时回调。大家应该在这里开荒一个文件选用器,假设要吊销以此伏乞大家能够调用filePathCallback.onReceiveValue(null)并返回true

onPermissionRequest(PermissionRequest request):该情势在web页面央求有个别尚未被允许或拒绝的权能时回调,主程序在那时候调用grant(String [])deny()方式。假使该格局未有被重写,则暗中认可拒绝web页面央浼的权柄。

onPermissionRequestCanceled(PermissionRequest request):该格局在web权限申请权限被撤回时回调,那时应该隐蔽任何与之荣辱与共的UI分界面。

WebView·驾乘指南

目录

  • WebView简介
  • WebView基本选择
  • WebView常用艺术
  • WebSettings
  • WebViewClient
  • WebChromeClient
  • JavaScript与WebView交互
  • WebView加载优化
  • 驾驶证件本考试
  • 上路

WebView简介

要兑现Android与H5互调,WebView是四个十分重大的控件,WebView能够很好地支援大家来得html页面,所以有须要先掌握一下WebView。

<!DOCTYPE html><head></head><body> <button onclick="fetchLocation()">获取位置</button> <script> var tipsEle = document.getElementById function fetchLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError) } else { alert('当前设备不支持定位!') } } function onGeoSuccess{ alert("Success: " + event.coords.latitude + ", " + event.coords.longitude) } function onGeoError{ alert("Error code " + event.code + ". " + event.message) } </script></body>

WebView基本使用


下边简介下WebView的着力选拔: 首先新建三个工程,在layout文件里放入三个WebView控件(当然也能够因而Java代码动态放入,这里不演示了)

图片 3

XML

下一场在Activity的onCreate方法里写入如下代码:

图片 4

Java

跟着在AndroidManifest申明访谈网络的权限:

图片 5

Java

就,完事了~ 那时运营app,它曾经得以访问钦点地址的网页了。


上边提到了WebView承继自AbsoluteLayout,能够在里面归入一些子View,那也顺手来一下。 Layout文件改为:

图片 6

XML

Activity的onCreate里加上:

图片 7

Java

此刻,运营app,里面就能够多出贰个Button~ 但即便您真的运维以来,你就能发觉,app会自动跳到浏览器并开发钦定的网页,而毫无在app内显示网页,那这就与我们的初心齐镳并驱了,那么要怎样达成网页在App内展开呢?那就引出了下边的章节会提到的事物:WebViewClient。小编先将代码贴出,具体完毕原理留到下节表达。

谈起底XML布局如同上边那样,Java代码(最后)如下:

图片 8

Java

效果图:

WebView·驾车指南·效果图1

目录

  • WebView简介
  • WebView基本选用
  • WebView常用艺术
  • WebSettings
  • WebViewClient
  • WebChromeClient
  • JavaScript与WebView交互
  • WebView加载优化
  • 驾驶证照考试
  • 上路

WebView基本使用

下边简要介绍下WebView的骨干选取:
先是新建贰个工程,在layout文件里放入二个WebView控件(当然也能够经过Java代码动态放入,这里不演示了)

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<WebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</LinearLayout>

下一场在Activity的onCreate方法里写入如下代码:

String url = "https://www.google.com";
WebView webView = (WebView) findViewById(R.id.web_view);
webView.loadUrl(url);

进而在AndroidManifest表明访谈互连网的权限:

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

就,完事了~
那时运转app,它曾经得以访谈钦点地址的网页了。
上边提到了WebView承接自AbsoluteLayout,能够在里头放入一些子View,那也顺手来一下。
Layout文件改为:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <WebView
      android:id="@+id/web_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

      <Button
          android:id="@+id/button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_x="170dp"
          android:layout_y="400dp"
          android:background="@color/colorAccent"
      android:text="@string/app_name" />
  </WebView>
</LinearLayout>

Activity的onCreate里加上:

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Toast.makeText(getApplicationContext(), "系好安全带!", Toast.LENGTH_SHORT).show();
    }
});

那儿,运营app,里面就可以多出三个Button~ 但一旦你真正运维以来,你就可以意识,app会自动跳到浏览器并开采钦赐的网页,而毫无在app内体现网页,那那就与大家的当初的愿景齐镳并驱了,那么要怎么样实现网页在App内展开呢?那就引出了上边包车型大巴章节会提到的事物:WebViewClient。我先将代码贴出,具体落到实处原理留到下节认证。

终极XML布局就好像上边那样,Java代码(最终)如下:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String url = "https://www.google.com";
    WebView webView = (WebView) findViewById(R.id.web_view);
    webView.loadUrl(url);

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.toString());
            return true;
        }
    });

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(getApplicationContext(), "系好安全带!", Toast.LENGTH_SHORT).show();
        }
    });
  }
}

java与JS互调代码示例

先看成效图:
图片 9

腼腆,传错了,是那张:
图片 10

代码很轻巧,何况加了讲解,直接看代码就能够了。

第一是本土的JavaAndJavaScriptCall.html文件,放在asstes目录下

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <script type="text/javascript">

    function javaCallJs(arg){
         document.getElementById("content").innerHTML =
             ("欢迎:"+arg );
    }

    </script>
</head>
<body>
    <div id="content"> 请在上方输入您的用户名</div>
    <input type="button" value="点击Android被调用" onclick="window.Android.showToast('JS中传来的参数')"/>
</body>
</html>

javaCallJs是java调用JS的方法,showToast方法是JS调用java的方法

接下去是布局文件,activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="20dp"
        android:background="#000088">
        <EditText
            android:id="@+id/et_user"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="输入WebView中要显示的用户名"
            android:background="#008800"
            android:textSize="16sp"
            android:layout_weight="1"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="20dp"
            android:textSize="16sp"
            android:text="确定"
            android:onClick="click"/>
    </LinearLayout>

</LinearLayout>

很简短,正是三个输入框和二个分明开关,点击按键会调用JS中的方法。

MainActivity

package com.wangjian.webviewdemo;

import android.annotation.SuppressLint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private LinearLayout ll_root;
    private EditText et_user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ll_root = (LinearLayout) findViewById(R.id.ll_root);
        et_user = (EditText) findViewById(R.id.et_user);
        initWebView();
    }

    //初始化WebView

    private void initWebView() {
        //动态创建一个WebView对象并添加到LinearLayout中
        webView = new WebView(getApplication());
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        webView.setLayoutParams(params);
        ll_root.addView(webView);
        //不跳转到其他浏览器
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        WebSettings settings = webView.getSettings();
        //支持JS
        settings.setJavaScriptEnabled(true);
        //加载本地html文件
        webView.loadUrl("file:///android_asset/JavaAndJavaScriptCall.html");
        webView.addJavascriptInterface(new JSInterface(),"Android");
    }

    //按钮的点击事件
    public void click(View view){
        //java调用JS方法
        webView.loadUrl("javascript:javaCallJs(" + "'" + et_user.getText().toString()+"'"+")");
    }

    //在页面销毁的时候将webView移除
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ll_root.removeView(webView);
        webView.stopLoading();
        webView.removeAllViews();
        webView.destroy();
        webView = null;
    }

    private class JSInterface {
        //JS需要调用的方法
        @JavascriptInterface
        public void showToast(String arg){
            Toast.makeText(MainActivity.this,arg,Toast.LENGTH_SHORT).show();
        }
    }
}

故而,HTML5 本人的一向操作只可以当做一种辅帮手腕。更妥帖的做法是,开垦职员通过百度、高德之类的第三方定位 SDK 在原生代码中拿走顾客地方音讯,当张开 WebView 中的网页时通过拼接 U索罗德L 参数的款式传递给网页。网页自行判别,尽管 U宝马X3L 中不带有定位新闻的话,再通过自己的 API 发起定位央浼。

WebViewClient


从名字上轻巧了解,那么些类仿佛WebView的代办同样,是援救WebView管理各类布告和呼吁事件的,大家能够称他为WebView的“内政大臣”。

onLoadResource(WebView view, String url):该格局在加载页面财富时会回调,每三个能源(譬喻图片)的加载都会调用三遍。

onPageStarted(WebView view, String url, Bitmap favicon):该方法在WebView起始加载页面且仅在Main frame loading(即整页加载)时回调,叁遍Main frame的加载只会回调该措施一次。大家能够在这些情势里设定开启贰个加载的动画片,告诉客商程序在守候互连网的响应。

onPageFinished(WebView view, String url):该方法只在WebView实现三个页面加载时调用一遍(一样也只在Main frame loading时调用),大家能够能够在此刻关闭加载动画,举行其余操作。

onReceivedError(WebView view, WebResourceRequest request, WebResourceError error):该格局在web页面加载错误时回调,这一个错误平日都以由不能与服务器常规连接引起的,最广泛的便是互联网难点。

那些法子有三个地点要求介意:

1.那一个主意只在与服务器不能平常连接时调用,类似于服务器再次来到错误码的那种错误(即HTTP ERROR),该办法是不会回调的,因为你早就和服务器常规连接上了(全怪官方文档(︶^︶));

2.以此法子是新本子的onReceivedError()方法,从API23早先引入,与旧方法onReceivedError(WebView view,int errorCode,String description,String failingUrl)分化的是,新点子在页面局地加载爆发错误时也会被调用(举例页面里三个子Tab可能一张图纸)。这就代表该措施的调用频率恐怕会愈发频仍,所以大家应该在该方法里进行尽量少的操作。

onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse):上二个方法提到onReceivedError并不会在服务器重临错误码时被回调,那么当大家须要捕捉HTTP ECR-VRO瑞虎并拓宽相应操作时应有如何做呢?API23便引进了该措施。当服务器重返二个HTTP ELX570RO奇骏并且它的status code>=400时,该情势便会回调。那些方法的作用域并不局限于Main Frame,任何能源的加载引发HTTP E奥迪Q5RO牧马人都会挑起该措施的回调,所以大家也应有在该格局里施行尽量少的操作,只实行特别须求的错误管理等。

onReceivedSslError(WebView view, SslErrorHandler handler, SslError error):当WebView加载有个别财富吸引SSL错误时会回调该格局,那时WebView要么实行handler.cancel()打消加载,要么实践handler.proceed()方法继续加载(默以为cancel)。必要留意的是,那么些决定也许会被保存并在以后重新境遇SSL错误时施行同一的操作。

WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request):当WebView需求要求某些数据时,那一个措施能够阻止该诉求来报告app况且同意app自己重临一个数码来替代大家原先要加载的数码。

诸如您对web的某部js做了本土缓存,希望在加载该js时不再去乞请服务器而是可以平昔读取本地缓存的js,那个方法就可以扶持你完结这几个需要。你能够写一些逻辑检查评定这一个request,并回到相应的数量,你回来的数量就能够被WebView使用,假如你回去null,WebView会继续向服务器须求。

boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request):哈~ 终于到了这几个主意,在最开头的功底演示时大家用到了这几个艺术。从执行中大家掌握,当大家平昔不给WebView提供WebViewClient时,WebView假设要加载一个url会向ActivityManager寻求多个切合的管理者来加载该url(比方系统自带的浏览器),那平常是大家不想看看的。于是大家供给给WebView提供多个WebViewClient,不分厚薄写该格局再次回到true来告知WebView url的加载就在app中张开。那时便能够兑现在app内访问网页。

onScaleChanged(WebView view, float oldScale, float newScale):当WebView得页面Scale值发生转移时回调。

boolean shouldOverrideKeyEvent(WebView view, KeyEvent event):暗许值为false,重写此措施并return true能够让大家在WebView内部管理理按钮事件。

WebView基本选拔

上面简介下WebView的中坚接纳:首先新建贰个工程,在layout文件里放入一个WebView控件(当然也足以透过Java代码动态归入,这里不演示了)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       
     android:layout_width="match_parent" 
     android:layout_height="match_parent">
<WebView android:id="@+id/web_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/>
</LinearLayout>

下一场在Activity的onCreate方法里写入如下代码:

String url = "https://www.google.com";
WebView webView = (WebView) findViewById(R.id.web_view);
webView.loadUrl(url);

随之在AndroidManifest评释访谈互连网的权限:

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

就,完事了~那时运转app,它早已足以访问钦赐地点的网页了。下边提到了WebView承袭自AbsoluteLayout,能够在个中放入一些子View,这也顺手来一下。Layout文件改为:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       
           android:layout_width="match_parent" 
           android:layout_height="match_parent"> 
<WebView android:id="@+id/web_view" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent"> 
<Button android:id="@+id/button" 
              android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:layout_x="170dp" 
              android:layout_y="400dp" 
              android:background="@color/colorAccent" 
              android:text="@string/app_name" /> 
</WebView>
</LinearLayout>

Activity的onCreate里加上:

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(
            new View.OnClickListener() { 
            @Override 
            public void onClick(View view) { 
                      Toast.makeText(getApplicationContext(), "系好安全带!", Toast.LENGTH_SHORT).show(); }});

此时,运行app,里面就能多出四个Button~ 但假设您真的运转以来,你就可以开采,app会自动跳到浏览器并开荒内定的网页,而不要在app内体现网页,那那就与大家的最初的心愿并肩前进了,那么要怎么兑现网页在App内开发呢?那就引出了上边包车型大巴章节会提到的东西:WebViewClient。小编先将代码贴出,具体贯彻原理留到下节认证。
最后XML布局就像下面那样,Java代码(最后)如下:

public class MainActivity extends AppCompatActivity {
            @Override
             protected void onCreate(Bundle savedInstanceState) {       
                          super.onCreate(savedInstanceState); 
                          setContentView(R.layout.activity_main); 
                          String url = "https://www.google.com"; 
                          WebView webView = (WebView) findViewById(R.id.web_view); 
                          webView.loadUrl(url); 
                          webView.setWebViewClient(new WebViewClient() { 
                     @Override 
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { 
                          view.loadUrl(request.toString());
                          return true; 
                          } }); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getApplicationContext(), "系好安全带!", Toast.LENGTH_SHORT).show(); } }); }}

WebView简介
接下去再介绍一些WebView的常用方法,具体演示会在末端章节的代码里联合显示。

String getUrl():收获当前页面包车型大巴UEvoqueL。
reload():重新reload当前的URL,即刷新。
boolean canGoBack():用来承认WebView里是还是不是还应该有可回落的历史记录。经常大家会在WebView里重写再次来到键的点击事件,通过该办法推断WebView里是不是还应该有历史记录,若有则赶回上一页。
boolean canGoForward():用来承认WebView是还是不是还应该有可向前的历史记录。
boolean canGoBackOrForward(int steps):以当下的页面为起先点,用来确认WebView的历史记录是或不是可未来退或提升给定的步数,正数为发展,负数为落后。
goBack():在WebView历史记录后退到上一项。
goForward():在WebView历史记录里升华到下一项。
goBackOrForward(int steps):以如今页面为起头点,前进或后退历史记录中钦定的步数,正数为发展,负数为落后。
clearCache(boolean includeDiskFiles):清空网页访谈留下的缓存数据。供给专一的时,由于缓存是全局的,所以如若是WebView用到的缓存都会被清空,尽管其余地点也会选取到。该措施接受贰个参数,从命名就可以看见效果。若设为false,则只清空内部存储器里的能源缓存,而不清空磁盘里的。
clearHistory():解除当前webview访谈的历史记录。
clearFormData():撤除自动达成填写的表单数据。须求注意的是,该方法只有清除当前表单域自动实现填写的表单数据,并不会去掉WebView存款和储蓄到地头的数目。
onPause():当页面被失去核心被切换来后台不可知状态,要求举办onPause操作,该操作会布告内核安全地暂停全数动作,比方动画片的施行或一定的得到等。要求专心的是该格局并不会暂停JavaScript的举办,若要暂停JavaScript的推行请使用接下去的那一个措施。
onResume():在原先调用onPause()后,大家得以调用该措施来恢复生机WebView的运作。
pauseTimers():该措施面向全局全体应用程序的webview,它会中断全数webview的layout,parsing,JavaScript Timer。当程序步入后台时,该方法的调用能够减低CPU功耗。resumeTimers():回复pause提姆ers时的兼具操作。
destroy():销毁WebView。需求专心的是:这些格局的调用应在WebView从父容器中被remove掉之后。我们能够手动地调用

rootLayout.removeView(webView);webView.destroy();

getScrollY():该格局重回的当前可知区域的上方距整个页面顶上部分的距离,也正是眼下内容滚动的离开。
getHeight():方法都回去当前WebView那一个容器的莫斯科大学。其实以上七个办法都属于View。
getContentHeight():该措施重临整个HTML页面包车型客车莫斯中国科学技术大学学,但该中度值并不均等当前全部页面包车型地铁惊人,因为WebView有缩放功用, 所以当前全部页面包车型大巴可观其实应该是原始HTML的冲天再乘上缩放比例。由此,正确的论断格局应该是
if (webView.getContentHeight() * webView.getScale() == (webView.getHeight() + webView.getScrollY())) {//已经处于底端}if(webView.getScrollY() == 0){//处于顶部}

pageUp(boolean top):将WebView体现的页面滑动至顶端。
pageDown(boolean bottom):将WebView呈现的页面滑动至尾部。
WebSettings
WebSettings是用来治本WebView配置的类。当WebView第三回成立时,内部会包蕴贰个暗许配置的聚合。若大家想改动这个配置,便得以通过WebSettings里的点子来进展设置。
WebSettings对象足以经过WebView.getSettings()获得,它的生命周期是与它的WebView自个儿城门失火的,假如WebView被销毁了,那么任何由WebSettings调用的格局也长久以来不能够动用。
获取WebSettings对象

WebSettings webSettings = webView.getSettings();

WebSettings常用方法
(差不离具有的set方法都有相应的get方法,这里就只介绍set了。另,全部未写方法再次回到值类型的皆为空类型)
- setJavaScriptEnabled(boolean flag):安装WebView是不是足以运作JavaScript。
- setJavaScriptCanOpenWindowsAutomatically(boolean flag):设置WebView是还是不是能够由JavaScript自动张开窗口,默以为false,平时与JavaScript的window.open()同盟使用。
- setAllowFileAccess(boolean allow):启用或剥夺WebView访谈文件数量。
- setBlockNetworkImage(boolean flag):禁止或允许WebView从互联网上加载图片。供给留意的是,假若设置是从禁绝到允许的成形的话,图片数据并不会在安装退换后立即去获取,而是在WebView调用reload()的时候才会收效。这年,须要确认保障那几个app具备访谈Internet的权力,否则会抛出安全特别。日常未有明确命令禁绝图片加载的急需的时候,完全不用管这么些主意,因为当我们的app具备访谈Internet的权位时,那个flag的默许值正是false。
- setSupportZoom(boolean support):安装是还是不是协助缩放。
- setBuiltInZoomControls(boolean enabled):浮现或不出示缩放按键(wap网页不支持)。
- setSupportMultipleWindows(boolean support):安装WebView是不是帮忙多窗口。
- setLayoutAlgorithm(WebSettings.LayoutAlgorithm l):钦定WebView的页面布局呈现形式,调用该方法会引起页面重绘。私下认可值为LayoutAlgorithm#NARROW_COLUMNS。
- setNeedInitialFocus(boolean flag):布告WebView是或不是要求设置一个节点获取关节当WebView#requestFocus(int,android.graphics.Rect)被调用时,默感觉true。
- setAppCacheEnabled(boolean flag):启用或剥夺应用缓存。
- setAppCachePath(String appCachePath):安装使用缓存路线,这一个门路必需是足以让app写入文件的。该措施应该只被调用二回,重复调用会被漠视~
- setCacheMode(int mode):用来设置WebView的缓存格局。当大家加载页面或从上二个页面重临的时候,会根据设置的缓存形式去检查并利用(或不行使)缓存。
缓存方式有种种:
LOAD_DEFAULT:暗中认可的缓存使用情势。在进行页前面进或后退的操作时,假若缓存可用并未有过期就先行加载缓存,不然从互联网上加载数据。那样能够减掉页面包车型客车互联网央求次数。
LOAD_CACHE_ELSE_NETWORK:倘诺缓存可用就加载缓存,哪怕它们已经过期失效。就算缓存不可用就从互联网上加载数据。
LOAD_NO_CACHE:不加载缓存,只从网络加载数据。
LOAD_CACHE_ONLY:不从互连网加载数据,只从缓存加载数据。
平凡大家能够依据网络状态将这两种形式结合使用,譬如有网的时候使用LOAD_DEFAULT,离线时利用LOAD_CACHE_ONLY、LOAD_CACHE_ELSE_NETWO奔驰M级K,让客户不至于在离线时啥都看不到。setDatabaseEnabled(boolean flag):启用或剥夺数据库缓存。
setDomStorageEnabled(boolean flag):启用或剥夺DOM缓存。
setUserAgentString(String ua):设置WebView的UserAgent值。
setDefaultEncodingName(String encoding):设置编码格式,平日都设为“UTF-8”。
setStandardFontFamily(String font):设置专门的学问的字体族,私下认可“sans-serif”。
setCursiveFontFamily:安装宋体字体族,暗许“cursive”。
setFantasyFontFamily:设置CursiveFont字体族,默认“cursive”。
setFixedFontFamily:安装混合字体族,暗中认可“monospace”。
setSansSerifFontFamily:设置梵文字体族,暗中同意“sans-serif”。
setSerifFontFamily:设置衬线字体族,暗中同意“sans-serif”
setDefaultFixedFontSize(int size):设置暗中认可填充字体大小,默许16,取值区间为[1-72],超越限制,使用其上限值。
setDefaultFontSize(int size):安装暗许字体大小,暗许16,取值区间[1-72],当先限定,使用其上限值。
setMinimumFontSize:设置最小字体,暗中同意8. 取值区间[1-72],超过限制,使用其上限值。
setMinimumLogicalFontSize:安装最小逻辑字体,默许8. 取值区间[1-72],当先限定,使用其上限值。
如上便是一些WebSettings的常用方法,具体的接纳以及部分缓存的主题材料会在接下去的代码以及小说中有更直观的辨证。
WebViewClient
从名字上简单明白,这么些类仿佛WebView的代理人一样,是支援WebView管理种种布告和伸手事件的,我们得以称她为WebView的“内政大臣”。
onLoadResource(WebView view, String url):该形式在加载页面财富时会回调,每二个财富(比方图片)的加载都会调用贰次。
onPageStarted(WebView view, String url, Bitmap favicon):该办法在WebView起始加载页面且仅在Main frame loading(即整页加载)时回调,二回Main frame的加载只会回调该方式三回。我们能够在这一个方法里设定开启七个加载的卡通,告诉客商程序在伺机互连网的响应。
onPageFinished(WebView view, String url):该措施只在WebView达成二个页面加载时调用叁遍(同样也只在Main frame loading时调用),大家能够能够在那时关门加载动画,进行任何操作。
onReceivedError(WebView view, WebResourceRequest request, WebResourceError error):该办法在web页面加载错误时回调,这个错误平时都以由不可能与服务器常规连接引起的,最常见的正是互连网难题。 那些方法有七个地点需求留意:
1.以此措施只在与服务器不能符合规律连接时调用,类似于服务器重返错误码的这种错误(即HTTP E福特ExplorerRO本田CR-V),该格局是不会回调的,因为你已经和服务器常规连接上了(全怪官方文书档案(︶^︶));
2.以此方式是新本子的onReceivedError()方法,从API23初步引入,与旧方法onReceivedError(WebView view,int errorCode,String description,String failingUrl)不一致的是,新点子在页面局地加载爆发错误时也会被调用(举例页面里五个子Tab只怕一张图片)。那就表示该办法的调用频率大概会愈加频仍,所以我们应该在该措施里实践尽量少的操作。
onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse):上八个办法提到onReceivedError并不会在服务器再次来到错误码时被回调,那么当咱们须要捕捉HTTP ELX570RO巴博斯 SL级并举行对应操作时应该如何做吧?API23便引进了该措施。当服务器再次来到三个HTTP E凯雷德RO大切诺基何况它的status code>=400时,该情势便会回调。这些主意的成效域并不局限于Main Frame,任何资源的加载引发HTTP EMuranoRO大切诺基都会引起该办法的回调,所以大家也应当在该措施里施行尽量少的操作,只进行特别须求的错误管理等。
onReceivedSslError(WebView view, SslErrorHandler handler, SslError error):当WebView加载有些财富吸引SSL错误时会回调该格局,那时WebView要么实践handler.cancel()撤废加载,要么试行handler.proceed()方法继续加载(默以为cancel)。供给当心的是,这几个决定可能会被保存并在以后再也相遇SSL错误时进行同样的操作。
WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request):当WebView须求要求某个数据时,这些法子能够阻止该供给来告诉app何况同意app本人重返三个数据来替代大家本来要加载的数量。
举个例子你对web的某个js做了本地缓存,希望在加载该js时不再去乞请丐服装务器而是能够直接读取本地缓存的js,这么些措施就足以协助您成功这几个供给。你能够写一些逻辑检查评定那个request,并回到相应的多寡,你回来的多寡就能够被WebView使用,固然您回去null,WebView会继续向服务器乞求。
boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request):哈~ 终于到了这么些办法,在最开头的根基演示时大家用到了这一个点子。从试行中大家知道,当我们并未有给WebView提供WebViewClient时,WebView借使要加载一个url会向ActivityManager寻求二个适合的管理者来加载该url(举个例子系统自带的浏览器),那日常是大家不想见见的。于是大家要求给WebView提供三个WebViewClient,因人而异写该办法重返true来告知WebView url的加载就在app中张开。那时便能够达成在app内访谈网页。
onScaleChanged(WebView view, float oldScale, float newScale):当WebView得页面Scale值发生改造时回调。
boolean shouldOverrideKeyEvent(WebView view, KeyEvent event):默许值为false,重写此格局并return true能够让大家在WebView内管理按钮事件。
WebChromeClient
假若说WebViewClient是帮助WebView处理各样通告、央求事件的“内政大臣”的话,那么WebChromeClient正是扶持WebView处理Javascript的对话框,网站Logo,网址title,加载进度等偏外界事件的“外武大臣”。
onProgressChanged(WebView view, int newProgress):当页面加载的速度产生转移时回调,用来告诉主程序当前页面包车型大巴加载进度。
onReceivedIcon(WebView view, Bitmap icon):用来收取web页面包车型地铁icon,我们能够在此处将该页面包车型客车icon设置到Toolbar。
onReceivedTitle(WebView view, String title):用来接过web页面包车型客车title,我们得以在此间将页面包车型地铁title设置到Toolbar。
以下五个艺术是为着援助web页面步向全屏方式而留存的(举例播放摄像),如若不落到实处这五个方法,该web上的内容便不能够进来全屏格局。
onShowCustomView(View view, WebChromeClient.CustomViewCallback callback):该措施在当下页面步入全屏格局时回调,主程序必得提供多个包括当前web内容(录制or Something)的自定义的View。
onHideCustomView():该情势在这两天页面退出全屏情势时回调,主程序应在那儿遮掩此前show出来的View。
Bitmap getDefaultVideoPoster():当大家的Web页面满含录制时,大家可以在HTML里为它设置三个预览图,WebView会在绘制页面时依照它的宽高为它布局。而当大家处于弱网状态下时,大家从不十分的快的获得该图形,那WebView绘制页面时的gitWidth()方法就能够报出空指针极度~ 于是app就crash了。。
那时候咱们就必要重写该格局,在我们从不得到web页面上的video预览图时,给予它多少个本土的图样,防止空指针的发生。
View getVideoLoadingProgressView():重写该办法能够在摄像loading时赋予二个自定义的View,能够是加载圆环 or something。
boolean onJsAlert(WebView view, String url, String message, JsResult result):处理Javascript中的Alert对话框。
boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result):处理Javascript中的Prompt对话框。
boolean onJsConfirm(WebView view, String url, String message, JsResult result):处理Javascript中的Confirm对话框
boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams):该措施在客户进行了web上有个别需求上传文件的操作时回调。大家应当在此地开荒一个文本选拔器,假如要吊销以此央浼大家得以调用filePathCallback.onReceiveValue(null)并赶回true。
onPermissionRequest(PermissionRequest request):该办法在web页面央浼某些尚未被允许或拒绝的权能时回调,主程序在这儿调用grant(String [])或deny()方法。假设该格局未有被重写,则暗中认可拒绝web页面须求的权能。
onPermissionRequestCanceled(PermissionRequest request):该措施在web权限申请权限被吊销时回调,那时应该遮蔽任何与之相关的UI分界面。
Js与WebView交互
既然嗨鸟应用大行其道,那么不容置疑Android与JavaScript的竞相大家也非得掌握精通,上边来介绍一下JavaScript与Android是怎么样相互调用的。
行使WebView调用网页上的JavaScript代码
在WebView中调用Js的大旨格式为webView.loadUrl("javascript:methodName(parameterValues)");
幸存以下这段JavaScript代码

function readyToGo() { alert("Hello") } function alertMessage(message) { alert(message) } function getYourCar(){ return "Car"; }

1. WebView调用JavaScript无参无重返值函数

String call = "javascript:readyToGo()";webView.loadUrl(call);

2. WebView调用JavScript有参无再次来到值函数

String call = "javascript:alertMessage("" + "content" + "")";webView.loadUrl(call);

3. WebView调用JavaScript有参数有再次回到值的函数

@TargetApi(Build.VERSION_CODES.KITKAT)private void evaluateJavaScript(WebView webView){webView.evaluateJavascript("getYourCar()", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("findCar",s); } });}

JavaScript通过WebView调用Java代码
从API19始发,Android提供了@JavascriptInterface对象评释的方法来确立起Javascript对象和Android原生对象的绑定,提须要JavScript调用的函数必得富含@JavascriptInterface。
演示一 JavaScript调用Android Toast方法
1. 编辑Java原生方法并用使用@JavascriptInterface表明

@JavascriptInterface
public void show(String s){ Toast.makeText(getApplication(), s, Toast.LENGTH_SHORT).show();}

2.注册JavaScriptInterface

webView.addJavascriptInterface(this, "android");

addJavascriptInterface的作用是把this所代表的类映射为JavaScript中的android对象。

3.编写JavaScript代码

function toastClick(){ window.android.show("JavaScript called~!"); }

示范二 JavaScript调用有重回值的Java方法
1.概念多少个带再次回到值的Java方法,并选取@JavaInterface:

@JavaInterfacepublic String getMessage(){ return "Hello,boy~";}

2.添加JavaScript的映射

webView.addJavaScriptInterface(this,"Android");

3.通过JavaScript调用Java方法

function showHello(){ var str=window.Android.getMessage(); console.log(str);}

以上就是Js与WebView交互的一对介绍,希望能对您有帮带。
WebView加载优化
当WebView的应用功能变得频仍的时候,对于其各方面包车型大巴优化就变得日益注重了四起。能够领悟的是,大家每加载三个H5页面,都会有为数不菲的央浼。除了HTML主UHighlanderL本身的央浼外,HTML外界援用的 JS、CSS、字体文件、图片都以二个个独立的HTTP 乞请,即使央浼是出新的,但当网页全部数量达到自然水平的时候,再加上浏览器分析、渲染的时日,Web全部的加载时间变得不短。同期伸手文件更加的多,消耗的流量也会越来越多。那么对于加载的优化就变得老大主要,那上面包车型客车阅历我也尚无什么样其他,差不离多少个方面:
一个,正是能源本地化的主题材料
第一能够显明的是,以近日的互联网条件,通过互联网去服务器获取财富的快慢是遥远不如从地点读取的。商量各个优化战术其实恰恰忽略了“须要加载”才是掣肘速度进步的最大阻力。所以大家的笔触一,正是将一些较重的能源举个例子js、css、图片乃至HTML自己实行本地化管理,在历次加载到那几个财富的时候,从地面读取举办加载,能够简简单单纪念为“存·取·更”。
切切实实贯彻思路为:
“存”——将上述重量级财富打包进apk文件,每便加载相应文件时时从本地取就可以。也可不打包,在第贰回加载时以及接下来的繁多间隔时间里动态下载存款和储蓄,将有所的财富文件都存在Android的asset目录下;
“取”——重写WebViewClient的WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)方法,通过自然的识别方法(比如正则表明式)拦截相应的诉求,从本地读取相应能源并回到;
“更”——创建起Cache Control机制,定时或选用API通告的方式调整地点能源的立异,保险本地财富是流行和可用的。这里附上一篇博客链接,十分的厉害可供参谋:caching-web-resources-in-the-android-device

其次个,正是缓存的难题
万一你不选用或不完全选用第一条能源本地化的思绪,那么你的WebView缓存是必供给翻开的(尽管这一思路和第一条有重叠的地点)。

WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//开启DOM缓存settings.setCacheMode(WebSettings.LOAD_DEFAULT);

在互连网健康时,采取默许缓存攻略,在缓存可收获何况未有过期的景况下加载缓存,不然通过网络获得财富以缩减页面包车型大巴网络哀告次数。
此地值得一提起的是,我们平日在app里用WebView展示页面时,并不想让客户以为他是在做客一个网页。因为一旦大家的app里网页非常多,而小编辈给客户的以为又都像在拜候网页的话,大家的app便失去了意义。(小编的情趣是为什么客商不直接采纳浏览器呢?)
故而那时候,离线缓存的难点就值得大家注意。大家供给让客商在未曾网的时候,还能够够操作我们的app,并非面前遭受一个和浏览器里的互联网错误同样的页面,哪怕他能进行的操作非常星星。
此处作者的笔触是,在展开缓存的前提下,WebView在加载页面时检查评定互联网生成,假诺在加载页面时顾客的网络顿然断掉,大家理应改变WebView的缓存攻略。
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo.isAvailable()) { settings.setCacheMode(WebSettings.LOAD_DEFAULT);//互联网健康时利用私下认可缓存战术} else { settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//网络不可用时只利用缓存}

既是有缓存,将要有缓存调控,与一相似的是我们也要组建缓存调整机制,定时或接受服务器文告来进展缓存的清空或更新。
其多少个,正是延迟加载和实行js
在WebView中,onPageFinished()的回调意味着页面加载的姣好。但该方法会在JavScript脚本施行到位后才会触发,要是大家要加载的页面使用了JQuery,会在拍卖完DOM对象,施行完$(document).ready(function() {})后才会渲染并展现页面。那是不可承受的,所以大家须求对Js实行延期加载,当然那有的是Web前端的工作。
假如说还只怕有哪些
这正是JsBridge一律不得滥用,这一个对页面加载的姣好速度是有相当的大影响的,假设二个页面相当多操作都通过JSbridge来支配,再怎么优化也不算(因为毕竟有那么多操作要实际施行)。同有时间要留神的是,不管你是否对资源进行缓存,都请将财富在服务器端实行削减。因为不管能源的得到和更新,都以要从服务器获取的,所以对于财富文件的滑坡其实是最直接也最应该做的政工之一,不过平日服务器端都会做好,所以首要便是上面那三件事。
驾驶牌照考试
介绍了这么多,希望能对你有一点援助。接下来时纯实战时间,作者会将地点所介绍的不菲知识点在接下去的代码里其实使用三遍,希望能够带给您更直观的利用感受。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
      android:orientation="vertical"> 
<android.support.design.widget.AppBarLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content"> 
<android.support.v7.widget.Toolbar 
        android:id="@+id/toolbar" 
        android:layout_width="match_parent" 
        android:layout_height="?attr/actionBarSize" 
        android:background="?attr/colorPrimary" 
        app:theme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.AppBarLayout> 
  <FrameLayout 
         android:layout_width="match_parent" 
         android:layout_height="match_parent"> 
<WebView 
         android:id="@+id/web_view" 
         android:layout_width="match_parent" 
         android:layout_height="match_parent" /> 
<ProgressBar 
         android:id="@+id/progress_bar" 
         android:layout_width="50dp" 
         android:layout_height="50dp" 
         android:layout_gravity="center" 
         android:visibility="gone" /> 
</FrameLayout>
</LinearLayout>

Java部分

public class MainActivity extends AppCompatActivity {

  private WebView mWebView;

  private ProgressBar mProgressbar;
  private Toolbar mToolbar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      initAppBar();//初始化Toolbar

      initWebView();//初始化WebView
      initWebSettings();//初始化WebSettings
      initWebViewClient();//初始化WebViewClient
      initWebChromeClient();//初始化WebChromeClient
  }

  private void initAppBar() {
      mToolbar = (Toolbar) findViewById(R.id.toolbar);
      mToolbar.setTitle("载入中..");
      mToolbar.setTitleTextColor(getResources().getColor(R.color.colorWhite));
      setSupportActionBar(mToolbar);
      getSupportActionBar().setDisplayHomeAsUpEnabled(false);
  }

  private void initWebView() {
      mWebView = (WebView) findViewById(R.id.web_view);
      mProgressbar = (ProgressBar) findViewById(R.id.progress_bar);
      String url = "https://www.google.com";
      mWebView.loadUrl(url);
  }

  private void initWebSettings() {
      WebSettings settings = mWebView.getSettings();
      //支持获取手势焦点
      mWebView.requestFocusFromTouch();
      //支持JS
      settings.setJavaScriptEnabled(true);
      //支持插件
      settings.setPluginState(WebSettings.PluginState.ON);
      //设置适应屏幕
      settings.setUseWideViewPort(true);
      settings.setLoadWithOverviewMode(true);
      //支持缩放
      settings.setSupportZoom(false);
      //隐藏原生的缩放控件
      settings.setDisplayZoomControls(false);
      //支持内容重新布局
      settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
      settings.supportMultipleWindows();
      settings.setSupportMultipleWindows(true);
      //设置缓存模式
      settings.setDomStorageEnabled(true);
      settings.setDatabaseEnabled(true);
      settings.setCacheMode(WebSettings.LOAD_DEFAULT);
      settings.setAppCacheEnabled(true);
      settings.setAppCachePath(mWebView.getContext().getCacheDir().getAbsolutePath());

      //设置可访问文件
      settings.setAllowFileAccess(true);
      //当webview调用requestFocus时为webview设置节点
      settings.setNeedInitialFocus(true);
      //支持自动加载图片
      if (Build.VERSION.SDK_INT >= 19) {
          settings.setLoadsImagesAutomatically(true);
      } else {
          settings.setLoadsImagesAutomatically(false);
      }
      settings.setNeedInitialFocus(true);
      //设置编码格式
      settings.setDefaultTextEncodingName("UTF-8");
  }

  private void initWebViewClient() {
      mWebView.setWebViewClient(new WebViewClient() {

          //页面开始加载时
          @Override
          public void onPageStarted(WebView view, String url, Bitmap favicon) {
              super.onPageStarted(view, url, favicon);
              mProgressbar.setVisibility(View.VISIBLE);
          }


      //页面完成加载时
      @Override
      public void onPageFinished(WebView view, String url) {
          super.onPageFinished(view, url);
          mProgressbar.setVisibility(View.GONE);
      }

      //是否在WebView内加载新页面
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
          view.loadUrl(request.toString());
          return true;
      }

      //网络错误时回调的方法
      @Override
      public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
          super.onReceivedError(view, request, error);
          /**
               * 在这里写网络错误时的逻辑,比如显示一个错误页面
               *
               * 这里我偷个懒不写了
               * */
      }

      @TargetApi(Build.VERSION_CODES.M)
      @Override
      public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
          super.onReceivedHttpError(view, request, errorResponse);
      }
  });
}

private void initWebChromeClient() {

  mWebView.setWebChromeClient(new WebChromeClient() {

      private Bitmap mDefaultVideoPoster;//默认的视频展示图

      @Override
      public void onReceivedTitle(WebView view, String title) {
          super.onReceivedTitle(view, title);
          setToolbarTitle(title);
      }

      @Override
      public Bitmap getDefaultVideoPoster() {
          if (mDefaultVideoPoster == null) {
              mDefaultVideoPoster = BitmapFactory.decodeResource(
                      getResources(), R.drawable.video_default
              );
              return mDefaultVideoPoster;
          }
          return super.getDefaultVideoPoster();
      }
  });
}

  /**
   * 设置Toolbar标题
   *
   * @param title
   */
  private void setToolbarTitle(final String title) {
  Log.d("setToolbarTitle", " WebDetailActivity " + title);
  if (mToolbar != null) {
      mToolbar.post(new Runnable() {
          @Override
          public void run() {
              mToolbar.setTitle(TextUtils.isEmpty(title) ? getString(R.string.loading) : title);
          }
      });
  }
 }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.menu_main, menu);
      return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.page_up:
              Toast.makeText(getApplicationContext(), "页面向上", Toast.LENGTH_SHORT).show();
              mWebView.pageUp(true);
          break;
      case R.id.page_down:
          Toast.makeText(getApplicationContext(), "页面向下", Toast.LENGTH_SHORT).show();
          mWebView.pageDown(true);
          break;
      case R.id.refresh:
          Toast.makeText(getApplicationContext(), "刷新~", Toast.LENGTH_SHORT).show();
          mWebView.reload();
      default:
          return super.onOptionsItemSelected(item);
  }
  return super.onOptionsItemSelected(item);
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {

  //如果按下的是回退键且历史记录里确实还有页面
  if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
      mWebView.goBack();
      return true;
  } else {
      Toast.makeText(getApplicationContext(), "考试结束,恭喜您考试合格!", Toast.LENGTH_LONG).show();
  }
  return super.onKeyDown(keyCode, event);
  }
}

小说来源:http://www.jianshu.com/p/e246d6f537d6

演示一 JavaScript调用Android Toast方法

1. 编辑Java原生方法并用使用@JavascriptInterface申明

 @JavascriptInterface
public void show(String s){
    Toast.makeText(getApplication(), s, Toast.LENGTH_SHORT).show();
}

2.注册JavaScriptInterface

webView.addJavascriptInterface(this, "android");
addJavascriptInterface的作用是把this所代表的类映射为JavaScript中的android对象。

3.编写JavaScript代码

function toastClick(){
     window.android.show("JavaScript called~!");
 }

初稿链接:

此地是贰个差不离的网页源码,当中有一段 JavaScript 代码,用于向宿主浏览器哀求定位:

WebView简介


为了便利开辟者达成在app内体现网页并与网页交互的供给,Android SDK提供了WebView组件。

它一而再自AbsoluteLayout,呈现网页的还要,也能够在内部放入其余的子View。

现目前,Hybrid应用就好像占据的应用程式的主流类型,那么关于WebView的利用就变得愈加的着重。

从Android 4.4(KitKat)早先,原来基于WebKit的WebView初步依照Chromium内核,这一改造大大提高了WebView组件的性质以及对HTML5,CSS3,JavaScript的支撑。但是它的API却未曾相当大的改动,在合营低版本的同有的时候候只援用了少部分新的API,并没有要求你做比异常的大的转移。

唯只有几点改动须求静心,但作者尝试着翻译了下,开采照旧英文原稿说得好,所以自个儿贴链接吧~~~

Migrating to WebView in Android 4.4

​在WebView中,有多少个地方是我们得以应用来定制大家的WebView各类表现的,分别是:WebSettingsJavaScriptInterfaceWebViewClient以及WebChromeClient。这个笔者都会在接下去的稿子中逐条介绍。

WebView简介

接下来再介绍一些WebView的常用方法,具体演示会在后面章节的代码里统一展示。

String getUrl():获得当前页面包车型地铁U福睿斯L。

reload():重新reload当前的URL,即刷新。

boolean canGoBack():用来确认WebView里是还是不是还会有可回落的历史记录。平常大家会在WebView里重写重临键的点击事件,通过该格局推断WebView里是还是不是还恐怕有历史记录,若有则赶回上一页。

boolean canGoForward():用来确认WebView是不是还应该有可向前的历史记录。

boolean canGoBackOrForward(int steps):以当下的页面为伊始点,用来确认WebView的历史记录是不是可现在退或发展给定的步数,正数为发展,负数为落后。

goBack():在WebView历史记录后退到上一项。

goForward():在WebView历史记录里升华到下一项。

goBackOrForward(int steps):以前段时间页面为伊始点,前进或后退历史记录中钦定的步数,正数为发展,负数为落后。

clearCache(boolean includeDiskFiles):清空网页访问留下的缓存数据。要求介怀的时,由于缓存是全局的,所以一旦是WebView用到的缓存都会被清空,纵然其余地点也会动用到。该方法接受一个参数,从命名就可以知到效果。若设为false,则只清空内部存储器里的财富缓存,而不清空磁盘里的。

clearHistory():扫除当前webview访谈的历史记录。

clearFormData():解除自动达成填写的表单数据。须求小心的是,该措施唯有清除当前表单域自动完毕填写的表单数据,并不会免去WebView存款和储蓄到本地的多少。

onPause():当页面被失去主题被切换来后台不可知状态,须求实行onPause操作,该操作会通告内核安全地暂停全部动作,例如动画片的实践或牢固的收获等。要求介意的是该办法并不会暂停JavaScript的进行,若要暂停JavaScript的举办请使用接下去的那个点子。

onResume():在原先调用onPause()后,大家得以调用该格局来还原WebView的运维。

pauseTimers():该措施面向全局全体应用程序的webview,它会暂停全体webview的
layout,parsing,JavaScript Timer。当程序走入后台时,该格局的调用能够降低CPU功耗。
resumeTimers():复原pause提姆ers时的装有操作。

destroy():销毁WebView。供给在乎的是:那个艺术的调用应在WebView从父容器中被remove掉之后。大家得以手动地调用

rootLayout.removeView(webView);
webView.destroy();

getScrollY():该措施重回的近期可知区域的最上端距整个页面最上部的偏离,也正是时下内容滚动的相距。

getHeight():格局都回到当前WebView那么些容器的高度。其实以上多个点子都属于View。

getContentHeight():该办法再次回到整个HTML页面包车型地铁万丈,但该中度值并不平等当前线总指挥部体页面包车型地铁中度,因为WebView有缩放成效, 所以当前任何页面的莫斯中国科学技术大学学其实应该是原始HTML的惊人再乘上缩放比例。因而,正确的推断格局应该是

if (webView.getContentHeight() * webView.getScale() == (webView.getHeight() + webView.getScrollY())) {
//已经处于底端
}

if(webView.getScrollY() == 0){
//处于顶端
}

pageUp(boolean top):将WebView显示的页面滑动至最上部。

pageDown(boolean bottom):将WebView突显的页面滑动至尾巴部分。

二、WebSettings配置

1.获取WebSettings对象

WebSettings webSettings = webView.getSettings();

2.常用设置方法

(1)支持js

settings.setJavaScriptEnabled(true);

(2)设置缓存格局,首要有以下三种:
LOAD_CACHE_ONLY: 不采纳网络,只读取本地缓存数据。
LOAD_DEFAULT: 依照cache-control决定是还是不是从互联网上取数据。
LOAD_CACHE_NORMAL: API level 17中一度放弃, 从API level 11发端功效同LOAD_DEFAULT模式。
LOAD_NO_CACHE: 不选择缓存,只从互联网获取数据。
LOAD_CACHE_ELSE_NETWO昂CoraK:只要本地有,无论是或不是过期,可能no-cache,都应用缓存中的数据。

settings.setCacheMode(WebSettings.LOAD_NO_CACHE);

(3)开启DOM storage API效能(HTML5 提供的一种标准的接口,主要将键值对存储在该地,在页面加载完结后方可通过 JavaScript 来操作这几个数据。)

settings.setDomStorageEnabled(true);

(4)设置数据库缓存路线

settings.setDatabasePath(cacheDirPath);

(5)设置Application Caches缓存目录

settings.setAppCachePath(cacheDirPath);

(6)设置暗中认可编码

settings.setDefaultTextEncodingName(“utf-8”);

(7)将图纸调解到切合webview的轻重缓急

settings.setUseWideViewPort(false);

(8)扶助缩放

settings.setSupportZoom(true);

(9)协理内容重新布局

settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

(10)多窗口

settings.supportMultipleWindows();

(11)设置能够访谈文件

settings.setAllowFileAccess(true);

(12)当webview调用requestFocus时为webview设置节点

settings.setNeedInitialFocus(true);

(13)设置支持缩放

settings.setBuiltInZoomControls(true);

(14)扶助通过JS张开新窗口

settings.setJavaScriptCanOpenWindowsAutomatically(true);

(15)缩放至显示屏的轻重缓急

settings.setLoadWithOverviewMode(true);

(16)协助自动加载图片

settings.setLoadsImagesAutomatically(true);

Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);startActivity;

小说给前半部分相当多是方法的牵线,若嫌琐碎可径直拖到最终看代码演示。

WebView·驾驶指南

需求注意的地点

参照链接:安卓webview的局地坑

  1. webView.addJavascriptInterface()方法在API 17事先有局地纰漏(风乐趣的能够参见本篇小说,WebView 远程代码实施漏洞浅析),所以在API 17后头,要求在JavaScript接口类的格局加上@JavascriptInterface申明。

  2. 精心看的话你会发觉大家地点的WebView对象并非直接写在布局文件中的,而是经过二个LinearLayout容器,使用addview(webview)动态向个中增添的。其余部须求要静心创设webview须求利用applicationContext实际不是activity的context,销毁时不再占领activity对象,最终离开的时候要求立刻销毁webview,onDestory()中应超越从LinearLayout中remove掉webview,再调用webview.removeAllViews();webview.destory();

  3. 假设想要webView在产生OOM的时候不影响主进度,能够另开叁个进度,在androidmanifest.xml的activity标签里拉长Android:process属性就可以了。

  4. 在activity被杀死之后,依然维持webView的场馆,方便客商下一次张开的时候可以重回此前的动静。webview帮忙saveState(bundle)和restoreState(bundle)方法。

保存情状

@Override  
protected void onSaveInstanceState(Bundle outState) {  
    super.onSaveInstanceState(outState);  
    wv.saveState(outState);  
    Log.e(TAG, "save state...");  
}  

光复状态(在activity的onCreate(bundle savedInstanceState)里)

if(null!=savedInstanceState){  
    wv.restoreState(savedInstanceState);  
    Log.i(TAG, "restore state");  
}else{  
    wv.loadUrl("http://3g.cn");  
}  

别的部分大范围难点:

1. WebViewClient.onPageFinished()。
您永久不能鲜明当WebView调用那一个艺术的时候,网页内容是还是不是确实加载完成了。当前正值加载的网页发生跳转的时候这几个方法只怕会被反复调用,StackOverflow上有相比具体的分解(How to listen for a Webview finishing loading a UEscortL in Android?), 但个中列举的化解形式并不到家。所以当您的WebView需求加载丰富多彩的网页同一时候须要在页面加载成功时利用一些操作的话,恐怕WebChromeClient.onProgressChanged()比WebViewClient.onPageFinished()都要可信一些。
2. WebView后台功耗难题。
当您的顺序调用了WebView加载网页,WebView会自身展开一些线程(?),假若你未曾科学地将WebView销毁的话,这么些残余的线程(?)会直接在后台运营,由此导致您的应用程序功耗量有增无减。对此作者利用的管理形式相比偷懒,简单又强行(不建议),即在Activity.onDestroy()中一直调用System.exit(0),使得应用程序完全被移出设想机,那样就不会有其余难点了。
3. 切换WebView闪屏难点。
假定你须求在同四个ViewGroup中来回切换不一致的WebView(包罗了不相同的网页内容)的话,你就能够开掘闪屏是不可反败为胜的。那应当是Android硬件加快的Bug,假设关闭硬件加快这种气象会好广大,但不能够获取很好的浏览体验,你会以为网页滑动的时候一卡一卡的,不顺手
4. 在一些手提式有线电话机上,Webview有录像时,activity销毁后,摄像财富未有被销毁,乃至还是可以听到在后台播放。即就是像刚刚那样各样销毁webview也行不通,消除办法:在onDestory此前修改url为空地址。
5.WebView硬件加速导致页面渲染闪烁难题
有关Android硬件加快 开头于Android 3.0 (API level 11),开启硬件加速后,WebView渲染页面越来越高效,拖动也特别顺滑。但有个副成效正是便于会现出页面加载白块同期分界面闪烁现象。消除这些标题的主意是设置WebView一时半刻关张硬件加快代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

本文由胜博发-编程发布,转载请注明来源:不过它的API却没有很大的改动,这一改动大大提