简化安卓环境下HTTP连接的SDK设计

2018-02-02 05:43林育曼温子仪邓圳立罗枳珊刘茹饶浩
电脑知识与技术 2018年1期
关键词:安卓

林育曼+温子仪+邓圳立+罗枳珊+刘茹+饶浩

摘要:为简化安卓下HTTP连接请求的操作,在HttpURLConnection连接的基础上,封装连接与异步到一个aar上,最终用一至二行代码实现想要的操作,提高工作效率。在减少操作代码的同时,也保留了异步操作的灵活性。

关键词:安卓;SDK;连接aar;异步;HTTP连接

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2018)01-0053-02

Abstract: To simplify the operation of the HTTP connection request under Android, Based on the HttpURLConnection, connection was encapsulated and asynchronous to AAR. One or two lines of code were used to implement the desired operation. The efficiency of software development has been improved. The flexibility of asynchronous operations was also retained.

Key words: android; SDK; connection aar; asynchronous; http connection

1 背景

随着智能手机的普及,安卓设备的应用层出不穷,手机应用联网获取数据是必不可少的。传统的安卓开发使用键值对传值,或者利用json 解析,但是往往诸如此类重复的代码需要在很多地方出现,影响整体代码质量。另一方面,代码多了也容易出错,往往一个空指针就需要一番调试。面向对象程序设计很好地解决了这个问题,把很多复杂繁琐的操作封装起来,供用户调用。用户只要会使用方法操作就行,无须花费精力去研究。因此,善于利用封装好所需类的包,可以为开发带来便利。

2 Android连接协议和解析方式

Android使用java语言进行开发,java里面连接的API有HttpURLConnection和 HttpClient,目前官方已经不推荐使用HttpClient,并且HttpURLConnection在原则上也会比HttpClient要快。故而Android常使用HttpURLConnection连接。

每个HttpURLConnection实例都可用于生成单个请求,但是其他实例可以透明地共享连接到HTTP服务器的基础网络。请求后在 HttpURLConnection的InputStream或OutputStream上调用close()方法可以释放与此实例关联的网络资源,对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。

HttpURLConnection已经封装好URL.openConnection()打开一个连接强制转换为HttpURLConnection。然后为其设置“POST”或“GET”以及連接超时时间。若HttpURLConnection的返回码为200则表示连接成功。可以进行下一步操作。

数据请求有POST和GET两种,服务器根据请求的不同给予不同的处理。对于服务器传过来的数据需要根据数据的格式进行解析,较为常用的是JSON和XML,移动开发,用的比较多的是JSON。而传递参数则是直接编辑传递过程的参数,如“www.xxx.com/login?phone=110&user=dxs”。

3 常规连接方式

常规开发采用异步开发,比如一个登录的接口,需要POST传递手机号和密码参数到服务器,服务器再传递登录信息回来。

首先建一个服务器模拟登录的接口,这个接口接收两个参数,一个手机号码,一个加密过的密码,接收到参数后会进行验证,若验证通过则返回登录成功的状态码还有登录的手机号码;若验证不通过,返回错误状态码还有错误信息。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub

String phone = request.getParameter("phone");

String password = request.getParameter("password");

response.setCharacterEncoding("utf-8");

PrintWriter out = response.getWriter();

if(phone.equals("110")){

out.print("{status:1,data:110,message:''}");}

else{

out.print("{status:0,data:'',message:fail}");}}

手机端初始化键值对params, 然后把手机号和加密过的密码分别添加到params里面,用HttpURLConnection连接把params转为html代码通过UTF-8编码发给服务器。

这时候因为UI直接在UI线程操作会造成UI堵塞,这在安卓开发里是不允许出现的,所以可建立一个新的线程进行操作,将返回的数据传递给Handler句柄,在Handler进行想要的处理。endprint

4 SDK设计

4.1 4个请求类的设计

首先设计了4个请求类TextRequest、ImageRequest、FileRequest、MapRequest,具体如下:

TextRequest:有两个静态方法getTxt(String urlPath, String encoding),sendTxt(String urlPath, String txt, String encoding),分别从服务器获取文本还有向服务器发送文本,用于直接发送数据或者json,xml格式数据。

ImageRequest:只提供一个基本的获取图片的静态方法Bitmap getUrlImage(String url)。

FileRequest:提供三个文件上传的静态方法,分别通过文件名字+文件路径,还有不带参数的文件与带参数的文件。

MapRequest:向服务器发送参数的类,有两个静态方法sendPost(String urlPath,Map params, String encoding),sendGet(String urlPath, Map params, String encoding),分別用Post方式还有Get方式向服务器发送参数。

