版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、一步步教你为网站开发Android客户端注:本文来自友盟-安卓巴士教程大赛第一名获奖作品,作者安卓巴士的ID为liupeinye。推荐给所有刚刚开始接触Android开发的朋友们!本文面向Android初级开发者,有一定的Java和Android知识即可。文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView 背景介绍:客户端(Client)或称为用户端,是指与服务器相对应,为客户提供本地服务的程序。而android系统上的90%客户端软件都有一个共性,就是为了改善网页在android系统上体验不佳而生,最具有影响力的
2、软件有:新浪微博、人人网、淘宝等,这类软件最突出的特点就是,先有网站再有软件。由于网络技术发展的多样性,手机浏览器往往无法跟随它的步伐,为改善用户体验,网站客户端软件印运而生。 以下内容100%原创,并在安卓巴士论坛首发,如需转载,请注明作者和出处。谢谢合作。 开发Android网站客户端通常有两种方法:第一种,通过服务端的开放平台,调用提供的API接口来开发,比如说open sina;第二种,服务端没有提供任何接口,你也没有服务端任何数据库访问权限,就是一个纯纯粹粹的网站,要你做客户端。今天,我要和大家分享的正是第二种情况。这是一个简单的示意图,告诉我们,数据是由网页从数据库中取出,我们要为
3、这个系统做客户端,我们就应该这样去改造它。 通过这样间接的方法来访问数据库,只要网页能看到的内容,我们的客户端都能获取到,而UI是由你自行制作,就可以使使用体验上一个台阶。既然网页是我们的数据枢纽,我们就从网页分析着手。该教程来自本人项目-掌上民大-真实经验,所以用项目中的”掌上图书馆”板块来示范。该项目任务为中南民族大学图书馆图书查询功能制作客户端。 首先打开该网址/,我们会看到主界面正中间就是查询入口,我们输入”android”进行查询得到结果的网页,但我们能发现,这个页面是ILAS图书管理系统,所以真正的入口并不是上面红圈的地方。所以我
4、继续找,经过短暂的观察,发现入口在这里 我们点击进入果然就是这货,我们点击书目查询就是它了。真正的入口就在这里,这时我们打开HttpWatch软件,点”Record”,在搜索框里输入”android”,点击查询,抓取以”android”为关键字搜索时浏览器的所有包。待结果界面载入完成后,HttpWatch上就会出现如下信息我们先看Summary选项卡,我们可以初步了解,这是一个POST请求(Http请求中的一种,另一种是GET),POST到的网址是/cgi-bin/IlaswebBib。这样我们的思路就清晰了,我们的客户端需要模拟浏览器,向
5、上述地址POST一个包,那个地址肯定会返回一个Content给我们,不出意外的话,Content里面就是我们要的书目信息。那么,浏览器POST上去的内容是什么呢?我们点击这条POST请求,看详细信息, 由于是POST请求,我们先看POST DATA,里面是以键值对的形式存储的,这里显示了我们浏览器在我们搜索”android”时,POST的所有数据。那这些键值对又代表了什么呢,我们打开这个网页的源码来一探究竟。 从这段可以看出v_index是表示查找途径的它有TITLE,AUTHOR,SUBJECT,CLASSNO,ISBN,CALLNO六种值 FLD_DAT_BEG和FLD_DAT_END分别
6、是开始和结束年份 v_value表示用户在搜索框中输入的内容 v_paggnum表示每页显示的书目条数,有10 15 20三种 v_seldatabases是检索库 有0 1 2三种值v_LogicSrch是检索方式 有0 1两种值 Submit是查询或重填,有 查 询 和 重 填 两种值 至此,我们弄清楚了POST Data里所有内容的含义和取值可能。但我们模拟POST请求为什么,其实就是为了得到搜索的书目信息,所以我们看一下返回的Content是不是我们要的东西 果然,就是我们搜到的书目信息,就以String的形式放在Content里面。最后我们查看一下Stream,截图,以防等下我们需要
7、这里面的东西 好了,这个页面的工作原理我们已经弄清楚了:用户在网页中输入搜索内容后,点击查询,浏览器会POST一个Data到目标网址,该网址的返回信息就是搜到的书目。 我们开始编写代码,模拟这个过程,先打开eclipse建立一个Java项目(注意是Java项目,因为Java项目可以完美移植到Android项目中且调试方便,并且模拟Http请求这一过程没有用到任何Android功能)。导入HttpClient的4个包commons-codec、commons-httpclient、commons-logging、log4j。 1 /实例化HttpClient2 HttpClient client
8、 = new HttpClient();3 /Stream页面里面有Host地址 端口是804 client.getHostConfiguration().setHost(, 80);5 /用目标地址 实例一个POST方法6 PostMethod post = new PostMethod(/cgi-bin/IlaswebBib);7 /将需要的键值对写出来8 NameValuePair beg = new NameValuePair(FLD_DAT_BEG , “”);9 NameVa
9、luePair end = new NameValuePair(FLD_DAT_END , “”);10 NameValuePair submit = new NameValuePair(submit , 查 询);11 NameValuePair vIndex = new NameValuePair(v_index , “TITLE”);12 NameValuePair vLogicSrch = new NameValuePair(v_LogicSrch , 0);13 NameValuePair vPagenum = new NameValuePair(v_pagenum , 1
10、0);14 NameValuePair vSeldatabase = new NameValuePair(v_seldatabase , 0);15 NameValuePair vValue = new NameValuePair(v_value ,”android”);16 17 /给POST方法加入上述键值对18 post.setRequestBody(new NameValuePair beg , end , submit , vIndex , vLogicSrch , vPagenum , vSeldatabase , vValue);19 /执行POST方法20 client.exe
11、cuteMethod(post);21 /将POST返回的数据以流的形式读入,再把输入流流至一个buff缓冲字节数组22 /StreamTool类是我自己写的一个工具类,其内容将在下文附出23 byte buff = StreamTool.readInputStream(post.getResponseBodyAsStream();24 /将返回的内容格式化为String存在html中25 String html = new String(buff);26 /任务完成了,释放连接27 post.releaseConnection(); 28 /StreamTool类如下29 public cl
12、ass StreamTool 30 /*31 * 从输入流中获取数据32 * param inputStream输入流33 * return 字节数组34 * throws Exception35 */36 public static byte readInputStream(InputStream inputStream) throws Exception37 38 /实例化一个输出流39 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();40 /一个1024字节的缓冲字节数组41 byte buffer = n
13、ew byte1024;42 int len = 0;43 /读流的基本知识44 while (len=inputStream.read(buffer) != -1) 45 outputStream.write(buffer, 0, len);46 47 /用完要关,大家都懂的48 inputStream.close();49 return outputStream.toByteArray();50 51 现在,我们得到了POST方法返回的String,我们输出到控制台看看是什么52 System.out.println(html);没错,就是我们上文看到的HttpWatch 抓到的返回Con
14、tent,也就是一段HTML代码,这说明,我们模拟浏览器POST请求成功了!我们再试试别的搜索内容,来一个”android开发”(即将v_value键值对的值改成”android开发”),这时运行后,我们却从控制台得到了这样的结果:经过几次试验后,发现一个规律,只要搜索内容中包括中文,就搜不到。所以可以判定是中文编码的问题,(在开发这类客户端时候,中文编码往往是个很具困难的问题。安卓巴士开发3群的某群友提到:服务器交流用的编码是”ISO-8859-1”,跟我起初用到的编码一致,但真实性仍需考证)所以我们修改上面的代码,将代表搜索内容的v_value对应的值编码为”ISO-8859-1” 就将上
15、段代码中的53 NameValuePair vValue = new NameValuePair(v_value ,”android”);改为54 NameValuePair vValue = new NameValuePair(v_value , new String(“android开发”.getBytes(),ISO-8859-1);这时再运行,控制台成功输出以” android开发”为关键字的Content。至此,我们POST请求才真正完成。 观察控制台的HTML后发现,我们需要的书目信息就在里面,只不过被一些HTML标签包裹住了,下一步我们就要解放这些信息,存储到容器里。这里我们要用
16、到Jsoup,一个Java开源HTML解析器(来自org.jsoup包)。我们直接上代码,逐行解释(大家最好对应上面的HTML代码来理解)首先我们建一个容器来装这些解析到的数据,由于我的项目是将这些数据以ListView呈现给用户,而ListView的数据是由Adapter提供,Adapter需要传一个特殊容器-包含HashMap的ArrayList(Android基础知识)55 /所以有56 ListMap list = new ArrayListMap();57 /开始使用Jsoup58 /Jsoup支援一个Document类 将刚才的html转化成Document59 Document
17、document = Jsoup.parse(html);60 /一个Document又由elements组成 我们选择”tr”开头的标签,存入 trs元素群中61 Elements trs = document.select(tr);62 /得到整个HTML中包含tr的标签的个数63 int totalTrs = trs.size();64 /我们可以观察上面没有搜索结果的那个HTML。发现,如果totalTrs 3)67 for(int i = 0;i totalTrs 3;i+)68 69 /观察HTML,从第i+2个tr开始,包含的才是我们要的书目信息70 /我们从每个tr中选出td标
18、签元素群71 Elements tds = trs.get(i + 2).select(td);72 /得到每个tr中td的个数73 int totalTds = tds.size();74 /一个临时的HashMap,里面是String-Object键值对75 Map map = new HashMap();76 /j是一个标识数77 for(int j =0;j totalTds ;j+)78 79 switch (j) 80 /0表示第一个,即书名81 /put方法即向map加入一条键值对82 /html()方法就得到标签括起来的内容83 case 0:84 map.put(book_t
19、itle, tds.get(j).html().toString();85 break;86 case 1:87 /1表示第二个,即作者88 map.put(book_author, tds.get(j).html().toString();89 break;90 case 2:91 /2表示第三个,即出版信息92 map.put(book_press, tds.get(j).html().toString();93 break;94 case 3:95 /3表示第四个,即页数96 map.put(book_page, tds.get(j).html().toString();97 break
20、;98 case 4:99 /4表示第五个,即价格100 map.put(book_price, tds.get(j).html().toString();101 break;102 case 5:103 /5表示第六个,即索取号104 map.put(book_noFor, tds.get(j).html().toString();105 break;106 case 6:107 /6表示第七个,即那段网址108 /那段网址td中又包含一个a标签,a标签的href属性的值就是网址109 /attr(“href”)可以返回href属性的值110 map.put(book_detail, tds
21、.get(j).select(a).attr(href).toString();111 break;112 default:113 break;114 115 116 list.add(map);117 list就是我们需要的ArrayList啦上面所有代码调通后,我们只需一些简单的复制粘贴,就可以放在我们的Android工程中,加上一段简单的代码就可以让ListView显示这个ArrayList。(由于没有任何技术含量,以及该项目暂未上线,此段代码不予以展示,敬请谅解) 接下来,我们一个页面最多只包含10个书目信息,而我们校图书馆,光以”Java”为关键字的书就超过1000本,怎么来显示完全呢,一次显示所有的书肯定不现实。首先数据量太大,手机无法承受;消耗流量过大,用户体验极差。所以,我们就需要ListView能够动态加载数据,即一开始显示十项,如果用户此时拉动ListView显示完十项之后,自动联网,再加载十项(如果还有十项的话),这样的用户体验会非常顺畅。这个功能的核心是,我们的List
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医院防疫绩效考核制度
- 国企风控制度
- 经络学护理的社会推广与应用
- 公证处绩效考核制度
- 审计政务服务工作制度范本
- 公司审计档案保管制度
- 4s店经员工绩效考核制度范本
- 2026年及未来5年市场数据中国机动车检测行业市场发展数据监测及投资前景展望报告
- 内审审计食堂购卖制度
- 乡镇慢性病绩效考核制度
- DB32∕T 5167-2025 超低能耗建筑技术规程
- 2026年湖南商务职业技术学院单招职业技能测试必刷测试卷及答案1套
- 雨课堂学堂在线学堂云《科学研究方法与论文写作(复大)》单元测试考核答案
- 高考语文二轮复习高中语文选用变换句式练习题含答案
- 异地升学协议书范本
- 水利工程项目法人保证安全生产措施方案
- 《AIGC文案策划与写作》-课程标准
- 企业管理顶层设计方案
- 2025年军事基础知识试题及答案
- 雨课堂在线学堂《资治通鉴》导读课后作业单元考核答案
- 2025年南京市事业单位招聘考试综合类专业能力测试试卷(管理类)真题
评论
0/150
提交评论