目录
1.Android 四大组件
2.Activity生命周期
3.Service的生命周期
4.Service的启动方式
5.Activity的启动模式
6.广播的分类
7.ANR是什么,怎么避免?
8.Handler消息处理机制
9.事件分发机制
10.View绘制流程
11.Binder机制
12.进程间通信
13.网络框架,区别
14.图片框架,区别
15.webview
16.RecyclerView
17.ListView优化
18.缩减APK包大小
19.Android与服务器交互的方式中的对称加密和非对称加密
1.Android 四大组件
Activity【活动】:用于表现功能。
Service【服务】:后台运行服务,不提供界面呈现。
BroadcastReceiver【广播接收器】:用来接收广播。
Content Provider【内容提供商】:支持在多个应用中存储和读取数据,相当于数据库。
2.Activity生命周期
Activity生命周期图及 Fragment生命周期图
Activity的生命周期
- onCreate(): 创建活动,做一些数据初始化操作
- onStart() :由不可见变为可见
- onResume() :可以与用户进行交互,位于栈顶
- onPause() :暂停,启动或恢复另一个活动时调用
- onStop() :停止,变为不可见
- onDestroy() :销毁
- onRestart(): 由停止状态变为运行状态
设备横竖屏切换的时候
- 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
- 设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
- 设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
3.Service的生命周期
- onCreate() :首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次。
- onStartCommand() :当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。
- onDestroy() :当服务不再使用且将被销毁时,系统将调用此方法。
- onBind() :当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。
- onUnbind() :当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。
- onRebind() :当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。
4.Service的启动方式
- 通过startService()方法启动的服务
初始化结束后系统会调用 void onStart(Intent intent) 方法,传递给startService()的Intent对象。如音乐服务会打开Intent 来探明将要播放哪首音乐,并开始播放。
注意:多次调用startService()方法会多次触发onStart()方法。
- 通过bindService()方法启动的服务
初始化结束后系统会调用 IBinder onBind(Intent intent) 方法,用来绑定传递给bindService 的Intent 的对象。
注意:多次调用bindService()时,如果该服务已启动则不会再触发此方法。
5.Activity的启动模式
Standard:标准启动模式,系统默认。
每次启动一个activity系统都会重新创建一个新的实例,不管这个ativity的实例是否已经存在。
问题:
在非Acitivty的 context(例如:getApplicationContext()) 去启动一个当前模式的 Activity,会抛异常:
android.util.AndroidRuntimeException: Calling startActivity() from outside of
an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this
really what you want?原因:
非activity的context不存在activity的任务栈,而新启动的Activity,需要去和启动它的activity在 同一个任务栈中,所以无法启动 Activity
解决:
- 按照异常的提示,跳转的时候,设置一个新的任务栈
Intent intent = new Intent(getApplicationContext(),MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplicationContext().startActivity(intent);
- 把需要启动的 Activity 的模式设置为 singleTask
应用场景:
绝大多数Activity
SingeTop:栈顶复用模式,
如果新的activity已经位于任务栈的栈顶,那么此activity不会重新创建实例(onCreate、onStart不会回调),执行它的onNewIntent方法回调。
如果activity的实例已经存在栈内,不是位于栈顶,还是会重新创建activity的实例的。
应用场景:
通知栏点击收到的通知
防止连续快速点击
新闻内容界面
登录界面
SingleTask:栈内复用模式,是一种单例模式
只要activity实例在栈中存在,那么多次启动此activity都不会重新创建此 activity的实例,多次启动时系统会调用onNewIntent方法,并清空这个activity任务栈上面所有的activity
应用场景:
大多数App的主页
浏览器
微博
SingleInstance:单一实例模式
整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity 公用的一个实例。他会运行在自己单独的任务栈里面,并且任务栈里面只有他一个实例存在。
应用场景:
呼叫来电界面
Intent的Flag:
除了在AndroidManifest文件中设置以外,还可以通过Intent的Flag来设置一个Activity的启动模式
- FLAG_ACTIVITY_NEW_TASK
使用一个新的Task来启动一个Activity,启动的每个Activity都在一个新的Task中。
应用场景:通常使用在从Service中启动Activity的时候,由于Service中并不存在Activity栈,所以使用该Flag来创建一个新的Activity栈,并创建新的Activity实例
- FLAG_ACTIVITY_SINGLE_TOP
使用SingleTop模式启动一个Activity,等价android:launchMode=“singleTop”
- FLAG_ACTIVITY_CLEAR_TOP
使用SingleTask模式来启动一个Activity,等价android:launchMode=“singleTask”
- FLAG_ACTIVITY_NO_HISTORY
Activity使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中
taskAffinity
- 默认情况下,activity的taskAffinity的值为app包名
- 将activity的taskAffinity的值设置为非包名,并且launchMode设置为singleTask 或者 singleInstance,activity可以在新的task启动,如果launchMode为standard,则activity不可以在新的task启动。
6.广播的分类
分为有序广播和无序广播两类。
7.ANR是什么,怎么避免?
Application Not Responding,即应用无响应
KeyDispatchTimeout(5s)主要类型按键或触摸事件在特定时间内无响应
BroadcastTimeout(10s)BoradcastReceiver在特定的时间内无法处理
ServiceTimeout(20s)小概率类型Service在特定的时间内无法处理完成
如何避免:
避免ANR最核心的一点就是在主线程减少耗时操作。如
- 使用子线程处理耗时操作,如IO、数据库
- 降低子线程优先级,使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,默认Thread的优先级和主线程相同
- 使用Handler处理子线程结果,不使用Thread.wait()或者Thread.sleep()来阻塞主线程
- Activity的onCreate和onResume回调中避免耗时的代码
- BroadcastReceiver中onReceiver也要尽量减少耗时操作,如果需要可以使用intentService处理。intentService是一个异步的,会自动停止的服务,解决传统的Service处理完耗时操作后忘记停止并销毁Service的问题
8.Handler消息处理机制
handler消息处理机制分析
9.事件分发机制
事件分发详解
10.View绘制流程
自定义view的基本流程
1、自定义View的属性 编写attr.xml文件
2、在layout布局文件中引用,同时引用命名空间
3、在View的构造方法中获得我们自定义的属性 ,在自定义控件中进行读取(构造方法拿到attr.xml文件值)
4、重写onMesure
5、重写onDraw
11.Binder机制
12.进程间通信
进程间通信详情
-
使用 Intent 中传递 Bundle 数据
-
使用文件共享传输数据
-
使用Messenger传输数据
-
使用Binder(AIDL)传递数据
-
使用ContentProvider的方式传递数据
-
使用BroadcastReceiver的方式
-
使用 Socket 的方式
13.网络框架,区别
- Xutils
优点:
- 全面,可以进行网络请求,可以进行图片加载处理,可以数据储存,还可以对view进行注解
- 使用这个框架非常方便,
缺点:
- 会导致项目对这个框架依赖非常严重
- Volley
为频繁的、数据量小的网络请求而生
优点:
- 小而巧的异步请求框架
- 扩展性很强,支持HttpClient、HttpUrlConnection, 还支持OkHttp
- 封装了ImageLoader,支持简单的图片加载(没有专门的图片加载框架功能强大)
缺点:
- 不支持post大数据,不适合上传文件
- Okhttp
okhttp针对Java和Android程序,封装的一个高性能的http请求库,支持同步,异步,而且okhttp又封装了线程池,封装了数据转换,封装了参数的使用,错误处理等
在使用的时候还需要做一层封装
- Retrofit
基于OkHttp封装的一套RESTful网络请求框架,Retrofit的封装应用了大量的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然默认是用http ,可以使用不同Json Converter 来序列化数据,同时提供对RxJava的支持
目前比较潮流框架使用Retrofit + OkHttp + RxJava + Dagger2
14.图片框架,区别
15.webview
16.RecyclerView
17.ListView优化
- 减少Item布局层级,避免过度绘制,可以使用hierarchyview工具查看优化。
- convertView 复用
- 使用ViewHolder
- item中有图片时,异步加载,并对图片进行压缩
- 快速滑动时,不加载图片
- 对数据进行分页加载
18.缩减APK包大小
- 代码层面
- 良好的编程习惯,不要写重复代码,不要添加无用代码,谨慎添加lib,移除使用不到的libs
- 使用proguard混淆代码(对无用代码进行优化,减少安装包大小)
- native code,大多情况下,只需要支持armabi与x86的架构,非必须,可以拿掉x86
- 资源层面
- 使用Lint工具查找没有使用到的资源,并去除没使用到的资源,如图片,String,XML等。 去除assets目录下的资源没有用到的资源。
- 生成APK的时候,aapt工具本身会对png做优化,在此之前还可以使用其他工具如tinypng对图片进行进一步的压缩预处理。
- 根据需要选择图片格式,在某些时候jpeg可以减少图片的体积。 对于9.png的图片,可拉伸区域尽量切小,尽量不要使用整张大图。使用webp格式
- 策略层面
- 有选择性的提供hdpi,xhdpi,xxhdpi的图片资源。优先提供xhdpi的图片,对于其他根据需要提供有差异的部分即可
- 尽可能重用已有的资源文件,
- 能用代码绘制实现的功能,直接用代码生成,尽量不要使用大量的图片
19.Android与服务器交互的方式中的对称加密和非对称加密
- 对称加密,就是加密和解密数据都是使用同一个key,这方面的算法有DES。
- 非对称加密,加密和解密是使用不同的key。发送数据之前要先和服务端约定生成公钥和私钥,使用公钥加密的数据可以用私钥解密,反之。这方面的算法有RSA。ssh 和 ssl都是典型的非对称加密。
未完待续……