最近做了一段时间的前端工作,越发感觉用前端写界面要比Android写界面快得多。所以,在最近一个简单Android项目中,我使用WebView来显示一些简单的东西。这只是一次简单的尝试。在完成该项目后写下本博客总结下~
对前端的感受
- 调试方便,代码逻辑断点调试速度很快。能很快的发现问题解决问题。相比Android每次都要run或者debug一遍都需要花上几十秒(像我的渣电脑需要1-2分钟)快了很多。
- 处理网络连接方面的问题方便。相比于Volley、Retrofit这类库,我更喜欢ajax,一个原因是写起来简洁明了,另一个是查错误方便。
- 资源丰富。Android有它的那一套第三方开源库,而前端也有自己的各种第三方库。甚至要比Android的多很多。每当遇到问题,查查Google、Github和Stackoverflow基本都能找到解决方案。
- 框架。Vue、jQuery、React、Augular等等各种js框架,jQuery UI、Bootstrap等UI框架等等这些好东西绝对让人事半功倍。
所以,我喜欢上了用前端来写界面,并在Android APP中尝试混合开发。下面是我开发过程中遇到的问题和解决方法(思路比较乱,用问答的方式记录下~)。
前端页面放在哪里?
一开始我对除了Android外的技术知识一无所知,当我写完一个页面后发现我不知道如何将页面放到我手机上。
其实就是对后端的无知了。这里需要一台服务器来放前端页面。我们公司用的是IIS管理器,将前后端代码放在服务器上。在启动服务器后,WebView就可以通过(服务器地址)+(端口)+(路径)找到我们的页面了。所以如果想写前端页面能在手机中显示必须知道它的路径。
Android端如何与HTML端通信
由于网页中的dialog效果不好,想用Native的Dialog来做。于是有了这个问题。Google下找到了这篇文章,写的很全很详细。Android中Java和JavaScript交互
下面是我项目中的交互代码:
JS调用Android中的方法
Android
public class JsInteration {
@JavascriptInterface
public void dialogMessage(String message, final boolean endPage) {
new AlertDialog.Builder(context)
.setTitle("提示")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//TODO
}
}).show();
}
}
注意:别忘了将JsInteration对象添加到WebView中。
wvContent = findViewById(...);
wvContent.getSettings().setJavaScriptEnabled(true);
wvContent.addJavascriptInterface(new JsInteration(), "control");
JS
function dialogMessage (message, endPage) {
window.control.dialogMessage(message, endPage);
}
最后在HTML端就可以通过dialogMessage('保存成功', true)
函数来显示Android的AlertDialog
反过来顺便说下Android调用JS的方法
JS
function changeStartTime(time) {
this.StartTime = time;
}
Android
private void callChangeStartTime(final String time){
runOnUiThread(new Runnable() {
@Override
public void run() {
String call = "javascript:changeStartTime(\"" + time + "\")";
wvContent.loadUrl(call);
}
});
}
这样就可以在Android中使用callChangeStartTime("2016.10.27 14:16:43");
方法修改JS中的this.StartTime
参数。
在loadUrl时出现java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.
的问题怎么办?
就是说loadUrl没有在同一个线程中调用。Stackoverflow上找到了两个解决方法
mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(...).
}
});
private void callChangeStartTime(final String time){
runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(...);
}
});
}
两个方法应该都能很好的解决这一问题。
Android端在页面的时候如何向前端页面传递必要的数据?
通过URL字段的拼接。如locolhost:8888/home/index?account=jack&password=123
。如此就把页面所需的账户密码信息传递给HTML页面啦。当然,使用Android和JS的交互也能达到数据传递的目的。
Android如何判断网页加载是否失败
使用WebView来加载URL,在加载失败时会出现一个很丑的默认加载失败页面。我们需要知道是否加载失败并在加载失败后显示我们自己的加载失败页面。
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//super.onReceivedError(view, errorCode, description, failingUrl);
ToastUtil.showToast(context, "读取数据失败,请检查网络并重新扫描");
mWebView.loadUrl("file:///android_asset/default.html");
}
});
通过重写WebViewClient的onReceivedError
方法就可以实现这个目的。
Android如何加载本地HTML页面
HTML文件需要放到Assest文件夹中。而Android Studio的项目目录默认没有这个文件夹。所以我们需要新建一个文件夹并将HTML文件放进去。
新建Assest文件夹 右击项目 -> New -> Floder -> Assest Floder
HTML文件路径 mWebView.loadUrl("file:///android_asset/default.html");
项目的问题
- 页面的点击反馈不强,试着使用fastclick来解决,效果不明显~
- 对手机前端页面其实知之甚少。
- 试着用rn和weex来做这些东西。
暂时就这么多吧,之后学到新的东西再分享出来。