Android基础知识总结(四)
31.Android 进程
一般大体分为前台进程,后台进程,可见进程,服务进程,空进程这五大进程。其中空进程优先级最低,调用startService()让service所在进程成为前台进程,service的onDestory()里重新启动自己可避免后台进程被杀死。
一个应用允许多个进程,在清单文件配置的service为一个进程,Android:process就可以配置;
多进程会引起的异常:静态成员和单例模式会失效,线程同步机制完全失效,SharedPreferences可靠性下降,Application会多次创建。
32.Android 五大存储方式
使用SharedPreferences存储数据; 文件存储数据;SQLite数据库存储数据;使用ContentProvider存储数据;网络存储数据。
当APP没有获取文件存储权限时,当需要存储大文件时,可以保存在APP-data-cache目录里。
ContentProvider:抽象类,为不同应用数据提供数据共享,提供统一接口,通过uri标识要访问的数据。
33.屏幕旋转Activity生命周期
参考文章链接:Activity横竖屏切换生命周期变化 - 简书
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行1次,切竖屏时会执行1次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
4、设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"时,切屏切记要加上screenSize,否则4.0版本以上生命周期不生效
34.Activity 四大启动模式
standard 启动模式
Activity 默认的启动模式,每次 startActivity 都会在栈顶创建一个新的实例,在同一个任务中可以存在多个Activity 的实例。
singleTop 启动模式
栈顶复用,也就是说,要启动 singleTop 模式的 Activity,如果它恰好在当前栈顶,那么直接复用,执行其 onNewIntent 方法。否则,就重新创建一个实例入栈。
singleTask 启动模式
在系统中只有一个实例,当再次启动该 Activity 时,会重用已存在的任务和实例,并且会调用这个实例的 onNewIntent()方法,将 Intent 实例传递到该实例中。
singleInstance 启动模式
总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他 Activity 会自动运行于另一个任务中。当再次启动该 Activity 的实例时,会重用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将 Intent 实例传递到该实例中。
总结:①standard每一次都会创建新的实例;②singleTop栈顶复用。和standard相似,但是如果栈顶已有实例,复用该实例,回调onNewIntent()方法;③singleTask栈内复用。查找栈内有没有该实例,有则复用回调onNewIntent()方法,如果没有,新建Activity,并入栈;④singleInstance单例模式,全局唯一。具备singleTask所有特性,独占一个任务栈。
35.CPU是一个有多功能的优秀领导者,它的优点在于调度、管理、协调能力强,计算能力则位于其次,而GPU相当于一个能接受CPU调度的“拥有强大计算能力”的员工,GPU提供了多核并行计算的基础结构,且核心数非常多,可支撑大量数据的并行操作,拥有更高的访存速度,更高的浮点运算能力。
36.UI卡顿原因
每16ms绘制一次Activity,如果由于一些原因导致了我们的逻辑、CPU耗时、GPU耗时大于16ms(应用卡顿的根源就在于16ms内不能完成绘制渲染合成过程,16ms需要完成视图树的所有测量、布局、绘制渲染及合成),UI就无法完成一次绘制,那么就会造成卡顿。①内存抖动问题,②方法耗时,③view本身卡顿。
解决办法:修改方法,使其不耗时,放到子线程中,如网络访问,大文件操作等,防止ANR,避免GPU过度绘制。
37.Application的生命周期
参考文章:Android中Application的用途及生命周期_YY小爬虫_新浪博客
①onCreate0 在创建应用程序时创建;
②onTerminate() 在模拟环境下执行。当终止应用程序对象时调用,不保证一定被调用,当程序是被内核终止以便为其他应用程序释放资源,那么将不会提醒,并且不调用应用程序的对象的onTerminate方法而直接终止进程;
③onLowMemory() 低内存时执行。好的应用程序一般会在这个方法里面释放一些不必要的资源来应付当后台程序已经终止,前台应用程序内存还不够时的情况;
④onConfigurationChanged(Configuration newConfig) 配置改变时触发这个方法。
⑤onTrimMemory(int level) 程序在进行内存清理时执行。
38.如何避免因引入的开源库导致的安全性和稳定性?
由于项目引入了太多第三方开源库,Android APP有65536方法数的问题,可使用multidex解决。Android Methods Count插件可以高效统计Android开源库的方法数。
39.简单的音频/视频格式
PCM:脉冲编码调制,由二进制数字信号对光源进行通断调制产生,没有压缩的编码方式。
WAV:无损音频文件格式,PCM是无损WAV文件中音频数据的一种编码方式,但是WAV还可以用其它编码。
AVI:音视频交错,调用方便,图像质量好,压缩标准可选。
WMV:可扩充的媒体类型,本地或网络回放,流优先级化。
3GP:3G流媒体,配合3G网络高速传输而开发。
FLV:文件小,加载速度快,用于网络观看视频。
MP4:音视频压缩编码标准。
40.线程同步的方法
①synchronized 即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态;
②同步代码块 即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步;
③使用特殊变量Volatile
(1)volatile关键字为域变量的访问提供了一种免锁机制;
(2)使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新;
(3)因此每次使用该域就要重新计算,而不是使用寄存器中的值;
(4)volatile不会提供任何原子操作,它也不能用来修饰final类型的变量。
④使用重入锁
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和块具有相同的基本行为和语义,并且扩展了其能力;
⑤使用局部变量;
⑥使用阻塞队列。
线程sleep()和wait()的区别
sleep()不释放同步锁,自动唤醒,需要try-catch,线程方法。
wait()释放同步锁,需要notify唤醒,是object方法。
线程的生命周期?如何中断?
生命周期:文章转载:多线程——线程的生命周期 - 积_跬步 - 博客园
来自百度图① 新建状态(New Thread):在Java语言中使用new 操作符创建一个线程后,该线程仅仅是一个空对象,它具备类线程的一些特征,但此时系统没有为其分配资源,这时的线程处于创建状态。
线程处于创建状态时,可通过Thread类的方法来设置各种属性,如线程的优先级(setPriority)、线程名(setName)和线程的类型(setDaemon)等。
② 就绪状态(Runnable):使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于就绪状态。此外,如果某个线程执行了yield()方法,那么该线程会被暂时剥夺CPU资源,重新进入就绪状态。
③ 运行状态(Running):Java运行系统通过调度选中一个处于就绪状态的线程,使其占有CPU并转为运行状态。此时,系统真正执行线程的run()方法。
a) 可以通过Thread类的isAlive方法来判断线程是否处于就绪/运行状态:当线程处于就绪/运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于阻塞状态,也可能处于停止状态。
④ 阻塞和唤醒线程
阻塞状态(Blocked):一个正在运行的线程因某些原因不能继续运行时,就进入阻塞 状态。这些原因包括:
a)当执行了某个线程对象的sleep()等阻塞类型的方法时,该线程对象会被置入一个阻塞集内,等待超时而自动苏醒。
b)当多个线程试图进入某个同步区域时,没能进入该同步区域的线程会被置入锁定集,直到获得该同步区域的锁,进入就绪状态。
c)当线程执行了某个对象的wait()方法时,线程会被置入该对象的等待集中,知道执行了该对象的notify()方法wait()/notify()方法的执行要求线程首先获得该对象的锁。
⑤ 死亡状态(Dead):线程在run()方法执行结束后进入死亡状态。此外,如果线程执行了interrupt()或stop()方法,那么它也会以异常退出的方式进入死亡状态。
终止线程的三种方法
① 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止,推荐使用。
② 使用stop方法强制终止线程(这个方法不推荐使用,因为stop和suppend、resume一样,也可能发生不可预料的结果)。
③ 使用interrupt方法中断线程。
上一篇:Android基础知识总结(三)
下一篇:Android基础知识总结(五)