Android 你需要掌握的知识(一)
目录
Activity.png一.Activity详解
问:什么是Activity
答:Android 是与用户交互的接口,它提供了一个界面让用户进行点击和各种滑动操作,这就是Activity的意义。
一.Activity的生命周期
1.activity的四种状态
1.1 running状态(运行):表明activity是处于活动状态,这时候用户可以点击屏幕,屏幕会做出相应,它是一个activity处于栈顶的一个状态。
1.2 paused状态(暂停):表明activity失去焦点的时候(失去焦点但仍然对用户可见),或者是被一个非全屏的activity占据,或者是被一个透明的activity放置在栈顶,会处于paused状态,但是我们需要明白这个时候activity只是失去了和用户的交互能力,用户对这个屏幕操作是没有反应的,并不是说整个activity被销毁,这时候它所有的状态信息和成员变量都还在,当然有一种情况就是内存紧张的时候,这个activity会被回收。
1.3 stopped状态(停止):当这个activity被另外一个activity完全覆盖时候,被覆盖的那个activity就会处于stopped状态,这时候它不再是可见的,但是它跟paused状态一样,在内存不紧张的情况,它的一些内存信息和成员变量都还在。
1.4 killed状态(销毁):表明activity已经被系统回收掉了,这时候它保存的信息,成员变量都不在了。
2.activty生命周期分析
图片来源于网络.png灵活的记忆activity的生命周期:
2.1 Activity启动
onCreate() -> onStart() -> onResume()
onCreate():是在Activity被创建的时候回调。
onStart():表明Activity正在启动,Activity已经处于用户可见的状态,并没有处于前台显示,用户还不能与这个Activity进行交互,就是用户看见了但是还不能点击的状态。
onResume():在前台可见了,已经可以与用户交互了,能进行点击,触摸,滑动等等。 在onResume中可以初始化一些资源。
2.2 HOME键
Home键退出:onPause() -> onStop()
onPause():这个方法被调用时,说明整个Activity是处于paused(暂停)状态的。可见的但是不能被触摸的状态,当用户退出至后台时onPause方法就会被调用。
onStop():一般都会在onPause方法执行后执行。表明Activity被停止,或者被完全覆盖,这时候Activity是完全不可见的。这时候如果内存紧张的话就有可能会被回收掉。
Home键回来:onRestart() -> onStart() -> onResume()
onRestart(): 表示Activity重新启动,Activity由不可见状态到可见状态的时候。 应用场景(用户打开了一个新Activity,当前Activity就会被占据,又回到这个Activity时就会调用onRestart()方法)
2.3 BACK键
onPause() -> onStop() -> onDestroy()
onDestroy():表明当前Activity正在被销毁,生命周期最后一个方法,在这个生命周期方法中我们可以做一些回收工作,以及一些资源的释放。
3.android 进程优先级(参考文章)
当系统的内存不足时, android系统将根据进程优先级选择杀死一些不太重要的进程. 进程优先级从高到低分别为:
前台进程/可见进程/服务进程/后台进程/空进程
前台进程:(重点为a,b两点)
a. 进程中包含处于前台的正与用户交互的activity;
b. 进程中包含与前台activity绑定的service;
c. 进程中包含调用了startForeground()方法的service;
d. 进程中包含正在执行onCreate(), onStart(), 或onDestroy()方法的service;
e. 进程中包含正在执行onReceive()方法的BroadcastReceiver.
系统中前台进程的数量很少, 前台进程几乎不会被杀死. 只有当内存低到无法保证所有的前台进程同时运行时才会选择杀死某个前台进程.
可视进程:
a. 进程中包含未处于前台但仍然可见的activity(调用了activity的onPause()方法, 但没有调用onStop()方法). 典型的情况是运行activity时弹出对话框, 此时的activity虽然不是前台activity, 但其仍然可见.
b. 进程中包含与可见activity绑定的service.
可视进程不会被系统杀死, 除非为了保证前台进程的运行而不得已为之.
服务进程 进程中包含已启动的service.
后台进程 进程中包含不可见的activity(onStop()方法调用后的activity). 后台进程不会直接影响用户体验, 为了保证前台进程/可视进程/服务进程的运行, 系统随时都有可能杀死一个后台进程. 一个正确的实现了生命周期方法的activity处于后台时被系统杀死, 可以在用户重新启动它时恢复之前的运行状态.(例如在点击home键后,前台进程就变成了后台进程,如果内存紧张的情况下就会被咔嚓掉)
空进程 不包含任何处于活动状态的进程是一个空进程. 系统经常杀死空进程, 这不会造成任何影响. 空进程存在的唯一理由是为了缓存一些启动数据, 以便下次可以更快的启动.(只要不属于前面4种,都是空进程,没有回掉的组件,出于缓存的目的而保留)
二.Android的任务栈
android 的内部是一个栈结构,栈结构就是后进先出的概念,用这个栈来存储Activity,每次打开一个新activity或者退出当前activity时,都会在一个任务栈当中添加或删除一个activity组件,因此一个task包含了其实是一个activity集合,android 的系统通过任务栈(返回栈)来有序的管理每一个Activity。在android 当中,退出应用程序的时候,必须要把任务当中的所有Activity清除出栈,这时候,才能安全的,完全的退出程序。任务栈只有被销毁了才是处于数据最安全的状态,当然如果不去删除它的话,一定要合理的去保存这个任务栈。这时候它这个任务栈就保留了每个activity的状态也会保存activity的信息,但是特别要注意的是一定要安全的保存任务栈,任务栈并不是唯一的,某些情况下一个activity可以独享一个任务栈,这就是启动模式当中 的 singleInstance。如果想更详细的了解的话,可以去看郭霖大神的Android任务和返回栈完全解析,细数那些你所不知道的细节。
三.Activity启动模式
1.standard(默认启动模式)
standard.png在这种模式下,每次启动一个activity都会重新创建一个activity实例,然后将它加到任务栈当中,就是task当中,不会考虑这个task当中有没有这个实例,不会去复用这个activity,只会重新创建activity,在这个模式当中,每次创建一个activity,都会走相应的生命周期方法,是非常消耗资源的。
为什么android 会提供一个启动模式,在开发中一般都会在不同页面间跳转,不同页面跳转实质就是activity 间的跳转。我们肯定会复用某个activity 。如果跳转到某个原来的activity实例的时候,希望activity是复用的,而不是重新创建的,重新创建是非常消耗资源的,如果每一次创建一个activity都放在task当中,就像standard模式一样。对内存,系统都是一个很大的消耗。
android 提供了第二种启动模式
2.singletop (栈顶复用模式)
singleTop.png如果你创建的activity是在任务栈的栈顶,它就不会创建新的activity,而是复用栈中的activity,如果你创建的activity 不是在栈顶,它还是会创建activity的。
所以为了提高复用模式,android又提供了第三种启动模式
3.singletask(栈内复用模式)
singleTask.png它其实是一个单例模式,每一次启动activity时,系统会在任务栈中检查是否存在该活动的实例,如果存在就直接将activity置于栈顶。注意,它把activity置于栈顶,把这个activity以上的activity都从任务栈中移除,销毁(在任务栈里面只允许一个实例)。
4.singleinstance(单实例模式)
singleInstance.png这个模式比较特殊,这个activity在整个系统当中有且只有一个实例,而且这个activity独享任务栈。(例如 SecondActivity设置成singleinstance模式。让FirstActivity跳转到了 SecondActivity,SecondActivity跳转 ThirdActivity,然后back ,会发现,ThirdActivity直接回到了FirstActivity再按back,才到SecondActivity,因为FirstActivity和ThirdActivity是同一个栈的,这个栈退出空了,就会显示另一个任务栈(返回栈)的栈顶活动)
假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面3种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而是用singleInstance模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。 选自《第一行代码》
四.scheme跳转协议
android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。
操作方法很简单,客户端向H5页面注册一个URL Scheme,由Scheme协议从浏览器中启动这个Activity。Scheme应用场景:
1.服务端下发一个URL的路径然后客户端根据服务端下发的URL跳转到相应的页面。
2.从H5页面跳转到相应的APP Activity
3.APP根据URL跳转到另一个APP的指定页面
scheme跳转协议在开发中是极其重要的。可以看这篇文章详细了解下android H5 应用内跳转Scheme协议