开始:
其实对Android我只是略知皮毛中的皮毛,但是为什么会突然想来要用Android WebView呢?哈哈,答案就是:之前写了一个ChinaNet登录的PC版(C#),于是应童鞋们要求,改成Android版的,可是哪有那么容易啊?于是我便毫无头绪的开始了。
过程:
大概从查资料,到做软件能登陆成功,一共用了6个小时(12:00-18:00)差不多,不过还是个BUG百出的程序。最开始是这样想的C#里面有Webbrowser 那么Android里面应该也要有个什么什么Browser吧,搜索后跑出来个新东东,WebView,大概看了下这个控件的功能,确定就是他了,Yes找到你了!so...开始工作了,WebView是Android里一个专门用来显示网页的控件,可以直接看成一个浏览器,只是缺少了交互。网上大多数文章都一模一样,这叫我怎么深入了解啊,我要的目的是自动试号啊,就是我有一堆可能能登上去的账号,让程序自动去登录这些账号。找了好久,大概这几篇文章有用,这里我就直接给链接了:
1.获取网页的源码,也涵盖了webview使用的大体程序结构(http://www.cnblogs.com/hibraincol/archive/2011/10/26/2224866.html)
2.WebViewClient里面的个个方法的功能解释(http://www.2cto.com/kf/201205/130261.html)
3.处理弹出对话框,自动识别点击对话框按钮(http://blog.csdn.net/llbupt/article/details/7368844)
当然我写的跟上面哪个都不一样,我把所用到的WebViewClient和WebChromeClient都独立出来用两个继承类。然后覆盖底下的方法。
webview 的几种使用形式:
1.webview.loadUrl(String );加载网址,可以是本地文件。
2.webviewclient里面的onPageFinished();网页加载完成,然后里面的进行对网页上控件进行赋值。实现账号、密码、开户地自动填写。
是怎么填进去的呢?明天说吧,熄灯了!(Javascript)
-----现在时间2013/10/10 6:41 ,起床接着写-----
说道了, javascript,(擦擦擦,完了,同学过来叫我去自习看英语,又不能写了,洗脸,走了,good bye)
自习中断,有点感冒不想自习了。
书回正题说到自动填写用户名密码,而之前提到了Javascript,如果是对JS使用比较熟练的自然不用我多说,应该已经知道做法了!其实很简单,就是拼接Javascript语句带入用户名密码并让浏览器执行Javascript,使用户名密码显示在浏览器中。这里给出文本框和调用原有Js方法的两个形式:
1. view.loadUrl(" javascript:document.getElementsByName('username')[0].value='"+ username + "'");
2. view.loadUrl("javascript:checkOtherForm()");
ps:这里补充一句,我在网上查了好久,基本上只有这种方法可以对网页内容进行修改,如果网友们有什么新的方法,麻烦告知Me一下。谢过!(Post封装方法说实话,我做不来。各种Js验证有木有啊亲,鬼知道Js里面写的啥。)
问题分析:
因为程序的设计存在很多问题,并且不清楚webviewclient里面的事件调用机制,所以这里最后我说下我未能解决的问题。
严重问题1:
shouldOverrideUrlLoading()方法里面调用了view.loadUrl(url);但是这个只是为了让跳转的页面的显示在webview控件上,而不是用系统默认的浏览器打开。(我是这样理解的。)
shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;//表示要在当前webview下打开这个链接url
}
我在onPageStarted()方法里面这样判断的:
if (url.contains("telecom/mobile/ jsp/mobilelogin. jsp"))
{
view.loadUrl("https://wlan.ct10000.com/telecom/mobile/jsp/otherlogin.jsp");
}
在onPageFinished()是这样:
if (url.contains("telecom/mobile/jsp/otherlogin.jsp"))
{
//自动填信息
//提交表单
}else if(url.contains("index.jsp"))
{
//登陆成功
}
随之,问提就出现了,当页面跳转一个链接时 ,先进入了shouldOverrideUrlLoading()执行了一次view.loadUrl(),之后会进入onPageStarted()如果if条件成立的话,又会执行一次webview.loadUrl(url)。此时当前的url是otherlogin.jsp,又会再次来到shouldOverrideUrlLoading()中load(url),导致执行了两次loadUrl(otherlogin.jsp),访问了两次这个链接,而且第一次load时间和第二次过于紧密,以至于,第一次被第二次界面刷新替换掉(看不出来其实界面跳转了两次),但是onPageFinished()里面确实执行了两次,以至于,提交了两次表单,而第一次还没来得急 服务器确认,就跳到了第二次提交表单。试号的话会有一半的号没有被试。
严重问题2:
之前提到,为了让各个功能分离开来,我把一些类独立出来WebViewClient和WebChromeClient还有一个封装账号密码的生成numlist的类MyOption用的是静态方法。
public class MyWebViewClient extends WebViewClient
{
private MainActivity activity;
private List<Num> list;
private int count;
public void countSub(int i)
{
this.count -=i;
}
public MyWebViewClient(MainActivity activity)
{
this.activity= activity;
this.list = MyOption.getNumList();//获取numlist
count = 0;
}
//下面是覆盖webviewcilent里面的事件方法...
}
从上面代码可以看出,为了方便的在webviewclient的事件里面对Activity 进行控制,所以干脆将Activity作为一个成员变量在MyWebViewClient实例化时通过构造方法传进来。我清楚地知道这样设计是不好滴,为啥呢?因为webView加载了处理事件的WebViewClient(这里为什么这样用,有待研究。)同时,webView又是Activity底下的成员变量,Activity反过来却又成了WebViewClient底下的成员变量,这是不是有点循环堆栈的意思啊?So...用来处理弹窗的类WebChromeClient也是这样设计的。
小问题:
我就直接都说下吧,就是一些小瑕疵:
1.Activity主界面WebView网页位置不适当问题。
2.显示登陆/试号信息的TextView位置,就文本对齐,字体颜色,都不好看。
3.直接退出程序,并不会断开ChinaNet的连接,应该在退出程序前,自动点击一下断开网络。
4.手机加载网页速度不是特别快,所以之前用view.goBack()方法试号也连接上了,但是由于网站有验证信息问题,所以这个最后考虑实现吧。
5.界面不友好,功能有限。(学弟提的意见,汗。。。)
结束:
说是结束,其实是未完待续,用昨晚看李开复的《世界因你而不同》里面的一句话做结束语:
Lead your life Not Live your life。