分类: Android平台
2017-12-07 15:41:22
1. Webview的应用场景
WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理,主要用于html页面的加载。
2. WebView的使用步骤
(1) 在xml布局中创建对应的webview控件
(2) 代码中通过findViewByid找出对应的控件
(3) Webview通过地址URL加载网页
// 1. 直接加载一个网页 webview.loadUrl(""); 注意:采用上面的方式加载网页,系统会重新打开浏览器加载网页,用户体验不好,需要进行以下设置 //2.处理跳转打开新的浏览器的问题setWebViewClient
webview.setWebViewClient(
new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//3.告诉系统不要打开新的浏览器了自己处理页面
return true;
}
}
);
//4.网页控件默认不支持JavaScript 需要用户打开支持的开关
webview.getSettings().setJavaScriptEnabled(true);
//5.网页控件默认不支持弹出框 alert() prompt() confirm()...
// 但是Html5的弹出框是默认支持的設置setWebChromeClient
webview.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
});
}
|
(4) WebView加载本地html页面
首先需要在Android项目的src—main包下面创建assets文件夹,将对应的html放入其中,如下图所示:
// 加载本地的网页
webview.loadUrl("file:///android_asset/webview.html");
|
(5) WebView直接加载html代码的两种方式
LoadData与LoadDataWithBaseURL的区别是什么?
两个方法加载的HTML代码片段有些不同,loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,这就为内嵌css等制造了些许麻烦,因为css中经常用'#', '%'等字符,需要用UrlEncoder编码为%23, %25, %27, %3f
在使用loadDataWithBaseURL时,需要注意的就是 baseUr:虽然API上写的是要传一个Url,但我在用时,发现传一个Url并不可以,我发现这个就是一个标志位,用来标志当前页面的Key值的,而historyUrl就是一个value值,在加载时,它会把baseUrl和historyUrl传到List列表中,当作历史记录来使用,当前进和后退时,它会通过baseUrl来寻找historyUrl的路径来加载historyUrl路径来加载历史界面,需要注意的就是history所指向的必须是一个页面,并且页面存在于SD卡中或程序中(assets),loadDataWithBaseURL,它本身并不会向历史记录中存储数据,要想实现历史记录,需要我们自己来实现,在加载页面时,把数据另外的写到一个html页面中,并把它保存到SD中,当点击返回时,它会通过historyUrl指向的路径来加载页面,这样就解决了历史记录问题
案例以本地的HTML页面为例进行讲解
(1) 在Android中创建供js调用的类和方法
(2) 在加载网页的时候需要进行相应的设置
(3) 在js中调用Android中方法的方式
在js中通过myObj调用本地的方法
注意:以上方法能够调用的前提是webview已经把对应的网页加载进来了
Js中对应的方法如下:
复写loadUrl()方法 @Override public void loadUrl(String url) {
Map map.put("clientid", SharedPreferencesUtil.getClientId(getContext())); loadUrl(url, map); } |
1. 打开网页时不调用系统浏览器, 而是在本WebView中显示: mWebView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });
2. 通过java代码调用javascript WebSettings webSettings = mWebView .getSettings(); webSettings.setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new Object() { public void clickOnAndroid() { mHandler.post(new Runnable() { public void run() { webview.loadUrl("javascript:wave()"); } }); } }, "demo");
3. 按返回键时, 不退出程序而是返回上一浏览页面: public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); }
4. 打开页面时,自适应屏幕: WebSettings webSettings = mWebView .getSettings(); webSettings.setUseWideViewPort(true);//设置此属性,可任意比例缩放 webSettings.setLoadWithOverviewMode(true);
5. 页面支持缩放: WebSettings webSettings = mWebView .getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setBuiltInZoomControls(true); webSettings.setSupportZoom(true);
6.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。 webview.requestFocusFromTouch(); |
WebviewClient常用方法: 1、shouldOverrideUrlLoading(WebView view, String url) 在API 24以后过时,当一个url即将被webview加载时,给Application一个机会来接管处理这个url,方法返回true代表Application自己处理url;返回false代表Webview处理url。举个例子,项目中需要处理传过来的URL是一个事件还是一个HTTP链接,可以通过自定义协议头 (nativeapi://) 来过滤,如: @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Uri uri = Uri.parse(url); String scheme = uri.getScheme(); if (TextUtils.isEmpty(scheme)) return true; if (scheme.equals("nativeapi")) { //如定义nativeapi://showImg是用来查看大图,这里添加查看大图逻辑 return true; } else if (scheme.equals("http") || scheme.equals("https")) { //处理http协议 if (Uri.parse(url).getHost().equals("")) { // 内部网址,不拦截,用自己的webview加载 return false; } else { //跳转外部浏览器 Intent intent = new Intent(Intent.ACTION_VIEW, uri); context.startActivity(intent); return true; } } return super.shouldOverrideUrlLoading(view, url); } 注:如果使用的是Post请求方式,则此方法不会被回调 2、shouldOverrideUrlLoading(WebView view, WebResourceRequest request)在API 24以后新加的,使用同上。 3、shouldInterceptRequest(WebView view, String url) 在API 21以后过时,通知Application加载资源的请求并返回请求的资源,如果返回值是Null,Webview仍然会按正常加载资源;否则返回的数据将会被使用 注:回调发生在子线程中,不能直接进行UI操作 4、shouldInterceptRequest(WebView view, WebResourceRequest request) 在API 21以后新加,使用同上 5、onPageStarted(WebView view, String url, Bitmap favicon)通知Application页面已经开始加载资源,页面加载过程中,onPageStarted至多会被执行一次 6、onPageFinished(WebView view, String url) 通知Application页面已经加载完毕 7、onReceivedError(WebView view, int errorCode, String description, String failingUrl) 通知Application有错误发生,这些错误是不可恢复的(即主要的资源不可用)。errorCode参数对应于一个ERROR_ *常量 8、shouldOverrideKeyEvent(WebView view, KeyEvent event)
//重写此方法才能够处理在浏览器中的按键事件。
9、doUpdateVisitedHistory(WebView view, String url, boolean isReload)
//(更新历史记录)
10、onLoadResource(WebView view, String url)
// 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
|
1、onProgressChanged(WebView view, int newProgress) 通知Application的加载进度,newProgress取值范围[0,100],可以通过这个方法来编写一个带加载进度条的Webview 2、onReceivedTitle(WebView view, String title) 当加载页面标题有改变时会通知Application,title即为新标题。 |
1. 使用HBuilder创建一个web app的项目,如下图:
2. 在Android studio中新建一个项目
3. 去官网下载对应的html5+sdk
4. 将HBuilder项目拷贝到Android studio中的assets文件夹中
5. 接下来需要将打包所用到的jar包和配置文件从下载的5+SDK中拷贝到Android studio里面
注意:jar包拷贝到libs文件夹下面,在 assets目录下新建一个data文件夹,并将对应的配置文件拷贝过去,更改配置文件中的appid;
从下载的5+SDK中的sdk文件夹下的libs中拷贝相应的jar包到Android studio中
将5+sdk包中的HBuidler-Integrate下assetsàdata目录中的配置文件全部包拷贝到studio中assets目录下的data目录中更改一下文件名,如下图所示.
修改control.xml中的appid与hbuilder中的一致
将5+sdk下面HBuidler-Integrate-àres下的所有文件拷贝到studio中的res文件夹下,主要是mui项目转换为Android项目后的一些资源文件;
拷贝HBuidler-Integrate-à src\com\HBuilder\integrate目录下的SDK_WebApp到对应的studio项目的包下面作为项目的入口Activity,这个时候还需要拷贝HBuilder-Integrate\src下的io包到studio的java目录下,如图所示:
修改AndroidMnifest.xml配置文件的入口Activity和相应的权限
xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
package="com.zwj.muiorandroid">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SDK_WebApp">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
manifest>
|
运行程序即可,现在就已经把HBuilder的项目转换为原生的Android项目打包结构