写Android也有些时间了,一边工作,一边学习,一边积累。仅仅有遇到问题了,花时间去研究,自己的能力才干提升。刀假设不用。慢慢的就会生锈应该也是这个道理吧!上个月公司项目server框架进行的一些调整。可是当时自己的项目没有移植框架。还是前人的代码,一下子差点没把我搞死,真是筋疲力尽。一个周末两天所有加班赶,结果赶出来的质量还很差,等改完了之后大概稳定下来。自己赶紧抽闲余时间把自己的框架移植进去,我的框架是自己慢慢琢磨积累的,拿出来给大家分享一下。有不正确的地方。欢迎大家批评指正。谢谢。

首先,我们要搞client的框架,我们就须要考虑一下client要作的全部事情:

1、封装业务数据,用来向server发请求

2、连接server,发送网络请求

3、拿到响应结果,解析数据。给回到自己的界面进行逻辑推断。控制界面显示

4、依据数据控制自己的界面显示

以上四点是我所考虑的client须要作的事情。第四点我们就不说了,仅仅要拿到了数据 。界面控制,我们自己实现就能够了,这个时候。server的不论什么异常也影响不了我们,那我们的框架就是基于前三点考虑了。

结合这次我们公司server改动的过程说一下。应该更easy理解:

server之前的框架:仅仅有一个HP,client调用的时候,仅仅须要连接HPserver就能够了。封装业务数据格式例如以下

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2luYXRfMjI2NTc0NTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

返回的json字符串格式例如以下图

就几个字段。很好解析

server之后的框架:ESB、ACC、HP。一下子多了两个,ESB是总体控制的,就是说你的全部业务调用的时候,不能再调用HP了,必须走ESB,ESB拿到数据后再进行纷发;ACC是账户中心业务。是从之前HP中分离出来的,也就是说之前业务中有属于账户中心的。如今的运行流程是先到ESB,ESB再纷发给ACC,ACC运行完后。把结果给ESB。ESB再将数据返回给client。并且ESB封装数据格式和ACC封装数据格式还不一样,ESB数据封装例如以下

ACC数据封装例如以下:

外边多加了一层,返回结果数据字段也不一样,这时候大家就明确client框架的重要性了!!

试想一下,假设我们的项目没有框架,回来的数据都是在Activity中处理,依据server返回的数据取结果,那server的依赖性特别大,假设server略微有点变动,那我们就死定了。每一个Activity都要改,工作量大如山啊,并且非常easy出错!Android本身强调高内聚,低偶合,这个道理也非常适用于我们client和server的交互,那我们如今要搭建的框架最应该考虑的。就是不受或者尽量少受server影响,不由于server变化而产生大的变化。所以,我自己总结出了我自己的client项目框架

当中Common类的大致方法例如以下:

/**



* @param context

* @param method调用的接口名称

* @param data
调用接口的业务数据

* @param urltype调用的url地址

* @param second调用接口的备用字段

* @return

*/

