图解为网站开发Android客户端
![](http://www.apkbus.com/data/attachment/forum/201111/29/100142wi7owzbdipoizddi.png)
这是一个简单的示意图,告诉我们,数据是由网页从数据库中取出,我们要为这个系统做客户端,我们就应该这样去改造它。
![](http://www.apkbus.com/data/attachment/forum/201111/29/10014339ojlyc0uw39kyl9.png)
![](http://www.apkbus.com/data/attachment/forum/201111/29/100149vs4ppclshksvmpsc.png)
![](http://www.apkbus.com/data/attachment/forum/201111/29/100321o5377rr75bj3p711.png)
所以我继续找,经过短暂的观察,发现入口在这里
![](http://www.apkbus.com/data/attachment/forum/201111/29/100259af2ofoaafab2aorr.png)
![](http://www.apkbus.com/data/attachment/forum/201111/29/1003279t9xg0kceqqfjrg1.png)
![](http://www.apkbus.com/data/attachment/forum/201111/29/1003331p6e8qpqzl6vjj1j.png)
![](http://www.apkbus.com/data/attachment/forum/201111/29/100336lee3bw26nbneb8cb.png)
我们先看Summary选项卡,我们可以初步了解,这是一个POST请求(Http请求中的一种,另一种是GET),POST到的网址是 http://coin.lib.scuec.edu.cn/cgi-bin/IlaswebBib 。
这样我们的思路就清晰了,我们的客户端需要模拟浏览器,向上述地址POST一个包,那个地址肯定会返回一个Content给我们,不出意外的话,Content里面就是我们要的书目信息。那么,浏览器POST上去的内容是什么呢?我们点击这条POST请求,看详细信息,
![](http://www.apkbus.com/data/attachment/forum/201111/29/100350znhx55x7anh5q5pn.png)
由于是POST请求,我们先看POST DATA,里面是以键值对的形式存储的,这里显示了我们浏览器在我们搜索”android”时,POST的所有数据。那这些键值对又代表了什么呢,我们打开这个网页的源码来一探究竟。
![](http://www.apkbus.com/data/attachment/forum/201111/29/100352xqs4zyhx9xuqauoa.png)
从这段可以看出v_index是表示查找途径的它有TITLE,AUTHOR,SUBJECT,CLASSNO,ISBN,CALLNO六种值
![](http://www.apkbus.com/data/attachment/forum/201111/29/100354bgowoic693ztozez.png)
FLD_DAT_BEG和FLD_DAT_END分别是开始和结束年份
![](http://www.apkbus.com/data/attachment/forum/201111/29/100355v1z9ur9pve7oo1lo.png)
v_value表示用户在搜索框中输入的内容
![](http://www.apkbus.com/data/attachment/forum/201111/29/1003568332z1wa2y3222al.png)
v_paggnum表示每页显示的书目条数,有10 15 20三种
![](http://www.apkbus.com/data/attachment/forum/201111/29/10035649uuhui4eqz29ei9.png)
v_seldatabases是检索库 有0 1 2三种值v_LogicSrch是检索方式 有0 1两种值
![](http://www.apkbus.com/data/attachment/forum/201111/29/1003577czopiinnnznc112.png)
Submit是查询或重填,有 查 询 和 重 填 两种值
至此,我们弄清楚了POST Data里所有内容的含义和取值可能。但我们模拟POST请求为什么,其实就是为了得到搜索的书目信息,所以我们看一下返回的Content是不是我们要的东西
![](http://www.apkbus.com/data/attachment/forum/201111/29/1004045virm7gv25apdqzq.png)
果然,就是我们搜到的书目信息,就以String的形式放在Content里面。最后我们查看一下Stream,截图,以防等下我们需要这里面的东西
![](http://www.apkbus.com/data/attachment/forum/201111/29/100428k7382nlnk8qq8sqz.png)
好了,这个页面的工作原理我们已经弄清楚了:用户在网页中输入搜索内容后,点击查询,浏览器会POST一个Data到目标网址,该网址的返回信息就是搜到的书目。
我们开始编写代码,模拟这个过程,先打开eclipse建立一个Java项目(注意是Java项目,因为Java项目可以完美移植到Android项目中且调试方便,并且模拟Http请求这一过程没有用到任何Android功能)。
导入HttpClient的4个包commons-codec、commons-httpclient、commons-logging、log4j。
- //实例化HttpClient
- HttpClient client = new HttpClient();
- //Stream页面里面有Host地址 端口是80
- client.getHostConfiguration().setHost("http://coin.lib.scuec.edu.cn", 80);
- //用目标地址 实例一个POST方法
- PostMethod post = new PostMethod("http://coin.lib.scuec.edu.cn/cgi-bin/IlaswebBib");
- //将需要的键值对写出来
- NameValuePair beg = new NameValuePair("FLD_DAT_BEG" , “”);
- NameValuePair end = new NameValuePair("FLD_DAT_END" , “”);
- NameValuePair submit = new NameValuePair("submit" , "查 询"));
- NameValuePair vIndex = new NameValuePair("v_index" , “TITLE”);
- NameValuePair vLogicSrch = new NameValuePair("v_LogicSrch" , "0");
- NameValuePair vPagenum = new NameValuePair("v_pagenum" , "10");
- NameValuePair vSeldatabase = new NameValuePair("v_seldatabase" , "0");
- NameValuePair vValue = new NameValuePair("v_value" ,”android”);
- //给POST方法加入上述键值对
- post.setRequestBody(new NameValuePair[] {beg , end , submit , vIndex , vLogicSrch , vPagenum , vSeldatabase , vValue});
- //执行POST方法
- client.executeMethod(post);
- //将POST返回的数据以流的形式读入,再把输入流流至一个buff缓冲字节数组
- //StreamTool类是我自己写的一个工具类,其内容将在下文附出
- byte[] buff = StreamTool.readInputStream(post.getResponseBodyAsStream());
- //将返回的内容格式化为String存在html中
- String html = new String(buff);
- //任务完成了,释放连接
- post.releaseConnection();
复制代码
- //StreamTool类如下
- public class StreamTool {
- /**
- * 从输入流中获取数据
- * @param inputStream 输入流
- * @return 字节数组
- * @throws Exception
- */
- public static byte[] readInputStream(InputStream inputStream) throws Exception
- {
- //实例化一个输出流
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- //一个1024字节的缓冲字节数组
- byte[] buffer = new byte[1024];
- int len = 0;
- //读流的基本知识
- while ((len=inputStream.read(buffer)) != -1) {
- outputStream.write(buffer, 0, len);
- }
- //用完要关,大家都懂的
- inputStream.close();
- return outputStream.toByteArray();
- }
- }
复制代码
现在,我们得到了POST方法返回的String,我们输出到控制台看看是什么
- System.out.println(html);
复制代码
![](http://www.apkbus.com/data/attachment/forum/201111/29/100416vycoy75588oy6kz6.png)
没错,就是我们上文看到的HttpWatch 抓到的返回Content,也就是一段HTML代码,这说明,我们模拟浏览器POST请求成功了!
我们再试试别的搜索内容,来一个” Android开发 ”(即将v_value键值对的值改成”android开发”),这时运行后,我们却从控制台得到了这样的结果:
![](http://www.apkbus.com/data/attachment/forum/201111/29/1004175hyg9o0p5ggz8mfs.png)
经过几次试验后,发现一个规律,只要搜索内容中包括中文,就搜不到。
所以可以判定是中文编码的问题,(在开发这类客户端时候,中文编码往往是个很具困难的问题。安卓巴士开发3群的某群友提到:服务器交流用的编码是”ISO-8859-1”,跟我起初用到的编码一致,但真实性仍需考证)所以我们修改上面的代码,将代表搜索内容的v_value对应的值编码为”ISO-8859-1”
就将上段代码中的
- NameValuePair vValue = new NameValuePair("v_value" ,”android”);
复制代码
改为
- NameValuePair vValue = new NameValuePair("v_value" , new String(“android开发”.getBytes(),"ISO-8859-1"));
复制代码
这时再运行,控制台成功输出以” android开发”为关键字的Content。
至此,我们POST请求才真正完成。 观察控制台的HTML后发现,我们需要的书目信息就在里面,只不过被一些HTML标签包裹住了,下一步我们就要解放这些信息,存储到容器里。
这里我们要用到Jsoup,一个Java开源HTML解析器(来自org.jsoup包)。
我们直接上代码,逐行解释(大家最好对应上面的HTML代码来理解)
首先我们建一个容器来装这些解析到的数据,由于我的项目是将这些数据以ListView呈现给用户,而ListView的数据是由Adapter提供,Adapter需要传一个特殊容器-包含HashMap的ArrayList(Android基础知识)
- //所以有
- List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
- //开始使用Jsoup
- //Jsoup支援一个Document类 将刚才的html转化成Document
- Document document = Jsoup.parse(html);
- //一个Document又由elements组成 我们选择”tr”开头的标签,存入 trs元素群中
- Elements trs = document.select("tr");
- //得到整个HTML中包含tr的标签的个数
- int totalTrs = trs.size();
- //我们可以观察上面没有搜索结果的那个HTML。发现,如果totalTrs<=3就表示没结果。
- //只要有书目结果totalTrs必定大于3,于是
- if(totalTrs > 3)
- for(int i = 0;i < totalTrs - 3;i++)
- {
- //观察HTML,从第i+2个tr开始,包含的才是我们要的书目信息
- //我们从每个tr中选出td标签元素群
- Elements tds = trs.get(i + 2).select("td");
- //得到每个tr中td的个数
- int totalTds = tds.size();
- //一个临时的HashMap,里面是String-Object键值对
- Map<String,Object> map = new HashMap<String,Object>();
- //j是一个标识数
- for(int j =0;j < totalTds ;j++)
- {
- switch (j) {
- //0表示第一个,即书名
- //put方法即向map加入一条键值对
- //html()方法就得到标签括起来的内容
- case 0:
- map.put("book_title", tds.get(j).html().toString());
- break;
- case 1:
- //1表示第二个,即作者
- map.put("book_author", tds.get(j).html().toString());
- break;
- case 2:
- //2表示第三个,即出版信息
- map.put("book_press", tds.get(j).html().toString());
- break;
- case 3:
- //3表示第四个,即页数
- map.put("book_page", tds.get(j).html().toString());
- break;
- case 4:
- //4表示第五个,即价格
- map.put("book_price", tds.get(j).html().toString());
- break;
- case 5:
- //5表示第六个,即索取号
- map.put("book_noFor", tds.get(j).html().toString());
- break;
- case 6:
- //6表示第七个,即那段网址
- //那段网址td中又包含一个a标签,a标签的href属性的值就是网址
- //attr(“href”)可以返回href属性的值
- map.put("book_detail", tds.get(j).select("a").attr("href").toString());
- break;
- default:
- break;
- }
- }
- list.add(map);
- }
复制代码
list就是我们需要的ArrayList啦
上面所有代码调通后,我们只需一些简单的复制粘贴,就可以放在我们的Android工程中,加上一段简单的代码就可以让ListView显示这个ArrayList。(由于没有任何技术含量,以及该项目暂未上线,此段代码不予以展示,敬请谅解)
接下来,我们一个页面最多只包含10个书目信息,而我们校图书馆,光以”Java”为关键字的书就超过1000本,怎么来显示完全呢,一次显示所有的书肯定不现实。首先数据量太大,手机无法承受;消耗流量过大,用户体验极差。所以,我们就需要ListView能够动态加载数据,即一开始显示十项,如果用户此时拉动ListView显示完十项之后,自动联网,再加载十项(如果还有十项的话),这样的用户体验会非常顺畅。
这个功能的核心是,我们的ListView需要实现OnScrollListener接口。
如果你的ListView所在的Activity继承的是ListActivity的话,只需在extends ListActivity后面加上implements OnScrollListener,这时你需要复写onScroll和onScrollStateChanged。如果你的ListView是从XMLgetView 得到的,你只需为它setOnScrollListener,也会需要你复写onScroll和onScrollStateChanged。
不管你用哪种方法,我们只用修改onScroll方法
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- // TODO Auto-generated method stub
- //关键的判断代码,这句话表示用户将ListView拉至最底部
- if(firstVisibleItem + visibleItemCount == totalItemCount)
- //你只需要把继续得到下面十项的代码写在这里,就可以实现上述功能了。
- //同样再使用一次POST方法,不再赘述
- //代码由于同样原因不予以展示,敬请谅解
复制代码
至此,文章开头的几个知识点已经全部讲解完毕,时间仓促,事物繁忙,可能会影响文章质量,还请大家多多包涵。 如果有问题,可以直接回帖、发论坛信息或通过Email:anliupeinye@gmail.com联系我。
项目成品展示:
![](http://www.apkbus.com/data/attachment/forum/201111/29/1613368fry8dtzxyzthxfy.png)
下载附件 (334.45 KB)
看看这些信息是不是就是上面用网页以"android"为关键字搜索到的?
最后感谢安卓巴士论坛、安卓王子、安卓巴士开发3群的群友的支持。
文中提到的jar包.zip (1.04 MB, 下载次数: 3560)
本文转自:http://www.apkbus.com/forum.php?mod=viewthread&tid=17712
图解为网站开发Android客户端相关推荐
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView...
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 一步步教你为网站开发Android客户端
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 怎样为网站开发android客户端
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 由网站到android客户端
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 新浪微博开放平台开发-android客户端(2)
引言 最近不是太忙,花了一些时间学习android的应用开发.经过两个星期的学习,学习的同时还写了很多的demo示例,可以从基本控件及基本动画效果等示例demo集合大放送,持续更新下载. 从这个星期开 ...
- 新浪微博开放平台开发-android客户端(3)
引言 最近不是太忙,花了一些时间学习android的应用开发.经过两个星期的学习,学习的同时还写了很多的demo示例,可以从基本控件及基本动画效果等示例demo集合大放送,持续更新下载. 从这个星期开 ...
- Android客户端应用享用传统Web服务
Android系统中提供了SQLite数据库,用于本地的数据存储,App链接到网络就要用到专门的服务应用.目前已经存在了服务应用,想要开发一个Android移动应用用来享用已有的Web服务应用,这类似 ...
- 微信开放平台开发第三方授权登陆(三):Android客户端
微信开放平台开发系列文章: 微信开放平台开发第三方授权登陆(一):开发前期准备 微信开放平台开发第三方授权登陆(二):PC网页端 微信开放平台开发第三方授权登陆(三):Android客户端 微信开放平 ...
- java并发小说爬虫,多站点搜索下载,并实现Android客户端开发
小说爬虫真的很简单,但要能优雅地使用却很麻烦.下面让我来诉说一下这几天的肝路历程.整个流程很完整,但不会很深入,主要是讲思路,给想要写类似功能的同学踩点坑,有什么细节问题直接评论就好. 文章目录 明确 ...
最新文章
- SAP 应用服务负载均衡的实现
- 《贝叶斯思维:统计建模的Python学习法》——1.8 讨论
- js截屏 video_js获取视频截图
- 计算机视觉Computer Vision网址导航
- 全球及中国4-氨基-3-硝基苯酚行业前景趋势与投资规模格局报告2022版
- 音视频技术开发周刊 | 230
- 日志服务客户端(logtail)异常检测工具
- CSS魔法堂:你一定误解过的Normal flow
- 主题:Spring注解入门(转载)
- JDK源码解析之java.util.ListIterator
- 林辉高考机器人_机器人2019年参加高考 力争考上一本
- Matplotlib中的“plt”和“ax”到底是什么?
- 苹果设备尺寸和控件尺寸
- php 公众号 模板消息id如何获取_微信公众号后台模板消息如何实现发送的功能...
- form表单的submit()和onsubmit()的区别
- Logisim的使用
- 画廊php网站,美术画室画廊艺术设计网站整站源码 v5.7sp1
- 美光科技:非挥发性存储器及快闪存储器才是归宿
- vn.py项目安装经验分享
- iofod - 为攻城师们打造的低代码平台
热门文章
- window硬件看门狗(喂狗程序) WinIo32/WinIo64
- agx 安装ros opencv_玩转软路由 篇二:虚拟机ESXI中Mikrotik RouterOS(ROS)的安装设置_路由器...
- VMware下Linux无法播放声音的解决方案
- Android架构详细讲解与C/C++开发支持原理
- 腾讯企业邮箱要实名认证吗?
- Java 将网络url图片链接转换为File类型对象
- CAD二次开发(Vba)------SETXDATA使用
- Openwrt通过tc,iptalbes限速
- Axis-Onvif-PTZ(安迅士摄像头控制设置)
- word文档怎样使用计算机,电脑Word文档怎么将旭日图插入使用