最近也是项目忙的差点不多了,偷点时间写写文章,反正把做的东西,感觉有那么点价值的东西分享出去,多交流交流! 带着几个小伙伴开发, 虽累但是挺开心,关键是公司够人性,老板为人到位!哈哈,,言归正传,
为什么取了这么个名字,也许大家最后不好找,但确实比较重要的部分!
现在我们开发移动 app 有这么几种情况:
1,webapp(H5+各种移动开发框架),开发工具像 hbuilder 之类,或者文本编辑之类的!
2,原生安卓开发(eclipse+android ADT 或者 android studio )
3,第三方开发工具(APIclould,wex5)
4,还有我们强大的 vs也可以开发,本人还没有试过
以上说到的是几种常见的app开发,情况,具体根据实际情况去选择,有时候觉得杀鸡焉用牛刀,那最简单是搞个 微信小程序!
开始准备,安卓开发环境 Java环境配置就不说了!
为什么说是桥接呢?
熟悉安卓的朋友都知道,安卓是通过注册活动页然后通过活动页上的启动的布局文件然后起大开页面的!
就像这个样子的
接下来我们看看name这个包(等同net里面的dll)下面的这个WelcomeActivity.java 这类文件
接下来,我们看看
实际上就是一个相对布局的图片视图,说白了就是图片控件,相对左上角布局。
好,到这里应该明白安卓启动页面的一个简单过程,那么问题来了
作为非全职的安卓开发人员,这方面的技术肯定是没有他们那么强悍的,尤其是复杂页面的布局,数据显示等,但是我们网页玩得熟悉,脚本写的好,那么有没有一种方式,让我们页面是html+js,我们不用安卓的xml布局,同意我们还能和后端Java代码交互呢?,想想都觉得很棒,答案是肯定的那么今天我前面做的项目就是这样实现的,效果还不错,为什么一定这么整,没办法啊, 后面还要接入安卓机器上的硬件部分!
问题来了,安卓是页面是xml的,网页是html 的,怎么显示上去呢,这里用到一个安卓的 WebView 控件,说白了就是一个 浏览器,肯定是谷歌内核啦。
首先加载启动页面
做到这里我们要利用webview把页面加载进来,代码如下
mWebView.loadData("", "summiapp/index.html", null);
mWebView.loadUrl("file:///android_asset/summiapp/index.html");
为了速度快一些,页面我是反正本地程序中,也快加载发布的网页
这里就可以正常显示了,还是跑起来给看一下吧
重点终于来了,点击登陆,怎么能够把点击事件获取的值传给后台Java,然后通过Java去发起数据请教调用写好的接口!(这个时候,会偷懒的家伙肯定就直接在页面上写ajax了,但是如果后要接入蓝牙,或者后要获gps,或者开启打印,兄弟你还是要和Java交互的哦),而且我通过Java去发起请求也是考虑了安全因素,不然谁愿意麻烦呢
开始接入
先看一下页面上的脚本,红色地方好像很奇怪
为什么可以这样调用,实际上是对webview做了配置,代码如下
注意: “webview 的客户端” 这块代码
// 加载浏览器(初始化)
@SuppressLint(“SetJavaScriptEnabled”)
public void initViews() {
mWebView = (WebView) findViewById(R.id.webView1);
// 页面编码
mWebView.getSettings().setDefaultTextEncodingName("utf-8");
mWebView.setWebChromeClient(new WebChromeClient());
// 设置背景色
// mWebView.setBackgroundColor(Color.rgb(96, 96, 96));
// webview 的客户端
mWebView.setWebViewClient(new WebViewClientDemo());
// 允许执行js
mWebView.getSettings().setJavaScriptEnabled(true);
// 防止出现空白
mWebView.getSettings().setBlockNetworkLoads(false);
mWebView.getSettings().setAllowFileAccess(true);
// 防止网页加载不全
mWebView.getSettings().setDomStorageEnabled(true);
// 关闭WebView中缓存
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 如果想要屏蔽长按只需要返回ture 即可,
mWebView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
return true;
}
});
// 返回按键
mWebView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& mWebView.canGoBack()) { // 表示按返回键
String url = mWebView.getUrl();
if (url.contains("login")) {
return true; // 已处理
} else {
// 时的操作
mWebView.goBack(); // 后退
// webview.goForward();//前进
return true; // 已处理
}
}
}
return false;
}
});
}
注意:onPageFinished这个方法
class WebViewClientDemo extends WebViewClient {
// 这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// 这里可以搞个加载的
showProgressDialog(MainActivity.this, "加载中。。");
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。
// 这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,
// 于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。
view.loadUrl(url);
return true;
}
// 在页面加载结束时调用。
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mWebView.addJavascriptInterface(new JsObject(), "lee"); // 脚本接口类
dismissProgressDialog(); // 关闭提示
}
}
仔细看就发现一步步的关联上了
// js对应操作类
class JsObject {
/**
* post请求方法 与get请求就只有发送数据的方式不同,不是明文传参,发送网络请求
*/
private String loginPost(String name, String passworld) {
String reString = "";
// 输入框非空验证
String strurl = "";
try {
URL url = new URL(strurl);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();// 打开连接
// conn.setRequestMethod("GET”);//设置请求方式,大写的GET
conn.setRequestMethod("POST");// 设置请求方式为POST
// 允许输入输入数据的设定,允许输入和输出,将数据date写入内存
conn.setDoInput(true);
conn.setDoOutput(true);
// 设置请求的头
String data = "{ \"Entry\": { \"LoginName\": " + name
+ ", \"Password\": " + passworld + " } }";
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Charset", "utf-8");
conn.setRequestProperty("Content-Length",
data.getBytes().length + "");
conn.setRequestProperty("AppID", "zhurui");
conn.setRequestProperty("AppKey", "123456");
// 将data数据写入内存
OutputStream os = conn.getOutputStream();
os.write(data.getBytes());
os.flush();// 刷新内存中的数据
// 获取请求结果
int code = conn.getResponseCode();
if (code == 200) {// 请求成功,返回请求结果码200,读取流结果 */
InputStream is = conn.getInputStream();// 获取流文件
InputStreamReader isr = new InputStreamReader(is);// 读取流文件
BufferedReader reader = new BufferedReader(isr);// 一次读一行
String line = "";// 定义空行用于追加内容
StringBuffer buffer = new StringBuffer();
while ((line = reader.readLine()) != null) {// 如果还没有读完
buffer.append(line);// 一直追加内容
}
// 关闭流,断开连接
reader.close();
conn.disconnect();
// 返回获取到的请求结果
return buffer.toString();
} else {
reString = "{ \"code\": \"1\"}";
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return reString;
}
注意页面创建 的方法生命允许脚本
关于前面的验证提示的toast调用也放出来吧
虽然很简单,但是还是要有点安卓和Java的底子,到这里这么一个简单的app登陆就搞定了,js调用Java也实现了,起到重要作用的是浏览器控件,其实在net里面也有,同时现在基于node出现的electron还可以通过写js之后生成exe程序,说的废话有些多,有需要可以给源码,我这个上面可以调用sunmi手持机打印功能和扫码功能,服务端程序自己可以去写个webapi或者websevers,总之程序无边,技术无界限,一通百通,欢迎指教!