题目来源:
https://www.jianshu.com/p/c70989bd5f29
reqeustlayout调用measure,layout
onlayout,ViewGroup用来摆放View的位置
ondraw:绘制view
DrawChild:child.draw
invalidate运行在UI线程
postInvalidate运行在非UI线程
Activity在attach()中创建一个PhoneWindow
Activity的onCreate()中调用setContentView,实际调用了PhoneWindow.setContentView,生成了一个DecorView,作为根布局,添加View
measure,layout,draw
@targetApi,动态获取版本号,如果大于等于就使用高版本api,否则自己根据需求实现。
同一级别,sink,source
参考:
http://blog.csdn.net/u012702547/article/details/47678943
bitmap是android中重要的图像处理工具类,通过bitmap可以对图像进行剪切、旋转、缩放等操作,同时还可以指定格式和压缩质量保存图像文件。
Bitmap的使用
https://www.jianshu.com/p/98c88f9ceafa
参考:
http://blog.csdn.net/lmj623565791/article/details/38377229
Looper:一个线程只有一个Looper,创建Looper时会创建一个MessageQueue,也就是MessageQueue也只有一个
Looper.prepare()创建一个Looper对象,同时创建一个MessageQueue对象
Looper.loop()进入一个无限循环,不断读取从MessageQueue中读取消息,回调msg.target.dispatchMessage
Handler创建时,会将线程的Looper对象保存在mLooper对象,将MessageQueue保存在mQueue.
Handler发送消息:
->sendMessage
->sendMessageDelayed
->sendMessageAtTime
->enqueueMessage
msg.target=this;将每一个Message的target设置为handler
->MessageQueue.enqueueMessage
发送到了消息队列
参考:
https://www.cnblogs.com/RGogoing/p/5095168.html
http://blog.csdn.net/wangqiubo2010/article/details/79540092
HashMap是数组和链表的结合体,被称为链表散列.
SparseArray是单纯数组的结合.被称为稀疏数组,对数据保存的时候,不会有额外的开销。
SpareseArray 也是通过键值对存储数据,只是key为整形int , 类似于key = Interger 的HashMap,但是SpareseArray 的key 为 int 非 Interger ,更省空间。
SpareArray 意为稀松数组,其结构类似于数组结构,依次排开;HashMap是散列列表,根据hash值来存储;因此SpareArray 会比 HashMap节省很多空间。
从查找速度 和 插入效率来看,如果是正序插入( 0 ->size插入),SpareArray 的插入效率会高于 HashMap。
如果是逆序插入(size -> 0)的顺序插入,则SpareArray 的插入效率表现是最差的,会低于HashMap。
SpareArray 在逆序插入效率很低,是因为 每次插入 SpareArray 都会采用二分查找来定位。
从查找速度来来考虑,HashMap的查找速度 会 高于 SparseArray。
通过以上分析,SpareArray 相对于 HashMap的最大优势在内存空间。
参考:
http://blog.csdn.net/hyhdcl/article/details/78069262?locationNum=9&fps=1
https://www.2cto.com/kf/201611/567930.html
https://www.jianshu.com/p/bdebf741221e
不是,可以使用ContentProvider
参考:
http://blog.csdn.net/a992036795/article/details/51362487
http://blog.csdn.net/qq_32199531/article/details/53435497
Thread
IntentService
AsyncTask
ExecuteService:ThreadPoolExecutor和ScheduledThreadPoolExecutor
HandlerThread
参考:
https://www.cnblogs.com/YukiKun/p/5136708.html
Application:
->onCreate()
->onLowMemory()
->onTrimMemory()
->onTerminate()
->onConfigurationChanged()
进程:
一、前台进程(进程满足如下任一条件即为前台进程):
1. 拥有 一个执行了onresume方法正在与用户交互(获得焦点)的Activity
2. 拥有一个service,这个Service跟正在与用户交互的Activity进行了绑定
3. 拥有一个Service,这个Service调用了startForeground()方法
4. 拥有一个正在执行onCreate()、onStart()或者onDestroy()方法中的任意一个的Service
5. 拥有一个正在执行onReceive方法的BroadcastReceiver
二、可见进程:
1. 拥有一个执行了onPause方法,但仍然可见的Activity
2. 拥有一个Service,这个Service跟一个可见的或前台的Activity绑定了
三、服务进程:
拥有一个通过startService方法启动的Service的进程
四、后台进程:
拥有一个后台Activity(onStop方法被调用)的进程
五、空进程:
没有拥有任何活动的应用组件的进程,也就是没有任何Service和Activity在运行
参考:
http://blog.csdn.net/fwt336/article/details/52979876
onMeasure()
包名,权限,命名空间
application,指定主题,图标,名称,标签
activity
service
receiver
provider
meta-data配置额外的信息
Thread需要借助handler完成线程消息循环,handlerThread就是实现了消息循环的子线程,否则的话需要自己Looper.prepare();Looper.loop();
一个线程要处理消息循环必须要有自己的Looper,new Handler是可以传入线程的Looper对象,将 handler与Looper关联,默认是当前线程。
参考:
http://blog.csdn.net/singwhatiwanna/article/details/48350919
ThreadLocal是一个线程内部的数据存储类,数据是以线程为作用域并且不同线程具有不同的数据副本。
原理:
每个线程都的数据都保存到当前线程本地数据的table数组中,通过get/set获取更新数据。
ThreadLocal的值在table数组中的存储位置总是为ThreadLocal的reference字段所标识的对象的下一个位置,比如ThreadLocal的reference对象在table数组的索引为index,那么ThreadLocal的值在table数组中的索引就是index+1。最终ThreadLocal的值将会被存储在table数组中:table[index + 1] = value。
if(table[index]==threadLocal.reference){
table[index+1]=value;
}
参考:
https://segmentfault.com/a/1190000002872278
内部有一个Handler子类InternalHandler用来实现线程消息传递,所以也要求AsyncTask在主线程实例化,这样Handler默认就是主线程的Handler。
内部有一个 BlockingQueue作为任务缓存队列,
默认核心线程为5的ThreadPoolExecutor,
取消AsyncTask,待用cancel()方法,成功返回true,不在执行onPostExecute,而是执行onCancelled(),但是任务并没有真正的结束,知识决定了成功后走onPostExecute还是onCancelled。
问题:
生命周期:如果执行onPostExecute时Activity已经销毁,而这时候去更新UI,就会发生崩溃。或者
AsyncTask不是内部静态类,Activity被回收,但是AsyncTask仍然保持对Activity的引用,就会内存泄漏。
configChanges,Activity重新创建了,内存泄漏。
更新UI前会调用ViewRootImpl.checkThread()会检测当前线程是否主线程,如果不是主线程,抛出异常:
only the original thread that create a view hierarchy can touch its views
参考:
https://www.jianshu.com/p/7fd95bc2a55c
Application not responsed.应用无响应。
1.在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
2.BroadcastReceiver在10秒内没有执行完毕
3.service是20
把耗时放到子线程执行,不要阻塞主线程
参考:
https://www.jianshu.com/p/f5d8d3066b36
堆内存溢出。
可以trycatch,但是必须是OutOfMemroyError,不属于异常,属于错误。
溢出了:两方面:一方面需要的内存多,创建了过多的对象或者直接加载大图片
另一方面剩余可使用的内存不多,通常是内存泄漏,对象不及时回收。
参考:
http://blog.csdn.net/u012482178/article/details/78988176
一般设置为可用内存的1/8
适配尺寸
AutoLayout,百分比适配
不同分辨率的图片
保存对象的字节序列到本地文件,使用时可以从本地文件读取
对对象进行序列化,在网络中或者在进程间传输对象
AS的插件Android Parcelable code generator
checkPermission+AppopsManager,推荐AndPermission
在申请权限的时候只需要申请这两者中的一个,就可以获得统一分组中的其他权限。
懒加载,setUserVisibleHint
阻止父层的View截获touch事件,调用getParent().requestDisallowInterceptTouchEvent(true);
尺寸压缩
inJustDecodeBounds,inSampleSize
质量压缩
compress quality