Android开发的一些技术细节

最近总结了一些开发中应该注意的技术细节,特此记录下

  • Message obtain跟直接new的区别 :本质是Message obtain是采用享元模式,所以效率会高一些
  • Rxjava操作符设计模式 :看了一下源码其实就是装饰器模式
  • Gson泛型擦除 :Java泛型的实现机制,使用了泛型的代码在运行期间相关的泛型参数的类型会被擦除,我们无法在运行期间获知泛型参数的具体类型(所有的泛型类型在运行时都是Object类型)
    意思就是说,我们传入一个泛型T,然后gson在解析的时候,会把泛型参数的类型擦除,那么我们就没办法获得参数的类型了。所以也就报错了,会把List< T > 泛型解析成LinkedTreeMap
  • 线程池如何保证核心线程不被销毁的 : 大致可以描述为线程池就是用一堆包装住Thread的Wroker类的集合,在里面有条件的进行着死循环,从而可以不断接受任务来进行。
  • 当有新任务来的时候,先看看当前的线程数有没有超过核心线程数,如果没超过就直接新建一个线程来执行新的任务,如果超过了就看看缓存队列有没有满,没满就将新任务放进缓存队列中,满了就新建一个线程来执行新的任务,如果线程池中的线程数已经达到了指定的最大线程数了,那就根据相应的策略拒绝任务。
  • 当缓存队列中的任务都执行完了的时候,线程池中的线程数如果大于核心线程数,就销毁多出来的线程,直到线程池中的线程数等于核心线程数。此时这些线程就不会被销毁了,它们一直处于阻塞状态,等待新的任务到来。
  • volatile和synchronized区别
  • 1、volatile不会进行加锁操作
    volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。
  • 2、volatile变量作用类似于同步变量读写操作
    从内存可见性的角度看,写入volatile变量相当于退出同步代码块,而读取volatile变量相当于进入同步代码块。
  • 3、volatile不如synchronized安全
    在代码中如果过度依赖volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解。仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用它。一般来说,用同步机制会更安全些。
  • 4、volatile无法同时保证内存可见性和原子性
    加锁机制(即同步机制)既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性,原因是声明为volatile的简单变量如果当前值与该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:“count++”、“count = count+1”。
  • 当且仅当满足以下所有条件时,才应该使用volatile变量:
    1、 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。
    2、该变量没有包含在具有其他变量的不变式中。
    总结:在需要同步的时候,第一选择应该是synchronized关键字,这是最安全的方式,尝试其他任何方式都是有风险的。尤其在、jdK1.5之后,对synchronized同步机制做了很多优化,如:自适应的自旋锁、锁粗化、锁消除、轻量级锁等,使得它的性能明显有了很大的提升。
  • HashMap容量为2次幂的原因 :HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法;
    这个算法实际就是取模,hash%length,计算机中直接求余效率不如位移运算,源码中做了优化hash&(length-1),
    hash%length==hash&(length-1)的前提是length是2的n次方;
    为什么这样能均匀分布减少碰撞呢?2的n次方实际就是1后面n个0,2的n次方-1 实际就是n个1;
    例如长度为9时候,3&(9-1)=0 2&(9-1)=0 ,都在0上,碰撞了;
    例如长度为8时候,3&(8-1)=3 2&(8-1)=2 ,不同位置上,不碰撞;
    其实就是按位“与”的时候,每一位都能 &1 ,也就是和1111……1111111进行与运算

  • 从性能层面出发,尽可能直接访问变量而非方法
    Android开发中,类内尽量避免通过get/set访问成员变量,虽然这在语言的开发中是一个好的习惯,但是Android虚拟机中,对方法的调用开销远大于对变量的直接访问。
    在没有JIT的情况下,直接的变量访问比调用方法快3倍,
    在JIT下,直接的变量访问更是比调用方法快7倍!
    基于现有Java封装思想只写public不符合封装,故依据个人习惯而言,没有强制,不过要尽量避免无用的set方法,个人习惯可以只写get方法,没有用到set的不建议生成。

  • ButterKnife只需要在Fragment里解绑,Activity不需要