1 Android加载HTML页面
1.1 WebView简介与使用
- Webview的应用场景
WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理,主要用于html页面的加载。
- WebView的使用步骤
(1) 在xml布局中创建对应的webview控件
image001.jpg
(2) 代码中通过findViewByid找出对应的控件
image002.jpg
(3) Webview通过地址URL加载网页
// 1. 直接加载一个网页
webview.loadUrl(“http://baidu.com”);
注意:采用上面的方式加载网页,系统会重新打开浏览器加载网页,用户体验不好,需要进行以下设置
//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放入其中,如下图所示:
image003.jpg
// 加载本地的网页
webview.loadUrl(“file:///android_asset/webview.html”);
(5) WebView直接加载html代码的两种方式
image004.jpg
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指向的路径来加载页面,这样就解决了历史记录问题
2 HTML与原生Android交互
2.1 HTML页面调用java中的方法
案例以本地的HTML页面为例进行讲解
(1) 在Android中创建供js调用的类和方法
image005.jpg
(2) 在加载网页的时候需要进行相应的设置
image006.jpg
(3) 在js中调用Android中方法的方式
在js中通过myObj调用本地的方法
image007.jpg
2.2 Android中调用HTML中的js代码
image008.jpg
注意:以上方法能够调用的前提是webview已经把对应的网页加载进来了
Js中对应的方法如下:
image009.jpg
3 WebView常用方法细节剖析
3.1 给webView添加header信息的方式
复写loadUrl()方法
@Override public void loadUrl(String url) {
Map<String, String> map = new HashMap<String, String>();
map.put("ajax", "true");
map.put("appversion", SharedPreferencesUtil.getAppVersion(getContext()));
map.put(“clientid”, SharedPreferencesUtil.getClientId(getContext()));
loadUrl(url, map);
}
3.2 Websettings详解
- 打开网页时不调用系统浏览器, 而是在本WebView中显示:
mWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
- 通过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");
- 按返回键时, 不退出程序而是返回上一浏览页面:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
- 打开页面时,自适应屏幕:
WebSettings webSettings = mWebView .getSettings();
webSettings.setUseWideViewPort(true);//设置此属性,可任意比例缩放
webSettings.setLoadWithOverviewMode(true);
- 页面支持缩放:
WebSettings webSettings = mWebView .getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
6.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。
webview.requestFocusFromTouch();
3.3 WebviewClient方法详解
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("www.example.com")) {
// 内部网址,不拦截,用自己的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)
// 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
3.4 WebCromeClient方法详解
1、onProgressChanged(WebView view, int newProgress)
通知Application的加载进度,newProgress取值范围[0,100],可以通过这个方法来编写一个带加载进度条的Webview
2、onReceivedTitle(WebView view, String title)
当加载页面标题有改变时会通知Application,title即为新标题。
4 Android studio中打包MUI项目
- 使用HBuilder创建一个web app的项目,如下图:
image010.png
-
在Android studio中新建一个项目
-
去官网下载对应的html5+sdk
-
将HBuilder项目拷贝到Android studio中的assets文件夹中
image011.jpg
image012.jpg
- 接下来需要将打包所用到的jar包和配置文件从下载的5+SDK中拷贝到Android studio里面
注意:jar包拷贝到libs文件夹下面,在 assets目录下新建一个data文件夹,并将对应的配置文件拷贝过去,更改配置文件中的appid;
从下载的5+SDK中的sdk文件夹下的libs中拷贝相应的jar包到Android studio中
image013.jpg
将5+sdk包中的HBuidler-Integrate下assetsàdata目录中的配置文件全部包拷贝到studio中assets目录下的data目录中更改一下文件名,如下图所示.
image014.jpg
修改control.xml中的appid与hbuilder中的一致
image015.png
将5+sdk下面HBuidler-Integrate-àres下的所有文件拷贝到studio中的res文件夹下,主要是mui项目转换为Android项目后的一些资源文件;
image016.png
拷贝HBuidler-Integrate-à src\com\HBuilder\integrate目录下的SDK_WebApp到对应的studio项目的包下面作为项目的入口Activity,这个时候还需要拷贝HBuilder-Integrate\src下的io包到studio的java目录下,如图所示:
image017.jpg
修改AndroidMnifest.xml配置文件的入口Activity和相应的权限
<?xml version="1.0" encoding="utf-8"?> <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" />
运行程序即可,现在就已经把HBuilder的项目转换为原生的Android项目打包结构
转自 http://learnfuture.com/article/1758