Android 开发内嵌H5的设置,稳定性,问题

1.资源文件已经部署到服务器上,直接请求服务器内的资源。

2.项目中的资源(也叫本地资源),html的展示所需源基本都在本地的源文件中。as一般放置于assete内。

 

//加载assets目录下的test.html文件

webView.loadUrl("file:///android_asset/test.html");

//加载网络资源(注意要加上网络权限)

webView.loadUrl("http://blog.csdn.net");

 

使用Android webView的基本设置

WebSettings webSettings = mWebView.getSettings();

//设置是否支持缩放

webSettings.setSupportZoom(true);

webSettings.setBuiltInZoomControls(true);

//设置是否显示缩放按钮

webSettings.setDisplayZoomControls(true);

 

//设置WebView是否允许执行JavaScript脚本,默认false,不允许

webSettings.setJavaScriptEnabled(true);

 

//设置自适应屏幕宽度

webSettings.setUseWideViewPort(true);

webSettings.setLoadWithOverviewMode(true);

//设置布局,会引起WebView的重新布局(relayout),默认值NARROW_COLUMNS

webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

//设置WebView的用户代理字符串。如果字符串为null或者empty,将使用系统默认值。

// 注意从KITKAT版本开始,加载网页时改变用户代理会让WebView再次初始化加载

String versionName = AppUtils.getInstance().getVersionName();

String userAgent =webSettings.getUserAgentString();

webSettings.setUserAgentString(userAgent.replace("Android", "sander/" + versionName + "/Android"));

//如果用户设置了WebViewClient,则在点击新的链接以后//就不会跳转到系统浏览器了,而是在本WebView中显示。

//主要用来辅助WebView处理各种通知、请求等事件

mWebView.setWebViewClient(new MyWebViewClient(mWebView));

mWebView.setDefaultHandler(new DefaultHandler());

//主要用来辅助WebView处理Javascript的对话框、网站//图标、网站标题以及网页加载进度等。

mWebView.setWebChromeClient(new MyWebChromeClient());

//设置cookie

setCookie(shareUrl);

//加载链接

mWebView.loadUrl(shareUrl);

//调用WebView的addJavaScriptInterface(Object object, String name)方法将object对象暴露给JavaScript脚本;

//     /**

//     * 暴露给JavaScript的接口

//     * @param content

//     */

//    @JavascriptInterface

//    public void showToast(String content){

//        Toast.makeText(context,content,Toast.LENGTH_SHORT).show();

//    }

//在JavaScript脚本中将通过上一步暴露的name对象调用Android方法;

// <input onclick="testJavaScript.showToast('测试')"/>

webView.addJavascriptInterface(new TestJavaScript(MainActivity.this),"testJavaScript");

 

// 点击手机上的返回,返回前一个页面

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

   if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {

       mWebView.goBack();

       return true;

   }

   return super.onKeyDown(keyCode, event);

}

 

private void setCookie(String url) {

    if (SpCache.getSession() != null) {

        String cookies = "accessToken=" + SpCache.getSession().getToken();

        CookieSyncManager.createInstance(this);

        CookieManager cookieManager = CookieManager.getInstance();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            cookieManager.setAcceptThirdPartyCookies(mWebView, true);

        } else {

            cookieManager.setAcceptCookie(true);

        }

        cookieManager.setCookie(url, cookies);

        CookieSyncManager.getInstance().sync();

    }

}

 

 

WebView可以很好地帮助我们展示html页面,但是webview使用不当的话还是可能产生一定问题的,下面就以下几个方面说说优化技巧

1、展示webview的activity可以另开一个进程,这样就能和我们app的主进程分开了,即使webview产生了oom崩溃等问题也不会影响到主程序,如何实现呢,其实很简单,在androidmanifest.xml的activity标签里加上android:process="packagename.web"就可以了。运行起来就会发现多了一个进程,哈哈。

2、webview的创建也是有技巧的,最好不要在layout.xml中使用webview,可以通过一个viewgroup容器,使用代码动态往容器里addview(webview),这样可以在onDestory()里销毁掉webview及时清理内存,另外需要注意创建webview需要使用applicationContext而不是activity的context,销毁时不再占有activity对象,这个大家应该都知道了,最后离开的时候需要及时销毁webview,onDestory()中应该先从viewgroup中remove掉webview,再调用webview.removeAllViews();webview.destory();

创建

ll = new LinearLayout(getApplicationContext()); 
ll.setOrientation(LinearLayout.VERTICAL);
wv = new WebView(getApplicationContext());

销毁

 @Override
protected void onDestroy() {
    ll.removeAllViews();
    wv.stopLoading();
    wv.removeAllViews();
    wv.destroy();
    wv = null;
      ll = null;
    super.onDestroy();
}

3、进一步的优化,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 URL in Android?), 但其中列的解决方法并不完美。所以当你的WebView需要加各种各的网并且需要在面加完成采取一些操作的,可能WebChromeClient.onProgressChanged()WebViewClient.onPageFinished()都要靠一些。
  2. WebView后台耗电问题。当你的程序用了WebViewWebView会自己开启一些线程(?),如果你没有正确地将WebView销毁的话,这些残余的线程(?)会一直在后台运行,由此导致你的应用程序耗电量居高不下。对此我采用的处理方式比较偷懒,简单又粗暴(不建议),即在Activity.onDestroy()中直接System.exit(0),使得用程序完全被移出虚机,这样就不会有任何问题了。
  3. WebView闪屏问题。如果你需要在同一个ViewGroup中来回切不同的WebView(包含了不同的网内容)的,你就会发现闪屏是不可避免的。这应该是Android硬件加速的Bug,如果关硬件加速种情况会好很多,但无法得很好的浏览,你会感候一卡一卡的,不跟手。
  4. 数据问题。开启存什么的有利于网浏览,但你会发现即使是清除了必要的内容,比如CacheCookieForm DataHistoryPassword等等西,你的用程序所占用的存间还是会越来越大,到最后只好手到系统设置的用信息界面里清除数据了 :(
  5. 滚动条问题Android System WebView的横向滚动条真是好粗的有木有...
  6. 在某些手机上,Webview视频时activity销毁后,视频资源没有被销毁,甚至还能听到在后台播放。即便是像刚才那样各种销毁webview也无于事,解决法:在onDestory之前修改url为空地址。是不是很坑

猜你喜欢

转载自blog.csdn.net/u014434239/article/details/81948083