public static ResponseBean getHttpResult(RequestBean request){

ResponseBean response=new ResponseBean();

String result="";

HttpResponse httpResponse = returnResponse(request.urltype,request.data.toString());

try {

result = EntityUtils.toString(httpResponse.getEntity());

if (httpResponse != null

&& httpResponse.getStatusLine().getStatusCode() == 200) {

//serverutf-8编码,转换为本地GBK编码

if("0".equals(Constants.isEsb)){

result=new String(result.getBytes("iso-8859-1"),"utf-8");

}

} else {// 请求失败



}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(TextUtils.isEmpty(result)){

response.code="-1";

response.msg="网络请求失败";

return response;

}else{

return parseResultToBean(result,request,response);

}

}





/**

* 解析http请求回来的结果

* @param resulthttp请求返回的字符串

* @param request请求的完整数据

* @param response封装好的响应信息

* @return

*/

private static ResponseBean parseResultToBean(String result,RequestBean request,ResponseBean response){

try{

JSONObject json=new JSONObject(result);

if("0".equals(request.packtype)){

response.code=json.getString("resp_code");

response.msg=json.getString("resp_desc");

response.data=(JSONObject) json.get("data");

if("1".equals(response.code)){

if(Constants.ACC_SYSTEM.equals(request.system)){

response.code=response.data.getString("resp_code");

response.msg=response.data.getString("resp_desc");

if(response.data.has("data")){

response.array=(JSONArray) response.data.get("data");

}

return response;

}else{

response.code=response.data.getString("errcode");

response.msg=response.data.getString("msg");

if(response.data.has("data")){

response.array=(JSONArray) response.data.get("data");

}

return response;

}

}else{

return response;

}

}else{

if(Constants.ACC_SYSTEM.equals(request.system)){

response.code=json.getString("resp_code");

response.msg=json.getString("resp_desc");

if(json.has("data")){

response.array=(JSONArray) json.get("data");

}

return response;

}else{

response.code=json.getString("errcode");

response.msg=json.getString("msg");

if(json.has("data")){

response.array=(JSONArray) json.get("data");

}

return response;

}

}

}catch(Exception e){

e.printStackTrace();

response.code="-2";

response.msg="解析结果失败";

return response;

}

}



/**

* 封装业务数据

* @param request



*/

public static void packRequestData(RequestBean request){

if(Constants.ACC_SYSTEM.equals(request.system)){

if("0".equals(request.packtype)){

request.data=packESBJsonData(request.context, request.data, request.method);

}else{

request.data=packCommonJson(request.data, request.context, request.method, request.system);

}

}else if(Constants.HP_SYSTEM.equals(request.system)){

request.data=packCommonJson(request.data, request.context, request.method, request.system);

if("0".equals(request.packtype)){

request.data=packESBJsonData(request.context, request.data, request.backupmethod);

}

}

}

我们能够看到,我仅仅须要构建RequestBean和ResponseBean就能够了。server的不论什么变化。我们仅仅须要在parseResultToBean(将结果解析为Bean)、packRequestData(封装请求数据)这两个方法中屏蔽完,我们要传回给Activity的解析结果,全部的字段都是我们自定义好的,简单解析例如以下:

private void cancleBind(final int type, final String openid) {

pDialog.show();

ThreadPool.getInstance().addTask(new Thread(){

public void run(){

try {

if (type == 1) {

QQInfo.logout(mTencent, BandAccountActivity.this);

}

JSONObject data = new JSONObject();

data.put("bindtype", type+"");

data.put("userid", Constants.userId);



RequestBean request=new RequestBean(); 

request.context=BandAccountActivity.this; 

request.method="huicloud_remove_bind_sns"; 

request.backupmethod="";

request.packtype=Constants.isEsb; 

request.data=data; 

request.urltype=Constants.ACC_SYSTEM; 

request.res="";

request.array=null;

request.system=Constants.ACC_SYSTEM; 

Common.packRequestData(request); 

ResponseBean response=Common.getHttpResult(request);

if("1".equals(response.code)){

handler.obtainMessage(4, type).sendToTarget();

}else{

handler.obtainMessage(5, type).sendToTarget();

}

Log.d(Constants.TAG, "===BandAccountActivity===取消绑定结果==="

+ response.toString() + "===请求数据===" + request.toString());

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

handler.obtainMessage(2,"网络错误").sendToTarget();

}

}

});

}

看到这里,大家基本大致明确我写这篇文章的目的了吧,再次强调一下,我们搭建自己client的框架,核心思想就是:产生client高内聚,减少与服务端的耦合性!!

而RequestBean和ResponseBean的各自属性,大家就能够依据自己的须要来定了,我眼下定的属性例如以下:

RequestBean:

/**

* 上下文环境

*/

public Context context;



/**

* 调用的接口名称

*/

public String method;



/**

* 调用接口的备用字段

* 由于调用呼朋系统且要经过ESB时。外层接口名称为upeng_app。内层才是真正的业务数据名称

* 当调用呼朋系统时。此字段不可缺少

*/

public String backupmethod;



/**

* 按什么样的要求封装数据

*/

public String packtype;



/**

* 调用接口的业务数据

*/

public JSONObject data;



/**

* 调用接口的url地址

*/

public String urltype;



/**

* 调用接口的备用字段

*/

public String res;



/**

* 备用的array类型

*/

public JSONArray array;



/**

* 调用哪个业务系统

*/

public String system;

ResponseBean的属性:

/**

* 请求结果码

*/

public String code;



/**

* 请求结果信息

*/

public String msg;



/**

* 按哪种方式解析结果

*/

public String packtype;



/**

* 结果数据

*/

public JSONObject data;



/**

* 备用的结果数据

*/

public JSONObject res;



/**

* 备用的存放多个对象

*/

public JSONArray array;



/**

* 结果为string时,用此字段

*/

public String result;

大家在解析结果时。仅仅须要在Common类的parseResultToBean方法中。依据server变化后的方式,任意加入自己解析结果的方式就能够了,自己的这个小框架也经过了一些项目的锻炼,自己感觉很好用。推荐给大家,假设大家有好的提议。欢迎交流,我的QQ:1531074759,自己的框架理解就说到这里,谢谢大家!

浅谈Androidclient项目框架的更多相关文章

  1. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  2. 浅谈开源项目Android-Universal-Image-Loader(Part 3.1)

    本文转载于:http://www.cnblogs.com/osmondy/p/3266023.html 浅谈开源项目Android-Universal-Image-Loader(Part 3.1) 最 ...

  3. [转]浅谈Python web框架

    说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...

  4. 浅谈Python web框架

    一.Python web框架 Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全 ...

  5. Vue 浅谈前端js框架vue

    Vue Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vu ...

  6. 浅谈 Angular 项目实战

    为什么使用 Angular 我不是 Angular 的布道者,但如今痴迷 Angular,使用 Angular 做项目让我有一种兴奋感.目前的三大主流前端框架都研究过,博客中也有三者的相关教程,最早接 ...

  7. 浅谈Log4j2日志框架及使用

    目录 1.日志框架 2.为什么需要日志接口,直接使用具体的实现不就行了吗? 3.log4j2日志级别 4.log4j2配置文件的优先级 5.对于log4j2配置文件的理解 6.对于Appender的理 ...

  8. 浅谈前端三大框架Angular、react、vue

    每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式. 一.Angular,它两个版本都是强主张的,如果你用它,必 ...

  9. 浅谈python web框架django2.x

    1.Django简介 Python下有多款不同的 Web 框架,Django是最有代表性的一种.许多成功的网站和APP都基于Django. Django是一个开源的Web应用框架,由Python写成. ...

随机推荐

  1. Getting and installing the PEAR package manager

    Windows After you have downloaded and installed PHP, you have to manually execute the batch file loc ...

  2. 【转】linux_fdisk命令详解

    转自:http://www.cnblogs.com/xiaofengkang/archive/2011/06/06/2073579.html fdisk -l 可以列出所有的分区,包括没有挂上的分区和 ...

  3. 如何在Docker中部署DzzOffice

    一.一些背景 之前研究Docker很久了,并且在公司内部实际使用起来了,目前分两种场景使用Docker 1.作为PAAS,提供一致,统一的编译/测试环境: 2.作为虚拟机,直接分配给新来的开发人员使用 ...

  4. windows下django1.7 +python3.4.2搭建记录2

    1.自定义页面写一个显示当前时间的页面views.py文件加一个使用模板的模块,整体内容为: #coding=utf-8 from django.shortcuts import render fro ...

  5. 五种情况会导致Session 丢失

    1.Session到期自定丢失.2.当修改web.config 系统会重启  SESSION 会丢失.3.Bin目录有变化时候系统会重启 SESSION会丢失 (这里变化指的是,创建新文件.修改文件名 ...

  6. Redis中的发布与订阅

    redis中实现发布与订阅相对于zookeeper非常简单.直接使用publish和subscribe就行. subscrible news; 订阅news这个channel publish news ...

  7. ps做gif 登陆下拉菜单效果

    作者这里仅介绍登录动画的制作思路和简单过程.一些细节的制作,如登录框,每一帧的图像等都需要自己根据参考图慢慢完成.最终效果 1.新建大小适当的文件,背景填充暗蓝色.首先设计一个底座,主要用图层样式来完 ...

  8. python中基于descriptor的一些概念

    python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2.2.1 静态方法 2.2.2 类方法 2.3 新式类(n ...

  9. 详解WPF Blend工具中的复合路径功能 ( 含路径标记语法 )

    写此文章的目的是为了简单分析一下 Blend工具中提供的"复合路径"功能.有人在我的博文中留言问我复合路径的问题.  稍微琢磨一下,觉得应该是对的.因此贴出来和大家分享.有不对的说 ...

  10. windows端口被占用

    查看端口号被占用进程netstat -a -n -o 强制结束PIDtaskkill /pid:604 /F