liu1813565583
liu1813565583
RecyclerView 滑动场景下的回收复用涉及到的结构体两个: mCachedViews 和 RecyclerViewPool mCachedViews 优先级高于 RecyclerViewPool,回收时,最新的 ViewHolder 都是往 mCachedViews 里放,如果它满了,那就移出一个扔到 ViewPool 里好空出位置来缓存最新的 ViewHolder。 复用时,也是先到 mCachedViews 里找 ViewHolder,但需要各种匹配条件,概括一下就是只有原来位置的卡位可以复用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里没有,那么才去 ViewPool 里找。 在 ViewPool 里的 ViewHolder...
在Android中,由于主线程的诸多限制,像网络请求等一些耗时的操作我们必须在子线程中运行。我们往往会通过new Thread来开启一个子线程,待子线程操作完成以后通过Handler切换到主线程中运行。这么以来我们无法管理我们所创建的子线程,并且无限制的创建子线程,它们相互之间竞争,很有可能由于占用过多资源而导致死机或者OOM。所以在Java中为我们提供了线程池来管理我们所创建的线程。 而AsyncTask就是这么个环境下产生的。它本质上是一个静态的线程池(封装了THREAD_POOL_EXECUTOR异步线程池和SERIAL_EXECUTOR同步线程池和Handler),AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。线程池中的工作线程执行doInBackground(mParams)方法执行异步的任务。当任务状态改变后,工作线程向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数。 AsyncTask使用不当的后果 1.)生命周期 AsyncTask不与任何组件绑定生命周期,所以在Activity/或者Fragment中创建执行AsyncTask时,最好在Activity/Fragment的onDestory()调用 cancel(boolean); 2.)内存泄漏 如果AsyncTask被声明为Activity的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露。 3.) 结果丢失 屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask(非静态的内部类)会持有一个之前Activity的引用,这个引用已经无效,这时调用onPostExecute()再去更新界面将不再生效。 AsyncTask里面的两个线程池: 1AsyncTask里面有THREAD_POOL_EXECUTOR和SERIAL_EXECUTOR两种方式来异步执行任务;THREAD_POOL_EXECUTOR是异步的,而SERIAL_EXECUTOR任务是顺序执行的。 2. THREAD_POOL_EXECUTOR如果添加的任务过多,没有及时处理的话,会导致程序崩溃,它的队列size是128;它的调度规则是核心池大小,队列大小,以及最大线程数和异常处理Handler来决定的。 3. SERIAL_EXECUTOR本质是在THREAD_POOL_EXECUTOR的基础上添加一个mTasks的集合来保证任务的顺序执行。
  一开始接触android的同学应该都知道,一般情况下android是不能在子线程中更新ui的。要更新ui界面的时候我们就需要用到android给我们提供的Handler机制。  Handler机制中核心的几个类有Handler、Looper、MessageQueen、Message这四个类,下面我们来一一剖析。   首先来谈谈Handler的用法(HOW): Handler中发送消息的函数可以分为两类:一类是post系列,一类则是sendMessage系列。 - post系列中包括如下方法: ```java post(Runnable) postAtTime(Runnable, long) postDelayed(Runnable, long) ``` 方法的具体意义这里不做解释,不知道的朋友可以去查下文档。post方法是容许你排列一个Runnable的线程对象到主线程队列中,具体的实现我们待会儿再看。    sendMessage系列中包括的方法也大致和post中的差不多 ```java sendEmptyMessage(int) sendMessage(Message) sendMessageAtTime(Message,long); sendMessageDelayed(Message, long); ``` - Handler类的部分源码: ```java public final boolean post(Runnable r)...
内存溢出:是指当对象的内存占用已经超出分配内存的空间大小,这时未经处理的异常就会抛出。比如常见的内存溢出情况有:bitmap过大;引用没释放;资源对象没关闭。 内存泄漏:有些对象只有有限的生命周期。当它们的任务完成之后,它们将被垃圾回收。如果在对象的生命周期本该结束的时候,这个对象还被一系列的引用,这就会导致内存泄漏。随着泄漏的累积,app将消耗完内存。比如,在Activity.onDestroy()被调用之后,view树以及相关的bitmap都应该被垃圾回收。如果一个正在运行的后台线程继续持有这个Activity的引用,那么相关的内存将不会被回收,这最终将导致OutOfMemoryError崩溃。 memory leak会最终会导致out of memory! 两者的关系 内存泄漏是造成内存溢出(OOM)的主要原因,因为系统分配给每个程序的内存也就是Heap size的值都是有限的,当内存泄漏到一定值的时候,最终会发生程序所需要的内存值加上泄漏值大于了系统所分配的内存额度,就是触发内存溢出
设备进行横竖屏切换时 如果不手动配置Activity configChanges属性,系统默认对Activity进行销毁重建操作。 API13以下,Activity configChanges属性中含有orientation即可避免Activity销毁重建。 API13及以上,Activity configChanges属性中同时含有orientation和screenSize即可避免Activity销毁重建。