四大组件
1.活动Activity
2.服务 service
3.内容提供者 content provider
4.广播 Broadcast
service 相关
- Android四大组件之一, 作用: 提供需在后台长期运行的服务, 场景: 复杂计算、音乐播放、下载等
- 特点:无用户界面、在后台运行、生命周期长
相关链接: https://www.jianshu.com/p/d963c55c3ab9
-
- 长生命周期 无界面
- 2.应用场景: 音乐播放器, 检测sd 的变化,在后台记录地理位置信息
-
- onCreate –> onStart(可多次调用)/–> onStop() –> onDestroy
- onCreate –>onBind() –>onUnBind()–>onDestory();
-
- 启动方式: (1).startService()组件启动service 之后,没有反馈结果
- (2).bindService()如果宿主自己的生命周期结束了,bindService模式就要先把服务给销毁掉
https://www.jianshu.com/p/ee224f18a4bd
-
brocastReceiver
- 阐述: 而BroadcastReceiver 是对发送出来的Broadcast进行过滤接受并响应的一类组件。可以使用BroadcastReceiver 来让应用对一个外部的事件做出响应.例如(打电话, 程序卸载完成)
- NotificationManager ,没有UI 来告知用户事情发生了.
- 注册方式: 清单文件静态注册(无论程序处于活动状态,都会进行监听), 代码动态注册(生命周期随aty ,比较推荐)
Content Provide
给不同应用提供内容访问,多进程通信方式
handler机制
- 4.0开始,主线程请求网络异常,利用handler处理,(AsyncTask,Volly,
- Bus对其进行巧妙封装)
- 主要包括Message,MessageQueue,Looper以及Handler。
- Looper 持有MessageQueue
- Message定义了消息必要的描述和属性数据
- MessageQueue 用来存放消息的消息队列
- Handler作为消息处理者,一是处理Message,二是将某个Message压入MessageQueue中
- handler 开始结束 mHandler.removeCallbacks(mRunnable)或者handler.removeMessages(what); 在new MyHandler()的时候开始.
- 一个线程对应一个looper().MessageQueue对象
- ThreadLocal:MessageQueue对象,和Looper对象在每个线程中都只会有一个对象,怎么能保证它只有一个对象,就通过ThreadLocal来保存。Thread Local是一个线程内部的数据存储类,通过它可以在指定线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储到数据,对于其他线程来说则无法获取到数据。
通过Looper的prepare方法创建MessageQueue 通过loop方法找到和当前线程匹配的Looper对象me 从me中取出消息队列对象mQueue 在一个死循环中,从mQueue中取出Message对象 调用每个Message对象的msg.target.dispatchMesssge方法(去除) 也就是Handler的dispatchMessage 方法 在dispatchMessage 根据Message对象的特点执行特定的方法。
1. Android 为什么设计只能通过handler机制更新UI呢
根本是为为了解决多线程并发问题,子线程不加锁会导致界面更新错乱. 线程加锁导致性能低下(不提倡)
handler负责发送消息,Looper负责接收handler发送的消息,并吧消息传给Handler自己
Handler与MessageQuee 关联:通过Handler的构造方法 赋值messageQuee
主线程给子线程发送消息:
handlerThread: 解决多线程并发问题:
mvc与mvp
mvc
- m Model: 对应的则是一些DataSource以及DataBean的相关对象,这里的DataSource指的是数据的来源. (model不只是很简单的一个数据结构定义,更多的它应该包含大量的数据处理和运算的逻辑)
- v View: 对应的则是Android中的layout文件夹中的xml文件
- c Controller: 对应的则是Activity/Fragment
mvp
- m
- v
- p Presenter:主持者层,它相当于是Controller中的业务逻辑部分,它主要是负责view和model层之间的通信
MVP特点:
* view和model之间的通信必须是通过presenter的传递,视图和数据分离,
* 两者之间定义通用接口IContract
*
参考链接:
http://blog.csdn.net/yang542397/article/details/78074629
apk打包过程
- 其实是一个zip压缩包, 可以进行解压
- classes.dex 是apk应用的核心,是源码生成.class文件,利用dex工具转换成虚拟机识别的二进制代码.
把java 文件 –>dex dex+资源文件+清单文件–>apk
屏幕适配
- dp 不能解决所有的适配, 最理想的是用百分比
(1. 用代码动态计算太麻烦,
- linearLayout 的weight来实现,但是不是适用于所有的场合)
- 解决: 1.多使用match_parent,2.多用weight,3.自定义view解决.
- 不同文件夹drawable-hdpi 里面存放的图片是==屏幕密度==(屏幕密度和分辨率没有关系)
自定义控件:
参考慕课网视频:
* 1.继承系统控件, 2.组合系统控件,3.自定义绘制控件.
* 日历控件自定义
权限
对用户的隐私保护力度越来越大.
Android 6.0 动态权限组
7.0 私有目录限制访问
事件分发机制
- 触摸任何一个view,都会调用dispatchTouchEvent. 一直向上查找到view,
- onTouch肯定是要优先于onClick执行, onTouch返回true,onClick就不会再执行
onTouch和onTouchEvent有什么区别
1.两个方法都在view的dispatchTouchEvent中调用,onTouch优先于onTouchEvent,若在onTouch 中返回true,消费掉事件,onTouchEvent 不会执行. 2.onTouch 执行条件, 控件是可以enable,mOnTouchListener 不能为空.
* ViewGroup事件分发
viewGroup包括子view和子viewGroup 1.android 事件分发是先到viewagroup 然后到view, 2. ViewGroup中可以通过onInterceptTouchEvent,返回true代表不允许事件继续向子View传递,返回false代表不对事件进行拦截,默认返回false 3. 子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件
view绘制
- 每个Activity都有一个Window(具体来说是PhoneWindow)相关联,用户界面则由Window所承载
- setContentView()的整体执行流程 :实际上调用到了PhoneWindow的setContentView()方法,最终调用最终调用的是inflate(XmlPullParser, ViewGroup, boolean)方法来填充布局.
- View的绘制是由ViewRoot来负责:::
- 绘制流程:
绘制背景; <br> 通过onDraw()绘制自身内容; <br> 通过dispatchDraw()绘制子View; <br> 绘制滚动条</li>
https://www.jianshu.com/p/060b5f68da79 (详细) http://www.codekk.com/blogs/detail/54cfab086c4761e5001b253f
动画
- 3.0之前传统动画,之后是属性动画(property Animation)
- 传统动画: 补间动画(Tween) 帧动画(Frame Animation).布局动画(Layout Animation)
- *
bitmap优化:
- 大图片 或者多张,可能引起卡顿,
bundle机制
它和Map类型有异曲同工之妙,同时实现了Parcelable接口,那么显然,它是支持进程间通讯的。所以,Bundle可以看做是一个特殊的Map类型,它支持进程间通讯,保存了特定的数据.
hashMap与hashTable
- 都使用哈希表来存储键值对。在数据结构上是基本相同的
- hashMap: 后来在hashTable的基础上演变来的, 线程不安全,效率高 允许null值和键,HashMap默认的初始化大小为16,之后每次扩充为原来的2倍,HashMap是支持null键和null值的
- HashTable: 默认的初始大小为11,之后每次扩充为原来的2n+1,ConcurrentHashMap代替
activity 四种启动方式
- standard singleTop singleTask singleInstance
-
activity 被复用之后中间的aty 会被清除.
onNewIntent()
- 复用Activity时的生命周期回调,onNewIntent(),
- Activity第一启动的时候执行onCreate()—->onStart()—->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()—- >onResart()——>onStart()—–>onResume().
- 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()—->onStart()—->onResume().
布局优化
优化方向:布局性能、布局层级、布局复用性 和 测量 & 绘制时间用来提高界面的显示速度.
(https://juejin.im/entry/5af8e7b26fb9a07acc11d18d)
- 选择耗费性能少的布局,详见(## LinearLayout 与RelativeLayout )
- 减少布局的层级嵌套(使用布局标签 & 合适选择布局类型,提高布局的复用性,使用 布局标签,布局属性 wrap_content 会增加布局测量时计算成本,应尽可能少用)
代码优化
1.多使用封装好的api,
LinearLayout 与RelativeLayout
不得不使用 ViewGroup 多重嵌套时,不要使用 LinearLayout 嵌套,RelativeLayout,可以有效降低嵌套数
1. LinearLayout ,FrameLayout 耗费性能低,
2. RelativeLayout 耗费性能高, 布局复杂
String,StringBuilder,StringBuffer三者的区别
- 速度: StringBuilder >StringBuffer >String,
- 安全:StringBuilder(适用于单线程)是线程不安全的,而StringBuffer是线程安全的(适用多线程下)
- string 不可变, 其内部成员变量全部使用final来修饰,保证成员变量的引用值只能通过构造函数来修改;
Tcp与UDP
- TCP :
- UDP:
- tcp协议和udp协议的差别
TCP UDP
是否连接 面向连接 面向非连接
传输可靠性 可靠 不可靠
应用场合 传输大量数据 少量数据
速度 慢 快
(参考链接)https://blog.csdn.net/air_hjj/article/details/70791852
rxJava 使用
合并多个网络请求:
Flowable.zip() 合并后同时发送, 一个出错全部都出错走onError()
Flowable.merge() merge是不按顺序发送事件
Flowable.concat() 顺序发送
map或flatMap操作符 请求之间存在相互依赖关系.
(https://blog.csdn.net/f1313131/article/details/78475747)被压Backpressure
背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略
Flowable是为了解决背压(backpressure)问题
操作符
类型 描述 Observable<T> 能够发射0或n个数据,并以成功或错误事件终止。 Flowable<T> 能够发射0或n个数据,并以成功或错误事件终止。 支持Backpressure,可以控制数据源发射的速度。 Single<T> 只发射单个数据或错误事件。 Completable 它从来不发射数据,只处理 onComplete 和 onError 事件。可以看成是Rx的Runnable。 Maybe<T> 能够发射0或者1个数据,要么成功,要么失败。有点类似于Optional
- 使用场景:
遍历
提取某条数据
处理耗时操作
- 使用场景:
https://www.cnblogs.com/ztzf-xd/p/7710724.html
EventBus 使用
应用程序的各组件、组件与后台线程间进行通信,比如在子线程中进行请求数据,当数据请求完毕后通过Handler或者是广播通知UI,而两个Fragment之家可以通过Listener进行通信等等。当我们的项目越来越复杂,使用Intent、Handler、Broadcast进行模块间通信、模块与后台线程进行通信时,代码量大,而且高度耦合.
- 粘性事件:@Subscribe(priority = 100,sticky = true)priority越大优先级越高
EventBus也可以终止对事件继续传递的功能
@Subscribe(priority = 100) public void onToastEvent(ToastEvent event){
Toast.makeText(MainActivity.this,event.getContent(),Toast.LENGTH_SHORT).show();EventBus.getDefault().cancelEventDelivery(event);
}
- 普通事件:
- 四种线程模式(thread)类型
- POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
- MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
- BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
- ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。
https://www.jianshu.com/p/251a1e1b793a
Integer 和 int 之间的区别
- Integer是int提供的封装类,而int是Java的基本数据类型; Integer默认值是null,而int默认值是0; 声明为Integer的变量需要实例化,而声明为int的变量不需要实例化; Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数值
- 两个new 出来的Integer总是不一样的。当使用==时,发现其内存地址不同,所以进行==返回false
listView 与RecyclerView
- 为什么listview 没有被代替:ListView采用的是RecyclerBin的回收机制在一些轻量级的List显示时效率更高.
- ListView优势:(1).添加头视图和尾视图,(2).android:divider”设置自定义分割线,(3).点击事件.(简单功能可用)
- 与RecyclerView优势:(1).默认已经进行复用,回收机制更加完善(2).默认支持局部刷新(3).容易实现item添加删除动画效果(4).容易实现拖拽侧滑
- RecyclerView是一个插件式的实现,对各个功能进行解耦,从而扩展性比较好.
https://blog.csdn.net/cuiyufeng2/article/details/54409456
AsyncTask 内部实现原理
性能优化:
- 布局优化:
- 内存优化:
每个app分配内存限制,随设备不同. 图片特别吃内存.
GC 回收线程暂停
切换应用后台app 清理机制: LRU Cache(最近最少使用) onTrimMemory(int level)
数据结构优化: 频繁字符串拼接StringBuilder
ArrayMap,SpareArray 代替HashMap
内存抖动(大规模变量声明不当)
每个class 最小占用0.5kb
HashMap一个enty 额外占用32b**
对象复用: 复用系统自带资源 \
ListView GridView的ConvertView复用\
避免onDraw()(频繁执行)方法里面执行对象创建
内存泄露:会频繁导致GC.
注意Activity 泄露, 用Application Context代替Activity context. Cousor 及时关闭
Android层面:
Android 手机屏幕每秒刷新60帧,大概需要16ms.每隔16ms触发对UI进行渲染,超过时间界面卡顿,通过工具检测,布局是否复杂,观察Gpu,cpu,找到性能瓶颈
过度绘制
- gc 内存抖动,Android Studio中的Memory Monitor查看程序的内存使用
- 请求捆绑,压缩
- 对于不透明的View,显示它只需要渲染一次即可,可是如果这个View设置了alpha值,会至少需要渲染两次
- onDraw()方法是执行在UI线程的,在UI线程尽量避免做任何可能影响到性能的操作
- View.invalidate()会触发View的重绘
- 尽量减少PNG图片的大小是Android里面很重要的一条规范。相比起JPEG,PNG能够提供更加清晰无损的图片,但是PNG格式的图片会更大,占用更多的磁盘空间。到底是使用PNG还是JPEG,需要设计师仔细衡量,对于那些使用JPEG就可以达到视觉效果的,可以考虑采用JPEG即可
- ArrayMap代替hashMap(占内存自动装箱)
- 发起网络请求与接收返回数据都是比较耗电的,应该减少网络请求的频率,这是为了减少电量的消耗
- 减少移动网络被激活的时间与次数,压缩传输数据
- 高程序的启动速度
- 移除那些在程序中使用不到的代码与资源,帮助减少APP的安装包大小
http://www.jackywang.tech/AndroidInterview-Q-A/chinese/subject/性能优化.html (较全面)
OOM
- 主要是图片问题,
- 软引用 :在生命周期内,内存不足会被回收, 强引用 不会
- oom优化:
临时bitmap 尽快处理或者回收(置为空或者回收) <br> 避免bitmap 浪费/ <br> 加载bitmap:缩放比例,解码格式,局部加载 </li>
Gilde 缓存
- 前言:
- 一般缓存模块设计都会有磁盘缓存和内存缓存这两级缓存。移动设备中对内存的使用管理要求很高,而图片资源往往是比较占内存的。
- Android 中图片的显示实体是 Bitmap 对象,每次图片显示时会将图片资源构建成一个 Bitmap 对象,创建 Bitmap 和销毁 Bitmap 是比较消耗系统资源的,所以能让 Bitmap 可复用可有效降低 Bitmap的创建和销毁和频繁的内存申请和释放操作,从而减少卡顿提高应用性能。
- glide:
- 中为了复用 Bitmap 构建了一个 bitmappool,图片的 Bitmap 的申请和释放都需要通过它来处理。需要加载新的图片时,先从 BitmapPool 中查找有没有相应大小或者稍大一点的 Bitmap,有则直接使用,没有再创建新的 Bitmap。一个长列表中的图片往往是大小相同的,所以这个复用率还是相当可观的。
- activeResource 缓存,存放的是正在使用的图片资源对象,数据结构为HashMap
Enum 枚举使用:
Android中是不推荐使用的,
Enum 需要占用较大的内存,如果对内存敏感,请尽量少使用 Enum,换用做静态常量。
枚举一般需要比静态常量超过两倍多的内存。
附录
android基础很全参考:
https://juejin.im/post/598f00da51882548630c0eab