zoukankan      html  css  js  c++  java
  • Android WebView 详解

    一、缓存:
    在assets文件夹下添加index.html,里面有一个img标签获取图片!

    <img alt="图片"
    src="https://images0.cnblogs.com/blog/391137/201304/18081911-50a2631f6af343d5b3444cb0e0454ff9.jpg">

    MainActivity:

    public class MainActivity extends Activity {
        private WebView webview;
        private static String url = "file:///android_asset/index.html";
    
        public void getcache(View v) { // 点击获取缓存数据
            ImageView iv = new ImageButton(MainActivity.this);
            iv.setImageBitmap(getPictureFromCache());
            Dialog dig = new Dialog(MainActivity.this);
            dig.setTitle("图片");
            dig.setContentView(iv);
            dig.show();
        }
    private Bitmap getPictureFromCache() { Bitmap bitmap = null; File file = new File(getCacheDir() + "/webviewCacheChromium/f_000001"); try { FileInputStream ins = new FileInputStream(file); bitmap = BitmapFactory.decodeStream(ins); } catch (FileNotFoundException e) { e.printStackTrace(); } return bitmap; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webview = (WebView) findViewById(R.id.webview); webview.loadUrl(url); } }

    第一次打开应用之后可以看到File Explorer中cache文件夹下多了一些文件;

    getPictureFromCache()方法中地址来源:getCacheDir()方法返回cache文件夹,通过index.html页面中的图片地址获取图片知道图片大小为57159kb,对应的数据即为/webviewCacheChromium/f_000001

    二、WebView使用简单设置

        private void setSettings() {
            WebSettings settings = webview.getSettings();
            settings.setJavaScriptEnabled(true);// 这样网页就可加载JavaScript了
            settings.setJavaScriptCanOpenWindowsAutomatically(true);
            webview.setWebViewClient(new WebViewClient());// 设置点击网页中的链接不会打开android内置的浏览器,默认情况下点击链接会打开android内置的浏览器
            settings.setBuiltInZoomControls(true);// 显示放大缩小按钮
            settings.setSupportZoom(true);// 允许放大缩小
            settings.setSupportMultipleWindows(true);
        }

    WebView在默认情况下会记录访问过的page,这样可以实现访问过的网页的向前和向后浏览
    setWebViewClient时,可以自定义WebViewClient,重写里面的方法shouldOverrideUrlLoading

    private class MyWebViewClient extends WebViewClient {
         @Override
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
             if (Uri.parse(url).getHost().equals("blog.csdn.net")) {
                 // This is my web site, so do not override; let my WebView load the page
                 return false;
             }
             // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
             Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
             startActivity(intent);
             return true;
         }
    }

    有时候需要获取WebView所加载的网页的title,有什么方法能获取这个title呢,查看WebViewClient;

    发现并没有相关的方法;那么该如何实现?
    查看webView的其它方法?发现有个setWebChromeClient,它有两个相关的方法用于获取Title和Icon;

            webview.setWebChromeClient(new WebChromeClient(){
                @Override
                public void onReceivedTitle(WebView view, String title) { // 获取到Title
                    super.onReceivedTitle(view, title);
                }
    @Override
    public void onReceivedIcon(WebView view, Bitmap icon) { // 获取到图标 super.onReceivedIcon(view, icon); } });

    通过查看网上的相关资料,还有另一种可行的方法,此种方法需要用到js与webview的交互的技术,下面是一个例子;

        public void getTitle(WebView wv) {
            wv.addJavascriptInterface(new GetTitle(), "getTitle"); // 向webview注册一个本地接口
            wv.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageFinished(WebView view, String url) {
                    view.loadUrl("javascript:window.getTitle.onGetTitle("
                            + "document.getElementsByTagName('title')[0].innerHTML" + ");");
                    super.onPageFinished(view, url);
                }
            });
        }
    
        class GetTitle {
            public void onGetTitle(String title) {
                // ...参数title即为网页的标题,可在这里面进行相应的title的处理
            }
        }

     延伸思考:将上面document.getElementsByTagName('title')[0].innerHTML,将title换为其它的,就可以获取到其它的内容;

    三、WebView中应用HTML5
    WebView中应用HTML5主要有三种常用情况
    >>1.HTML5本地存储

            String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
            settings.setDatabaseEnabled(true);
            settings.setDatabasePath(dir);// 设置数据库路径
            settings.setDomStorageEnabled(true);// 使用LocalStorage则必须打开

    >>2.HTML5地理位置服务,需要在设置中进行设置,另外还需要重写WebChromeClient的允许获取地理位置的方法;

            settings.setGeolocationEnabled(true); // 启用地理定位
            settings.setGeolocationDatabasePath(dir); // 设置定位的数据库路径

    重写WebChromeClient的onGeolocationPermissionsShowPrompt方法,用于允许浏览器获取地下位置;

                @Override
                public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
                    super.onGeolocationPermissionsShowPrompt(origin, callback);
                    callback.invoke(origin, true, false);
                }

    下面是callback.invoke方法的描述

        /**一个允许让应用程序获取地理位置的接口
         */
        public interface Callback {
            /**
             * Sets the Geolocation permission state for the supplied origin.
             *
             * @param origin the origin for which permissions are set
             * @param allow 是否让origin也就是web站点获取地理位置
             * @param retain 是否保持此权限
             */
            public void invoke(String origin, boolean allow, boolean retain);
        };

    >>3.HTML5离线存储

            settings.setAppCacheEnabled(true);// 开启应用程序缓存
            String cache_dir = this.getApplicationContext().getDir("cache", Context.MODE_PRIVATE).getPath();
            settings.setAppCachePath(cache_dir);// 设置应用缓存的路径
            settings.setCacheMode(WebSettings.LOAD_DEFAULT);// 设置缓存的模式
            settings.setAppCacheMaxSize(1024 * 1024 * 8);// 设置应用缓存的最大尺寸
            settings.setAllowFileAccess(true);// 可以读取文件缓存(manifest生效)

    >>4.HTML5处理网页中的对话框,需要重写下面的三个方法,分别是{"警告","确认","提示"}

                @Override // 可以显示一个带确认的按钮并监听事件
                public boolean onJsAlert(WebView view, String url, String message,
                        JsResult result) {
                    return super.onJsAlert(view, url, message, result);
                }
    
                @Override // 可以显示一个带确定/取消按钮的对话框并监听用户的操作 
                public boolean onJsConfirm(WebView view, String url,
                        String message, JsResult result) {
                    return super.onJsConfirm(view, url, message, result);
                }
    
                @Override
                public boolean onJsPrompt(WebView view, String url, String message,
                        String defaultValue, JsPromptResult result) {
                    return super.onJsPrompt(view, url, message, defaultValue, result);
                }

    >>5.有时候希望使本地存储或离线存储的空间更大,需要扩展存储空间,需要重写WebChromeClient的onExceededDatabasseQuota方法;

                @Override
                public void onExceededDatabaseQuota(String url,
                        String databaseIdentifier, long quota,
                        long estimatedDatabaseSize, long totalQuota,
                        QuotaUpdater quotaUpdater) {
                    super.onExceededDatabaseQuota(url, databaseIdentifier, quota,
                            estimatedDatabaseSize, totalQuota, quotaUpdater);
                    quotaUpdater.updateQuota(estimatedDatabaseSize * 2); // 此方法扩展存储空间为默认的2倍
                }

    参考文章:
    1.html5 webview的本地存储优化
    2.android WebView加载html5介绍
    3.http://stackoverflow.com/questions/15768837/playing-html5-video-on-fullscreen-in-android-webview

  • 相关阅读:
    解决Tomcat无法shutdown进程
    ConcurrentHashMap Put()操作示例代码
    Spring Data JPA
    JAVA CAS原理
    多线程
    多线程
    java 虚拟机--新生代与老年代GC
    TCP协议中的三次握手和四次挥手
    java中volatile关键字
    Java多线程
  • 原文地址:https://www.cnblogs.com/a284628487/p/3162661.html
Copyright © 2011-2022 走看看