这篇文章主要讲述下,android进程死亡之后,会恢复到什么状态,经历哪些流程,包括onSaveInstanceState相关知识。
经常听到有人说android内存不足时会回收activity,这是不对的,android内存不足时会去查后台进程,杀死某些进程来获取内存。杀activity的说法是不对的,可能是受了官方某些文档的误导。
android官方文档上有这么一段话,有点误导的成分。
If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.
但是android之母Dianne hackbod在http://stackoverflow.com/questions/7536988/上是这么说的
The only memory management that impacts activity lifecycle is the global memory across all processes, as Android decides that it is running low on memory and so need to kill background processes to get some back.
对此,我们必须选择相信Dianne hackbod
有人还做了个android内存不足的一个实验,挺有意思的 http://lab.tigerpenguin.com/2014/03/android-activity-and-low-memory.html
所以结论是,android在运行程序的过程中发现内存不足,他会去杀一些后台进程,来获取内存。如果后台进程都杀光了,内存还不够,此时可能有2种表现,1,跳出OOM崩溃 2,杀死前台进程 并没有回收某个activity或者回收某些activity的行为
2 onCreate hasSaveInstance false
2 onStart
2 onResume
第二步,我们点home,使得我们的进程变为后台进程,可以看到此时onSaveInstanceState就被调用了,这里有些人有误区,有些人认为在杀进程的时候才调用onSaveInstanceState,实际上
任何使得activity变为
StoppedState,大部分会调用onSaveInstanceState,为什么说大部分呢? 因为按了back或者调用finish导致的StoppedState,是不掉onSaveInstanceState,因为activity马上要销毁了,根本不需要恢复,其他情况导致activity变为StoppedState都会调用 onSaveInstanceState,比如切换到其他activity,home,锁屏,旋转等等。onSaveInstanceState的调用频率远远高于onRestoreInstanceState我曾经在onSaveInstanceState存储过几十M的东西,现在想想似乎不是很合理,但是也没办法。还有一点需要注意,onSaveInstanceState和onPause前后关系不定( 在android HONEYCOMB(Api11)之前:onsaveinstance回调是在onpause之前,在Api11之后调整到了opause之后onstop之前,android为何做这个调整,后边会说)
2 onPause
2 onSaveInstanceState
2 onStop
2 onCreate hasSaveInstance true
2 onStart
2 onRestoreInstanceState
2 onResume
刚才说了onCreate里会去读取savedInstanceState这个Bundle的数据,具体怎么读取的呢?
2 onPause
3 onCreate
3 onStart
3 onResume
2 onSaveInstanceState
2 onStop
3 onCreate hasSaveInstance true
3 onStart
3 onRestoreInstanceState
3 onResume
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #5:
Task id #277
* TaskRecord{f101c60 #277 A=com.fish.activitylife U=0 sz=3}
userId=0 effectiveUid=u0a81 mCallingUid=2000 mCallingPackage=null
affinity=com.fish.activitylife
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.fish.activitylife/.MainActivity}
realActivity=com.fish.activitylife/.MainActivity
autoRemoveRecents=false isPersistable=true numFullscreen=3 taskType=0 mTaskToReturnTo=1
rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
Activities=[ActivityRecord{b45a429 u0 com.fish.activitylife/.MainActivity t277}, ActivityRecord{2f57ac2 u0 com.fish.activitylife/.SecondActivity t277}, ActivityRecord{4846528 u0 com.fish.activitylife/.ThirdActivity t277}]
askedCompatMode=false inRecents=true isAvailable=true
lastThumbnail=null lastThumbnailFile=/data/system/recent_images/277_task_thumbnail.png
stackId=5
hasBeenVisible=true mResizeable=false firstActiveTime=1466260184521 lastActiveTime=1466260184521 (inactive for 173s)
* Hist #2: ActivityRecord{4846528 u0 com.fish.activitylife/.ThirdActivity t277}
packageName=com.fish.activitylife processName=com.fish.activitylife
launchedFromUid=10081 launchedFromPackage=com.fish.activitylife userId=0
app=ProcessRecord{4c18519 26051:com.fish.activitylife/u0a81}
Intent { cmp=com.fish.activitylife/.ThirdActivity }
frontOfTask=false task=TaskRecord{f101c60 #277 A=com.fish.activitylife U=0 sz=3}
taskAffinity=com.fish.activitylife
realActivity=com.fish.activitylife/.ThirdActivity
baseDir=/data/app/com.fish.activitylife-1/base.apk
dataDir=/data/user/0/com.fish.activitylife
stateNotNeeded=false componentSpecified=true mActivityType=0
compat={420dpi} labelRes=0x0 icon=0x7f030000 theme=0x7f090037
config={1.0 460mcc1mnc zh_CN ldltr sw411dp w411dp h659dp 420dpi nrml port finger -keyb/v/h -nav/h s.39}
stackConfigOverride={1.0 ?mcc?mnc ?locale ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/?}
taskDescription: iconFilename=null label="null" color=ff3f51b5
launchFailed=false launchCount=1 lastLaunchTime=-2m53s527ms
haveState=false icicle=null
state=RESUMED stopped=false delayedResume=false finishing=false
keysPaused=false inHistory=true visible=true sleeping=false idle=true
fullscreen=true noDisplay=false immersive=false launchMode=0
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=APPLICATION_ACTIVITY_TYPE
waitingVisible=false nowVisible=true lastVisibleTime=-2m53s102ms
* Hist #1: ActivityRecord{2f57ac2 u0 com.fish.activitylife/.SecondActivity t277}
packageName=com.fish.activitylife processName=com.fish.activitylife
launchedFromUid=10081 launchedFromPackage=com.fish.activitylife userId=0
app=null
Intent { cmp=com.fish.activitylife/.SecondActivity }
frontOfTask=false task=TaskRecord{f101c60 #277 A=com.fish.activitylife U=0 sz=3}
taskAffinity=com.fish.activitylife
realActivity=com.fish.activitylife/.SecondActivity
baseDir=/data/app/com.fish.activitylife-1/base.apk
dataDir=/data/user/0/com.fish.activitylife
stateNotNeeded=false componentSpecified=true mActivityType=0
compat={420dpi} labelRes=0x0 icon=0x7f030000 theme=0x7f090037
config={1.0 460mcc1mnc zh_CN ldltr sw411dp w411dp h659dp 420dpi nrml port finger -keyb/v/h -nav/h s.39}
stackConfigOverride={1.0 ?mcc?mnc ?locale ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/?}
taskDescription: iconFilename=null label="null" color=ff3f51b5
launchFailed=false launchCount=0 lastLaunchTime=-3m5s390ms
haveState=true icicle=Bundle[mParcelledData.dataSize=760]
state=DESTROYED stopped=true delayedResume=false finishing=false
keysPaused=false inHistory=true visible=false sleeping=false idle=true
fullscreen=true noDisplay=false immersive=false launchMode=0
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=APPLICATION_ACTIVITY_TYPE
waitingVisible=false nowVisible=false lastVisibleTime=-3m4s931ms
* Hist #0: ActivityRecord{b45a429 u0 com.fish.activitylife/.MainActivity t277}
packageName=com.fish.activitylife processName=com.fish.activitylife
launchedFromUid=2000 launchedFromPackage=null userId=0
app=null
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.fish.activitylife/.MainActivity }
frontOfTask=true task=TaskRecord{f101c60 #277 A=com.fish.activitylife U=0 sz=3}
taskAffinity=com.fish.activitylife
realActivity=com.fish.activitylife/.MainActivity
baseDir=/data/app/com.fish.activitylife-1/base.apk
dataDir=/data/user/0/com.fish.activitylife
stateNotNeeded=false componentSpecified=true mActivityType=0
compat={420dpi} labelRes=0x7f060015 icon=0x7f030000 theme=0x7f090037
config={1.0 460mcc1mnc zh_CN ldltr sw411dp w411dp h659dp 420dpi nrml port finger -keyb/v/h -nav/h s.39}
stackConfigOverride={1.0 ?mcc?mnc ?locale ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/?}
taskDescription: iconFilename=null label="null" color=ff3f51b5
launchFailed=false launchCount=0 lastLaunchTime=-3m9s411ms
haveState=true icicle=Bundle[mParcelledData.dataSize=760]
state=DESTROYED stopped=true delayedResume=false finishing=false
keysPaused=false inHistory=true visible=false sleeping=false idle=true
fullscreen=true noDisplay=false immersive=false launchMode=0
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=APPLICATION_ACTIVITY_TYPE
waitingVisible=false nowVisible=false lastVisibleTime=-3m8s633ms
3 onPause
2 onCreate hasSaveInstance true
2 onStart
2 onRestoreInstanceState
2 onResume
3 onStop
3 onDestroy
2 onPause
1 onCreate hasSaveInstance true
1 onStart
1 onRestoreInstanceState
1 onResume
2 onStop
2 onDestroy