一个互联网app的开发设计(技术选型和架构)

在做一个互联网应用时, 要考虑技术选型和架构搭建。 先说说技术选型,   以丁丁租房为例在开发时会面对如下问题:1、图片处理, imageloader或者fresco, 推荐使用fresco,因为它使用三级缓存、占内存更小;2、http通信,  开源框架有很多例如volley,retrofit,okhttp等等,    用法都很简单也类似,  推荐使用OkHttp,它支持SPDY;3、
摘要由CSDN通过智能技术生成

               在做一个互联网应用时, 要考虑技术选型和架构搭建。 先说说技术选型,   以丁丁租房为例在开发时会面对如下问题:

1、图片处理, image loader、picasso、Glide、Fresco, 推荐使用fresco,因为它使用三级缓存、占内存更小;

2、http通信,  开源框架有很多例如volley,retrofit,okhttp等等,    用法都很简单也类似,  推荐使用OkHttp,它支持SPDY;

3、崩溃日志采集, 免费库也有很多,  腾讯bugly、友盟、Fabric。我们使用的是Fabric,  挺好用的。

4、即时聊天,   三方库也有很多, 就不多说了。 我们用的是leancloud, 因为它免费:), 而且效果还可以。

5、控件,   根据UI需要可以自己写或用别人写好的三方库, 例如Materialdialog,MPAndroidChart, WheelView等等。

6、进程内部消息传递,   例如跟Service交互的binder、或者LocalbroadcastReceiver(基于主线程handler实现的,所以不会被其他进程收到,比较安全!)、三方库EventBus和观察者模式等等。

7、支付, 可以用支付宝、微信的接口。 

8、埋点, 这个就很重要了,  产品经理每天都在盯着这个统计数据, 用他们的话叫做数据引导决策,  有时前端也会弄ABTest, 目的是做出让用户更喜欢的东西。 我们用了Countly, 因为它开源,  后台可以自己做,  埋点数据可以传到自己的服务器。 毕竟一些敏感的数据是不想让三方如友盟知道的。

9、bug热修复,  目前有很多技术方案, 我们参考了HotFix的方式在项目中落地,  网上有人说适配有问题, 但我们还没碰到。。。

10、插件化,  应用典型案例就是支付宝、微信。当app功能非常多、代码量很大(超过65535个方法)时要考虑,  我们是计划实践一下, 但因为公司突然倒闭, 没来得及做。

11、程序框架,   对比mvc、mvp和mvvm模式, 我觉得mvp模式比较合适并落地到丁丁租房app里, 因为mvp很好的实现了代码解耦、逻辑分层,  下层对上层透明, 每层只关心自己那点事情就够了。

12、UI标注,推荐使用标你妹啊网站、app.zeplin.io网站。


                                   下面丁丁租房架构图, 最上面一层是各个功能。

   代码结构如下, 按照业务划分一级目录, 二级目录是按照android各组件区分。


      从二级目录看到activity实例化presenter并保存该引用, presenter通过Activity传进来的interface回调到Activity, presenter实现网络接口。 

       调试网络接口要说一下, 在Activity/Fragment退出时要取消未完成的网络请求, 避免耗费流量和回调刷ui时的异常; 可以用RestClient在浏览器测试接口,目的是理解和调试接口的有效性;    

下面附干货源码, 供参考:

Model代码:

/**
 * http网络相关工具类, 目前使用三方库OkHttp库
 */
public class NetworkUtils {

    //网络接口执行周期打点
    private static class DotNet {
        public String tag;   //网络接口的标签
        public long   timestamp; //时间戳
        public String uuid;
    }

    private static OkHttpClient sInstance;

    //初始化OkHttp实例
    static {
        sInstance = new OkHttpClient();
        sInstance.setConnectTimeout(10, TimeUnit.SECONDS);  //连接超时时间
        sInstance.setWriteTimeout(10, TimeUnit.SECONDS);    //上传文件超时时间
        sInstance.setReadTimeout(20, TimeUnit.SECONDS);     //下载文件超时时间
    }

    /**
     * 格式化请求body
     *
     * @param object, 查询用的参数,Map or entity
     */
    private static RequestBody formatRequestBody(
            Context context,
            Object object) {

        //JSON.toJSONString(object)方法默认执行去除value为null的字段
        /*Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            //编辑房源时可以传空字符串
            if (entry.getValue() == null) {
                iterator.remove();
            }
        }*/

        LinkedHashMap baseMap = GatewayUtils.getInstance().getBase(context);  //获取base参数
        Iterator it = baseMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            if (entry.getValue() == null || StringUtils.isNull(entry.getValue().toString())) {
                it.remove();
            }
        }

        String param = JSON.toJSONString(object);           //生成param参数
        String sign = ParamBuild.getSign(object, baseMap);  //计算sign参数

        baseMap.put("sign", sign);
        String base = JSON.toJSONString(baseMap);

        RequestBody formBody = new FormEncodingBuilder()
                .add("base", base)
                .add("param", param)
                .build();

        return formBody;
    }

    /**
     * 格式化请求body
     *
     * @param object, 查询用的参数,Map or entity
     * @param dotNet, 打点要用的参数
     */
    private static RequestBody formatRequestBodyExt(
            Context context,
            Object object,
            DotNet dotNet) {

        //JSON.toJSONString(object)方法默认执行去除value为null的字段
        /*Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            //编辑房源时可以传空字符串
            if (entry.getValue() == null) {
                iterator.remove();
            }
        }*/

        LinkedHashMap baseMap = GatewayUtils.getInstance().getBase(context);  //获取base参数
        Iterator it = baseMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            if (entry.getValue() == null || StringUtils.isNull(entry.getValue().toString())) {
                it.remove();
            }
        }

        try {
            //网络接口执行周期打点时的参数
            String uuid = (String) baseMap.get("uuid");
            dotNet.timestamp = System.currentTimeMillis();
            dotNet.uuid = uuid;
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        String param = JSON.toJSONString(object);           //生成param参数
        String sign = ParamBuild.getSign(object, baseMap);  //计算sign参数
  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值