安卓细节知识点流水账(一)
2017-08-15 17:22
330 查看
Activivy
手机跟用户交互的的界面android 任务栈:后进先出
activity启动模式:
standard : 每次都会默认创建一个新的activity实例放入任务栈中
singleTop:栈顶复用模式。如果想创建的activity在任务栈栈顶,则使用栈顶的activity不重新创建
singleTask:如果想启动的activity存在于任务栈中,则将该activity置于栈顶,并将它上面的activity实例全部清除
singleInstance:activity实例独享一个任务栈
activity scheme跳转协议
android中scheme协议是一种内部跳转协议,
* 通过自定义scheme协议,可以非常方便地跳转app中的各个页面
* 通过自定义scheme协议 服务器可以定制化的告诉app要跳转到那个页面。
* 可以通过通知栏消息定制跳转页面
* 可以通过H5页面跳转页面
* APP通过scheme协议跳转到另一个APP中
Fragment
FragmentPagerAdapter和FragmentStatePagerAdapter 的区别 :FragmentStatePagerAdapter
在切换不同的Fragment的时候,我们会把前面的Fragment销毁,而我们系统在销毁前,会把我们的我们Fragment的Bundle在我们的onSaveInstanceState(Bundle)保存下来。等用户切换回来的时候,我们的Fragment就会根据我们的instance state恢复出来。
FragmentPagerAdapter
Fragment在切换的时候,不会销毁,而只是调用事务中的detach方法,这种方法,我们只会把我们的Fragment的view销毁,而保留了以前的Fragment对象。所以通过这种方式创建的Fragment一直不会被销毁。
结论:
FragmentPagerAdapter 适用于页面较少的地方
FragmentStatePagerAdapter 适用于页面较多的地方
Service
启动方法:startService()和bindServicesrartService()调用onStartCommand方法
@Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub return super.onStartCommand(intent, flags, startId); }
onStartCommand()的返回值是int 有下面几种类型
(1)START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null
(2)START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
(3)START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
(4)START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
bindService()调用ServiceConnection()方法
mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { InterpttService.LocalBinder localBinder = (InterpttService.LocalBinder) service; } @Override public void onServiceDisconnected(ComponentName name) { } };
IntentService
IntentService可以用来处理异步请求,其内部维护有子线程。启动方式跟传统的service的方式一样。当执行完任务之后它会自动停止。不需要手动去指定stopSelf()。IntentService可以启动多次,但是每次只会执行一个,剩下的都会进入队列中在IntentService的onHandleIntent方法中。当上一个执行完后再依次执行下一个。Broadcast Receiver
跟观察者模式很像可以在不同进程之间通信。同一个APP中的不同进程和不同的APP中都可以
内部实现机制
(1)自定义BroadcastReceiver的接收者 重写 onReceiver()方法
(2)通过Binder机制向AMS(Activity Manager Service)进行注册
(3)广播发送者通过Binder向AMS发送广播
(4)AMS查找符合条件的BroadcastReceiver的接收者,将广播发送到相应的消息队列中
(5)消息循环执行拿到此广播放回调到onReceiver()中。
WebView
(1)WebView的内存泄露。解决方法:《1》另外单独开一个进程 去使用WebView 并且当这个 进程结束时,请手动调用System.exit(0)。《2》动态创建WebView。对WebView中使用的Context使用弱引用。
第一种方法比较好。
(2)onPageFinished()
这个方法的调用时机不够准确,哪里都可能调用。所以别用这个方法。实在想用可以使用onProgressChanged()代替。
(3)导致耗电。
《1》后台无法释放js 如果遇到这种情况 请在onstop和onresume里分别把setJavaScriptEnabled();
给设置成false和true。
《2》后台线程无法释放 。 暴力解决在onDestory()中调用System.exit(0)
Binder
进程间通信* 被请求端(server)在ServiceManager中注册
* 请求端(client)请求的时候,ServiceManager查找需要请求的方法是否存在,如果存在将server的代理对象返回给client
* client通过server的代理对象的操控实现进程间的通信。
Handler(发送消息,处理消息)
handler 通过发送和处理Message和Runnable对象来关联相对应线程的MessageQueue。handler创建的时候,如果不传入looper默认是当前线程的looper。
handler会从MessageQueue中不断的循环取出消息交给Message或Runnable处理。
handler 使用不当会造成内存泄露。
原因:匿名内部类会持有外部activity的引用,如果handler中执行了耗时操作,当activity销毁的时候,handler还在运行。造成内存泄露。
解决方法:将handler设置成静态类。内部持有activity的弱引用。
AsyncTask
本质:封装了线程池和handler的异步框架。(1)一般处理一些耗时短的操作。耗时长的最好还用线程池。
(2)当activity销毁的时候在onDestroy()方法中调用AsyncTask的cancel方法 否则会造成内存泄露或者崩溃
(3)AsyncTask串行的时候稳定 并行的时候不稳定。
HandlerThread
多次创建和销毁线程是很消耗内存资源的。本质:是一个线程类,继承了Thread,HandlerThread有自己的Looper对象可以进行looper循环。所以其内部可以创建handler来发送和处理消息。
优点:不会阻塞。减少了对性能的消耗。
缺点:不能同时进行多任务处理,需要等待。效率低
使用场景源码分析
View的绘制流程
measure——>layout——drowmeasure 自上而下递归测量
MeasureSpac 测量规格是一个32为的int只。前面的两位表示测量模式,后面的30位表示在此模式下的大小
EXACTLY
父容器已经测量出View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值。它对应于LayoutParams中的match_parent和具体的数值这两种模式。
AT_MOST
父容器指定了一个可用大小即SpecSize,View大小不能大于这个值,具体是什么值要看不同View的具体实现。它对应于LayoutParams中的Wrap_content
UNSPECIFIED
父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。
layout 自上而下递归布局
该方法在ViewGroup中定义是抽象函数,继承该类必须实现onLayout方法,而ViewGroup的onMeasure并非必须重写的。View的放置都是根据一个矩形空间放置的,onLayout传下来的l,t,r,b分别是放置父控件的矩形可用空间(除去margin和padding的空间)的左上角的left、top以及右下角right、bottom值。
drow
invalidate() 重新绘制
requestLayout() 重新布局
事件分发的机制
PhoneWindow 所有view的最顶层DectorView Window界面的最顶层View
dispatchTouchEvent():
决定事件是自己处理还是给子view处理 通过调用onInterceptTouchEvent()来拦截事件
onInterceptTouchEvent():
用来拦截事件
onTouchEvent(MotionEvent event):
处理事件
listview相关
(1)适配器模式保证数据和view的分离
(2)缓存机制
recycleBin机制,总共创建屏幕可见的子view条数,将滑出屏幕的view缓存起来从底部复用。
(3)优化
convertView 缓存优化。
ViewHolder 减少findViewById()的次数
getView() 方法中少做耗时操作。
安卓构建
安卓的构建流程:把.java文件变异成.class文件,然后把.class和依赖的.jar文件打包成安卓可识别的.dex文件。然后打包资源文件,将他们合并成未签名的包,最后签名形成完成的包。
自动化构建 jenkins
git 版本管理
proguard混淆
开源框架
okhttpretrofit 动态代理
(1)通过method转换成ServiceMethod对象。
(2)通过ServiceMethod获取okHttpCall
(3)把okHttpCall封装返回call对象
butterknife
glide
相关文章推荐
- 安卓中一些细节问题
- 安卓实习期间整理知识点(七)
- 最近学习安卓中总结的一些知识点 复制代码
- 【安卓知识点汇总】 手机拍照上传照片
- 安卓开发知识框架_1_知识点总结
- 安卓零碎知识点
- day35_安卓基础之新特性和知识点回顾
- 【c++ 一些比较细节的知识点】函数指针
- IOS开发之细节知识点汇总
- 安卓知识点汇总
- 对于安卓锁屏中知识点小结
- 浅谈继承的那些细节知识点--java中继承的简单应用。
- 安卓实习期间整理知识点(五)
- 安卓实习期间整理知识点(十)
- 安卓实习期间整理知识点(十一)
- 安卓实习期间整理知识点(十二)
- 安卓实习期间整理知识点(十三)
- 安卓零碎知识点
- 安卓面试知识点
- 安卓开发-sdk目录细节详解