4.2 设计NetTool类调用4个请求类的方法

这里是把几个方法整合到一个类里方便调用,并做了一些优化处理。如GetTxt方法:

public boolean getTxt(final String urlPath, final String encoding, final int what, final Handler handler) {

(new Thread(new Runnable() {

public void run() {

try {

String result = TextRequest.getTxt(urlPath, encoding);

Message msg = new Message();

msg.what = what;

msg.obj = result;

handler.sendMessage(msg);

} catch (Exception e) {

e.printStackTrace();}}

})).start();

return true;}

除了TextRequest.getTxt(urlPath, encoding)本来需要的两个参数外,还需要传递Message.what和Handler,urlPath, encoding改为终态参数。将TextRequest.getTxt(urlPath, encoding)返回值即服务器返回数据作为Message的obj字段,参数what做为Message的what字段,向Handler发送Message信息。

4.3 用数组形式给出键值对

如果数据本来就是Map格式,可以直接传递给MapRequest类下的方法。但如果不是,很多情况下使用参数传参需要做很多重复的工作,将数据添加到Map,再将Map转化为html,这就做了不少多余的工作。上述操作可以用两个数组解决,一个存键,一个存值,在NetTool里将其遍历并添加Map,再用MapRequest类传参,例如:NetTool.sendPost(loginurl,new String[]{"phone","password"},new Object[]{phone,md5password},"utf-8",0,handler); 该操作借鉴于安卓的SimpleAdapter类。

4.4 生成aar包

新建一个android library,放入文件,重新编译,会自动生成aar包,导入项目如图1所示。

5 遇到的问题和解决方案

最大的问题是返回的数据要怎么返回给主程序。因为操作毕竟是在另外一个线程,要怎么从函数里面返回给主程序。一开始的思路是新建个handler,然后在Thread里调用,但是不管怎么创建,始终不是主程序的,无法进行沟通。后来在NetTool类建立一个result静态字段,线程结束后返回值给result,然后把result作为函数的返回值。但是这也是不行的,无法确定线程结束的时间,自然也不知道result里面的值是不是想要的数据。之前用过较好的Imageloader软件包能帮忙加载图片,也是一行代码实现,但是因为传递了Context和具体的控件,内容也较为明确,故软件包可以代替实现操作。但是本软件包并不仅为某一单一功能服务,而是希望程序员可以利用它进一步去做自己的各种操作,所以本方法不适用。最后的方法是在函数参数里传递handler ,而为了编码人员更加灵活操作,把 Message.what也做为参数传过来。这样可以较大提高代码效率,同时保证了数据的稳定性。

6 结束语

常规的安卓把操作封装成一个类,其中每次操作都要使用HttpUrlConnection连接是比较繁琐的步骤,每次连接都要新开一个线程。为了减少代码负担,往往会将连接的过程分离出来,提取成一个方法,但是仍然要手动开启一个线程。

本包将线程一并封装,并且使用两个数组分别传递参数名和参数值,无须用户考虑线程等问题,且在已有Handler情况下一行代码即可实现全部操作。线程和Handler由编码人员自己编写,可以灵活进行各种处理。本软件包帮忙建立了线程,但是Handler还是程序员自己给的,what参数也由程序员给出,因此保留了灵活性。

参考文献:

[1] 钟键. 试析Android异步通信机制[J]. 电脑编程技巧与维护, 2016(10):46-47.

[2] 程艺. android studio生成aar包并在其他工程引用aar包[EB/OL]. (2017-08-20).http://blog.csdn.net/getchance/article/details/47257389.

[3] 郭霖. 第一行代码Android[M]. 北京: 人民邮电出版社, 2014.

[4] 夏盛新. 基于Android的移动开放平台SDK的设计与实现[D]. 西安: 西安电子科技大学, 2014.

[5] 薛海龙, 陈渝, 雷蕾, 等. Android应用异步编程模型性能分析[J]. 计算机科学与探索, 2017.

[6] 章蓬阳, 邵帅. Android异步框架的研究与设计[J]. 软件, 2016, 37(2):150-154.

猜你喜欢
安卓
MIPS安卓平台上ARM二进制翻译系统
让iPhone变安卓,这是真的野
文物表情包
基于安卓手机用户行为的人口学信息预测
安卓系统或成智能汽车标配
一种基于安卓系统的手机侧抓包分析方法
学习安卓应用开发
功能不输iOS8!全新安卓Messenger发布
安卓L未至安卓M来了!安卓首泄漏M系统