WebView使用(内存泄露+获取网页标题+js交互+调用浏览器下载文件+网页加载失败+清缓存)

来源:互联网 发布:win7做mac启动盘 编辑:程序博客网 时间:2024/06/12 22:32

收集了几个比较常用的webview比较常用的功能,算是比较全了,开发一般需求应该是满足了的。注意一点就是网页加载失败、没有网络的情况下WebView会把加载的网页地址显示出来,貌似很多app都没有处理这点。。。


需要权限:

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

import android.content.Context;import android.content.Intent;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.webkit.CookieManager;import android.webkit.CookieSyncManager;import android.webkit.DownloadListener;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import com.zlc.utils.LogUtils;import com.zlc.utils.R;import java.io.File;public class WebViewActivity extends AppCompatActivity {    private WebView webView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_web_view);        webView = (WebView)findViewById(R.id.webView);        initConfig();        initLoad();    }    private void initConfig() {        WebSettings settings = webView.getSettings();        settings.setUseWideViewPort(true);//适配屏幕        settings.setLoadWithOverviewMode(true);        settings.setBuiltInZoomControls(false);//支持放大缩小,设置为true,要在Activity的ondestory方法中调用webView.setVisibility(View.GONE)        settings.setDisplayZoomControls(false);//隐藏放大缩小的按钮        settings.setDomStorageEnabled(true);//支持Html5标签        settings.setJavaScriptEnabled(true);//支持javascrip        webView.addJavascriptInterface(new JsCall(this), "test");//和JavaScript交互,CalledByJs是被javascript调用的类        webView.setWebViewClient(new MyWebViewClient());        webView.setWebChromeClient(new MyWebViewChromeClient());        webView.setDownloadListener(new DownloadListener() {            @Override            public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) {                //下载的url,调用浏览器下载                Intent intent= new Intent();                intent.setAction("android.intent.action.VIEW");                Uri uri = Uri.parse(url);                intent.setData(uri);                startActivity(Intent.createChooser(intent, "请选择浏览器"));            }        });    }    class MyWebViewChromeClient extends WebChromeClient {        @Override        public void onReceivedTitle(WebView view, String title) {            super.onReceivedTitle(view, title);            setTitle(title);            LogUtils.i("网页标题:" + title);        }    }    class MyWebViewClient extends WebViewClient {        @Override        public void onReceivedError(WebView view, int errorCode,                                    String description, String failingUrl) {            super.onReceivedError(view, errorCode, description, failingUrl);            //在这里进行加载错误、没有网络情况的处理            //方式1:加载一个本地的默认页面            //webView.loadData("file:///android_asset/refresh/refresh.html");            //方式2:显示一个默认布局            findViewById(R.id.tvError).setVisibility(View.VISIBLE);            webView.setVisibility(View.GONE);        }            // 自定义拦截        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            if(url!=null && !"".equals(url)){                if("拦截的网页".equals(url)){                    return true;                }else {                    return false;                }            }            return super.shouldOverrideUrlLoading(view, url);        }    }    private void initLoad() {        webView.loadUrl("http://blog.csdn.net/p522947409/article/details/53271525");//加载网络网页//        wvTest.loadData("file:///android_asset/refresh/refresh.html");//加载本地网页,或者直接传入副文本也可以//        webView.reload();//刷新当前页面    }    /**     * WebView清空缓存     */    public void clearCache(Context context) {        CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(context);        CookieManager cookieManager = CookieManager.getInstance();        cookieManager.removeAllCookie();        context.deleteDatabase("webview.db");        context.deleteDatabase("webviewCache.db");        context.deleteDatabase("webviewCookiesChromium.db");        context.deleteDatabase("webviewCookiesChromiumPrivate.db");        //WebView 缓存文件        File webviewCacheDir = new File(context.getCacheDir().getAbsolutePath()+"/webviewCacheChromium");        //删除webview 缓存目录        if(webviewCacheDir.exists()){//            deleteFile(webviewCacheDir);        }    }    @Override    public void onBackPressed() {        super.onBackPressed();        if(webView.canGoBack()){//返回上个页面            webView.goBack();        }else{            finish();        }//        if(webView.canGoForward()){//去刚才浏览的页面//            webView.goForward();//        }    }}import android.content.Context;import android.webkit.JavascriptInterface;import android.widget.Toast;//JavaScript代码://// function call(){//    test.callFromJs();// }// <img src="img/refreshicon.png" onclick="call()" alt="重新刷新" />class JsCall {    private Context mContext;    public JsCall(Context context){        this.mContext = context;    }     //在js中被调用的方法    @JavascriptInterface    public void callFromJs(){        Toast.makeText(mContext, "js调用啦~", Toast.LENGTH_LONG).show();    }}

----------------------------------------------------2016-12-14----------------------------------------------------------------------------------------

发现webview可能会导致内存泄露的问题,现在继续改进,关于webview的内存问题,有一篇算是国内比较元老级的博客https://my.oschina.net/zhibuji/blog/100580?p=1&temp=1481678574751,主要提供几种解决方案。

第一种方案:不在xml中加入webview,使用代码动态加入addView(webview),这种方法打开链接或者你打开的页面带有flash,获得你的WebView想弹出一个dialog,都会导致从ApplicationContext到ActivityContext的强制类型转换错误,从而导致你应用崩溃。。不能点击超链接,那有什么意义。果断不试这种方法

第二种方案:出现问题的原因还是不能删除引用的问题,解决办法是自己手动删除引用。涉及底层库代码,然后还有版本兼容的问题。。。继续往下看

第三种方案:应该算是最优方案了吧,新建进程,杀死进程,内存得到释放。意思是说你启动这个activity的时候要新建一个进程,等activity销毁时,结束这个进程。具体方法:在manifest.xml声明activity中声明新进程不在主UI线程中,android:process=":webview",在activity的ondestory中调用system.exit(0);(android:process使用本人参考了http://blog.sina.com.cn/s/blog_4c0706560101ncz4.html)。


----------------------------------------------------2016-1-4----------------------------------------------------------------------------------------

发现用webview直接加载www.baidu.com是加载不出来的,需要在前面加http://,具体原因有空再分析

if (!strUrl.startsWith("http://") && !strUrl.startsWith("https://"))
strUrl = "http://" + strUrl;


----------------------------------------------------2016-12-14----------------------------------------------------------------------------------------
0 0
原创粉丝点击