美文网首页
Android必须要掌握的东西

Android必须要掌握的东西

作者: acc8226 | 来源:发表于2017-03-27 08:34 被阅读114次

    石乐志, 从16101703中旬, 重新拾起旧物, 总结一下Android必须要掌握的东西.

    1. 熟练掌握Java技术,熟悉面向对象思想,熟悉常用设计模式

    2. 熟练掌握Android四大组件和Fragment的使用;

    3. 熟练掌握Android中的数据存储(文件, 网络, 数据库存储);

    4. 熟悉掌握Android中常用的UI元素, 动画, 样式;

    动画

    android 3.0新增属性动画(Object, Value)
    android 5.0新增矢量图动画

    通常定义一个AnimatedVectorDrawable需要以下三个xml文件:
    1.vector drawable本身:res/drawable/中定义一个有<vector>元素的xml文件,参考上面对VectorDrawable的定义。
    2.vector drawable的动画文件(Animated vector drawable):res/drawable/中定义一个有<animated-vector>元素的xml文件。
    3.一个或者多个属性动画文件:res/drawable/中定义一个有<objectAnimator>元素的xml文件。

    1. 完全自定义View
    2. 继承已有View, 重写部分功能
    3. 继承ViewGroup

    步骤

    1. 自定义属性的声明和获取
    2. 测量onMeasure
    3. 布局onLayout(ViewGroup)
    4. 绘制onDraw
    5. onTouchEvent
    6. onInterceptTouchEvent(ViewGroup)
      是否拦截该手势

    5. 消息机制和多线程的使用

    6. 网络通信机制及常用数据传输协议;

    HTTP网络请求原理

    HTTP是一种应用层协议, 通过TCP实现了可靠的数据传输, 能够保证可靠的数据传输.

    消息的交互流程有如下几步:

    1. 客户端执行网络请求, 从URL解析出服务器的主机名
    2. 将服务器的主机名转换为服务器的IP地址;
    3. 将端口号从URL中解析出来
    4. 建立一条客户端与Web服务器的TCP连接;
    5. 客户端通过输出流向服务器发送一条HTTP请求
    6. 服务器向客户端回送一条HTTP响应报文
    7. 客户端从输入流获取报文
    8. 客户端解析报文, 关闭连接
    9. 客户端将结果显示在UI上
    HTTP的请求方式(7种)

    get
    post
    put
    delete

    trace
    options
    head

    Android中执行网络请求
    1. 全面支持HTTP协议的HttpClient(在android2.3以前), 在android6.0中该库已被移除
    2. 最佳选择HttpURLConnection
    网络框架的简单实现

    7. Android中的屏幕适配

    8. Android中的布局优化, 内存优化;

    布局优化
    • 减少视图层级
      • 通过工具分析视图层级, 优先相对布局, 约束布局
      • merge标签, 去处理子布局的根视图和父布局是同一类型的情况
    • 延迟加载的ViewStub
      通过这个不可见的和能在运行期间延迟加载目标视图的, 宽高都为0的View.
    内存优化
    • 检查自身可以内存
      每个app都有heap限制, 可以通过调用getMemory来获取可用heap大小

    • 知晓内存的开支情况

      • 使用枚举通常会比使用静态常量要消耗两倍以上的内存,在Android开发当中我们应当尽可能地不使用枚举。
      • 任何一个Java类,包括内部类、匿名类,都要占用大概500字节的内存空间。
      • 任何一个类的实例要消耗12-16字节的内存开支,因此频繁创建实例也是会一定程序上影响内存的。
      • 在使用HashMap时,即使你只设置了一个基本数据类型的键,比如说int,但是也会按照对象的大小来分配内存,大概是32字节,而不是4字节。因此最好的办法就是像上面所说的一样,使用优化过的数据集合。
    • 注意内存的开销, 使用专门给为android优化过的数据容器SparseArray, SparseBoolArray, LongSparseArray, 比HashMap消耗更少的内存.通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效在于他们避免了对key与value的autobox自动装箱,并且避免了装箱后的解箱。
      弃用枚举类型而使用加上IntDef, StringDef注解修饰的全局常量

    • bitmap的优化

      • 千万不要去加载不需要的分辨率, 会占用我们相当多宝贵的内存
      • 图片的色彩格式, 来压缩图片质量
        ARGB_8888 代表32位ARGB位图
        ARGB_4444 代表16位ARGB位图
        RGB_565 代表8位RGB位图
      • 使用成熟的图片框架Picasso, ImageLoader
    • 当内存紧张时释放内存
      onTrimMemory()方法还有很多种其它类型的回调,可以在手机内存降低的时候及时通知我们。我们应该根据回调中传入的级别来去决定如何释放应用程序的资源:

    • 善用service资源
      系统会倾向于将这个Service所依赖的进程进行保留. 因为service的运行代价很高. 例如使用IntentService处理一些单一短时间任务, 这种Service的最大特点就是当后台任务执行结束后会自动停止,从而极大程度上避免了Service内存泄漏的可能性。

    • 为序列化的数据使用nano protobufs

    • 尽量避免使用依赖注入框架

    • 谨慎使用external libraries

    • 关注lint工具所提出的建议

    • 使用ProGuard来剔除不需要的代码
      能够通过移除不需要的代码,重命名类,域与方法等方对代码进行压缩,优化与混淆。使用ProGuard可以是的你的代码更加紧凑,这样能够使用更少mapped代码所需要的RAM。

    • 对最终的APK使用zipalign

    • 使用多进程
      一个典型的例子是创建一个可以长时间后台播放的Music Player。如果整个app运行在一个进程中,当后台播放的时候,前台的那些UI资源也没有办法得到释放。类似这样的app可以切分成2个进程:一个用来操作UI,另外一个用来后台的Service.
      你可以通过在manifest文件中声明’android:process’属性来实现某个组件运行在另外一个进程的操作。

    • 谨慎使用抽象编程
      许多程序员都喜欢各种使用抽象来编程,认为这是一种很好的编程习惯。当然,这一点不可否认,因为的抽象的编程方法更加面向对象,而且在代码的维护和可扩展性方面都会有所提高。但是,在Android上使用抽象会带来额外的内存开支,因为抽象的编程方法需要编写额外的代码,虽然这些代码根本执行不到,但是却也要映射到内存当中,不仅占用了更多的内存,在执行效率方面也会有所降低。当然这里我并不是提倡大家完全不使用抽象编程,而是谨慎使用抽象编程,不要认为这是一种很酷的编程方式而去肆意使用它,只在你认为有必要的情况下才去使用。

    9. Android中的单元测试;

    优点

    1. 为代码提供保障
    2. 优化设计, 编写单元测试从调用者角度观察, 迫使设计者吧程序设计成易于调试和可测试, 并且消除软件中的耦合.
    3. 文档记录, 是一种展示函数或者类使用的最佳文档
    4. 具有回归性, 编写完成后可以随时快速测试.

    JUnit简介
    基于Java语言的单元测试框架.

    开发人员一般需要新建一个TestCase的类, 然后在该测试类中添加测试函数.
    需要注意的是, 每个测试方法, TestCase之间并没有关联, 它们的执行顺序也不一定是代码中的执行顺序, 因此, 测试方法不要存在依赖性.

    测试哪些条件
    1. 边界条件
      是单元测试需要重要测试的地方
    2. 覆盖执行路径
    模拟所需的功能模块
    • 手动mock对象
    • 使用Mockito库
    Android中单元测试

    Google在Junit的基础上进行拓展, 使之能在Android上运行测试实例, Android平台下所有的测试类都是InstrumentationTestCase的子类, 它的内部封装了Instrumentation对四大组件进行操作, 而InstrumentationTestCase继承在Junit的TestCase.

    • 需要Context的测试用例
      AndroidTestCase
    • AcitivityUnitTestCase<T>
      和 ActivityInstrumentationTestCase2<T>
    • 测试Service, 继承自ServiceTestCase<T>
    • 测试ContentPrivider, 继承自ContentPrividerTestCase2<T>

    10. 网络框架Volley, 图片处理Picasso等;

    第一部分Request
    第二部分RequestQueue消息队列, 维护了提交我给网络框架的请求队列, 并根据对应规则进行排序, 该队列使用的线程安全的PriorityBlockingQueue, 所以支持并发访问.
    第三部分NetWorkExecutor, 也就是网络的执行者, 该Exectuor继承自Thread, 在run方法中循环访问请求队列, 从请求队列中获取网络请求, 请求完成后提交给UI线程
    第四部分Response及其投递类, 使用ResponseDelivery来封装Response的投递, 保证Response在UI线程中执行, Response会根据用户的不同需求返回特定的类型.

    Picasso

    Picasso不仅实现了图片异步加载的功能,还解决了android中加载图片时需要解决的一些常见问题:
    1.在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。
    2.使用复杂的图片压缩转换来尽可能的减少内存消耗
    3.自带内存和硬盘二级缓存功能

    Cache,缓存类


    Lrucache,主要是get和set方法,存储的结构采用了LinkedHashMap,这种map内部实现了lru算法(Least Recently Used 近期最少使用算法)。

    Request,操作封装类

    所有对图形的操作都会记录在这里,供之后图形的创建使用

    Action

    Action代表了一个具体的加载任务,主要用于图片加载后的结果回调,有两个抽象方法,complete和error,也就是当图片解析为bitmap后用户希望做什么。最简单的就是将bitmap设置给imageview,失败了就将错误通过回调通知到上层。


    ImageViewAction实现了Action,在complete中将bitmap和imageview组成了一个PicassoDrawable,里面会实现淡出的动画效果。

    BitmapHunter


    BitmapHunter是一个Runnable,其中有一个decode的抽象方法,用于子类实现不同类型资源的解析。

    在bitmaphunter成功得到bitmap后,就是通过dispatcher将结果传递出去的,当然让bitmaphunter执行也要通过Dispatcher。


    Dispatcher内有一个HandlerThread,所有的请求都会通过这个thread转换,也就是请求也是异步的,这样应该是为了Ui线程更加流畅,同时保证请求的顺序,因为handler的消息队列。外部调用的是dispatchXXX方法,然后通过handler将请求转换到对应的performXXX方法。例如生成Action以后就会调用dispather的dispatchSubmit()来请求执行,

    handler接到消息后转换到performSubmit方法

    这里将通过action得到具体的BitmapHunder,然后交给ExecutorService执行。

    下面是Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView)的过程,

    public static Picasso with(Context context) {
            if (singleton == null) {
                singleton = new Builder(context).build();
            }
            return singleton;
        }
                                                                                                                      
        public Picasso build() {
                Context context = this.context;
                                                                                                                  
                if (downloader == null) {
                    downloader = Utils.createDefaultDownloader(context);
                }
                if (cache == null) {
                    cache = new LruCache(context);
                }
                if (service == null) {
                    service = new PicassoExecutorService();
                }
                if (transformer == null) {
                    transformer = RequestTransformer.IDENTITY;
                }
                                                                                                                  
                Stats stats = new Stats(cache);
                                                                                                                  
                Dispatcher dispatcher = new Dispatcher(context, service, HANDLER,
                        downloader, cache, stats);
                                                                                                                  
                return new Picasso(context, dispatcher, cache, listener,
                        transformer, stats, debugging);
            }
    

    在Picasso.with()的时候会将执行所需的所有必备元素创建出来,如缓存cache、执行executorService、调度dispatch等,在load()时创建Request,在into()中创建action、bitmapHunter,并最终交给dispatcher执行。

    11. 目前流行的MVP模式构建应用

    全称Model View Presenter
    MVP让UI界面和数据分离, 解除View和Model直接的耦合

    相关文章

      网友评论

          本文标题:Android必须要掌握的东西

          本文链接:https://www.haomeiwen.com/subject/raernttx.html