App研发录读后总结(一)

Stella981
• 阅读 809

   通过一段时间的学习,阅读完了《App研发录》,此书同之前阅读的其他书,如 xx入门,xx提高不同,不是针对具体知识点、api的讲解,而是作者多年的工作经验及工作之中遇到的问题进行汇总分享,特别是第二部分crash异常收集、分析处理,作者花了大篇幅对项目中遇到的crash问题进行分析、归类,重现,有这样一个异常库,对快速定位原因解决bug是很有帮助的。接下来就阐述一下本人的一些学习心得。

   (一)App框架设计与重构

     App研发录读后总结(一)

    1.1  此部分主要讲述了项目开发中遇到的基础技术问题及经典场景,项目重构和命名规范两章,其实主要讲述了代码规范、风格一致,如项目包结构,BaseActivity,adapter模板设计,命名规范及编码规范,代码规范,风格规范一致有很多好处,如可以减少新人的学习成本、增强代码复用,快速bug定位、项目复制、多项目切换等,在项目中还可以结合mvc、mvp及设计模式进行设计及重构。

   1.2 网络设计讲述了怎样封装一个公共的网络请求框架,讲解了封装技巧,公共方法的提取,线程池,对比了asyncTask的优缺点,其中有个知识点,个人感觉项目中可能会用到,当我们定义一个公共的 interface 回调,如 interface CallBack{

        void showCollectResult();

       void showSubscribResult();

    }

A activity需要实现 CallBack,  只需要 showCollectResult,B activity 只需要showSubscribResult,

直接实现 CallBack,就会出现一些空方法,此时我们可通过如下方式避免

abstract class AdapterCallBack implements CallBack

A implements AdapterCallBack{

        void showCollectResult(){

         dosomething;

}

}

B implements AdapterCallBack{

       void showSubscribResult(){

        dosomething;

}

}

网络请求框架目前有很多开源框架可供参考

 1 volley   使用方法参考http://blog.csdn.net/sinyu890807/article/details/17482095

 2 Retrofit 使用方法参考 http://blog.csdn.net/carson\_ho/article/details/73732076

 3 OkHttp 使用方法参考:https://github.com/hongyangAndroid/okhttp-utils

1.3  app图片缓存讲述了 ImageLoader的原理、使用及改造,为减少GC次数,在页面onDestroy 时手动清空ImageLoader缓存。

  除ImageLoader外,Android 图片缓存框架还有 Picasso,Glide,Fresco,各原理及性能对比可参考:http://www.cnblogs.com/linghu-java/p/5741358.html

1.4 网络流量优化

    通信层面上 :

    1 、当api请求或者返回数据比较大时,考虑采用gzip压缩

    2、减少api请求频率,网络请求大部分时间都消耗在建立网络连接及数据传输上,因此能一次请求接口获取数据的,就不要两次, 但这种诉求经常和接口开发人员的设计思想相冲突,他们经常会说一个接口只做一件事,一个功能有时让客户端调两次,甚至三次接口。

   3、建立取消网络请求机制,页面跳转前,要将不用的网络请求停止掉,以免造成网络阻塞及资源浪费。

  图片策略优化:

  1 根据ImageView大小下载图片,通过额外在url 上添加width,height参数,如http://www.aaa.com/a.png?width=100&height=50从服务器获取相应尺寸图片。

     2 根据当前网络环境选择不同图片质量

1.5 APP和h5交互一章中,印象最深的是 h5跳转app页面分发器一节,之前的实现方式是:

h5端:

<a onclick="baobao.gotoAnyWhere('gotoMovieDetail:movieId=(int)12')"gotoAnyWher </a>

android端代码

public void gotoAnyWhere(String url){ if(url!=null){ if(url.startsWith("gotoMoviesDetail:")){ String starMoveId=url.substring(24); int movieId=Integer.valueOf(strMovieId); Intent intent=new Intent(MainActivity.this,MovieDetailActivity.class); intent.putExtra("movieId",movieId); startActivity(intent); }else if (url.startsWith("gotoNewsList:")){ //as above }else if (url.startsWith("gotoUrl:")){ String strUrl=url.substring(8); wvads.loadUrl(strUrl); }else if (url.startsWith("gotoPersonCenter:")){ Intent it=new Intent(MainActivity.this,PersonCenterActivity.class); startActivity(it);

    }
}

}

h5端每增加一个类型,app就要添加一else if,而且要发版解决,书中在页面分发器章节介绍了解决方案,改造如下:

h5端:

<a onclick="baobao.gotoAnyWhere('com.example.youngheart.MovieDetailActivity:
movieId=(int)12')"gotoAnyWher </a>

我们可以看到协议内容分两段:第一段是要跳转到的Activity名称及包路径,第二段是传递的参数,以key-value的形式组装。

 app端:

   解析出第一段,通过Class.fromName(pageName) 反射出Activity 对象, 解析第二段,用于跳转到目标页面传值,具体实现如下

public void gotoAnyWhere(String url) {
        if (url != null) {
            if (url.startsWith("gotoMovieDetail:")) {
                String strMovieId = url.substring(24);
                int movieId = Integer.valueOf(strMovieId);

                Intent intent = new Intent(this, MovieDetailActivity.class);
                intent.putExtra("movieId", movieId);
                startActivity(intent);
            } else if (url.startsWith("gotoNewsList:")) {
                // as above
            } else if (url.startsWith("gotoPersonCenter")) {
                Intent intent = new Intent(this, PersonCenterActivity.class);
                startActivity(intent);
            }
        }
    }

    private String getAndroidPageName(String key) {
        String pageName = null;

        int pos = key.indexOf(",");
        if (pos == -1) {
            pageName = key;
        } else {
            pageName = key.substring(0, pos);
        }

        return pageName;
    }

    public void gotoAnyWhere2(String url) {
        if (url == null)
            return;
        
        String pageName = getAndroidPageName(url);
        if (pageName == null || pageName.trim() == "")
            return;

        Intent intent = new Intent();

        int pos = url.indexOf(":");
        if (pos > 0) {
            String strParams = url.substring(pos);
            String[] pairs = strParams.split("&");
            for (String strKeyAndValue : pairs) {
                String[] arr = strKeyAndValue.split("=");
                String key = arr[0];
                String value = arr[1];
                if (value.startsWith("(int)")) {
                    intent.putExtra(key, Integer.valueOf(value.substring(5)));
                } else if (value.startsWith("(Double)")) {
                    intent.putExtra(key, Double.valueOf(value.substring(8)));
                } else {
                    intent.putExtra(key, value);
                }
            }
        }
        
        try {
            intent.setClass(this, Class.forName(pageName));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        startActivity(intent);
    }

}

      这样h5只要知道 需要跳转类的包路径及跳转参数即可实现跳转,不需app端做改动,相应的局限是只有当页面传递参数是简单类型才适应。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这