Q:Activity生命周期
activity生命周期由7个,3对+1
onCreate->onRestart->onStart:可见->onResume:交互
onPause:存储数据,要快,切换的时候onPause后,第二个activity才会执行onCreate
onStop:当activity仍然可见没有被完全覆盖,不走onStop,比如dialog或者透明主题
onDestory
Activity退居后台,且系统内存不足的时候,系统会杀死这个后台状态的Activity,若再次回到这个Activity,会走onCreate()–>onStart()—>onResume()
锁定屏与解锁屏幕 只会调用onPause(),而不会调用onStop方法,开屏后则调用onResume()
Q:为什么Activity要划分出这么多的生命周期方法
Q:onSaveInstanceState跟onRestoreInstanceState的场景与时机,谁调用,怎么调用
非正常退出的时候,有可能被回收,
在onStop之前
onResume之前
系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统都会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
1.当用户按下HOME键时
2.长按HOME键,选择运行其他的程序时
3.锁屏时
4.从activity A中启动一个新的activity时
5.屏幕方向切换时
如果想在横竖屏切换时,不重建activity
android:configChanges = “orientation|screenSize”
Q:onPause()和onSaveInstanceState都可以存储数据,用途有何不同
onPause(),保存需要持久化的数据,如邮件正文
onSaveInstanceState用于保存UI临时状态,如tab位置,滚动的位置。
不一定会被调用,在onStop之前,但是和onPause的顺序不定
Q:onRestart什么时候调用
再次显示activity的时候,没有销毁,从不可见到可见
onStop->onRestart->onStart
Q:onNewIntent
来了一个新的intent
当activity是栈顶复用(singleTop)或栈内复用(singleTask)的时候,如果要复用activity,就不会走onCreate去创建实例,而是onNewIntent(intent)
onNewIntent->onRestart->onStart
如果已经杀掉了,就会调onCreate,所以在onCreate和onNewIntent调用同一处理方法
另外在onNewIntent的时候需要setIntent,新的intent启动的,否则后续的getIntent会返回老的intent
Q:Activity的四种启动方式
standard:默认的,activity会有多个实例,每次启动activity,无论栈中有没有,都新建
singleTop:如果这个activity在栈顶,onNewIntent,不会创建新实例
singleTask:栈内有就复用,上面的出栈,手机令牌项目的主界面就是singleTask
singleInstance:整个Android系统只有一个实例,会创建一个新的任务栈,里面只有他一个
Q:在 AndroidManifest 里面和 Intent 里面设置的启动方式,哪个优先级更高?
intent更高
Q:AndroidManifest 里面设置的启动方式和 Intent.FLAG 的启动方式是一一对应的吗
否,双方都有一些对方没有的启动方式
Q:怎样用Intent实现singleTask模式
Q:taskAffinity干啥用的
任务栈亲密关系,启动在哪个任务栈
理论上所有的activity都是同一个,从application继承而来,application的affinity是包名。
不指定,都存放在默认的task,singleInstance除外
Q:Activity通信方式有哪些
Q:StartActivityForResult(int requestCode) 里面的 requestCode 有什么要求吗?正负大小等等
高16位必须为0,否则会抛出 IllegalArgumentException
Q:如何让activity运行在另一个进程中
在Androidmanifest中android:process
Q:为什么不new一个activity或service
因为要有framework层做初始化才有生命周期
Q:Intent可以传递什么数据?有大小限制吗?如何传递大文件
1.基本数据类型
2.serializable对象序列化
3.parcelable,新类型Parcel,实现了Parcelable可以放假Parcel,Android另一种序列化
4.charsequence:charBuffer,String,StringBuffer,StringBuilder
5.Bundle
1M以内,受Binder限制,Binder的大小限制1M
超过会闪退、停止运行等,不同手机反应不同
Q:Intent可以传递集合吗
可以,但是只可以传递ArrayList和HashMap
Q:intent如何传递大文件
图片可以穿R.id
如果是从网上下,可以放到map里,key是url地址,通过intent传key,然后从map取出图片
Q:intent-filter匹配规则
action:有且只有一个
category:intent可以没有,有默认,如果有,必须全部匹配
data:数据格式,mineType和URI,
intent-filter的URI有默认值,为content和file,Intent的URI必须为content或file才能匹配
Q:隐式跳转时如果有多个 Activity 具有相同的 schema,相同时怎么处理的
弹出对话框让用户选择进入哪个 Activity
Q:Activity里有一个viewpage fragment,生命周期是怎样的
在onCreate中发送一个网络请求,决定加几个fragment
Activity onCreate
Activity onResume
网络请求返回了 onSuccess
然后初始化viewPager
getCount,getCount
getItem new Fragment 0
getItem new Fragment 1
fragment 0 onCreate
fragment 1 onCreate
fragment 0 onCreateView
fragment 0 refreshView
fragment 0 onResume
fragment 1 onCreateView
fragment 1 freshView
fragment 1 onResume
放在onResume以后,生命周期是一样的
点击tab,没有adapter里的重复调用,只调用了getCount
只有一个tab
Activity onCreate
Activity onResume
refresh onSuccess,回来以后才new,不是初始化Adapter就调用
new Fragment
onCreate
onCreateView
onResume
Tab来回切换的时候也并不会调用onResume
Q:创建dialog所需的上下文为什么必须是Activity
会报BadTokenException
Token中文是令牌的意思,Android将其作为一种安全机制
本质是一个Binder对象,在跨进程的通信中充当验证码
activity启动过程中及界面绘制过程中会涉及到ActivityManagerService,应用程序,WindowManagerService三个进程间的通信,此时Token在这三个进程中充当一个身份验证的功能,ActivityManagerService与WindowManagerService通过应用程序的activity传过来的Token来分辨到底是控制应用程序的哪个activity
启动activity的流程,ActivityManagerService会创建ActivityRecord由其本身来管理,为这个ActivityRecord创建一个IApplication(Binder)
通过跨进程方式将这个binder对象传给WindowManagerService,记录下这个Binder
当ActivityManagerService这边完成数据结构的添加之后,会返回给ActivityThread一个ActivityClientRecord数据结构,中间就包含了Token这个Binder对象。
ActivityThread这边拿到这个Token的Binder对象之后,就需要让WindowManagerService去在界面上添加一个对应窗口,在添加窗口传给WindowManagerService的数据中WindowManager.LayoutParams这里面就包含了Token。
最终WindowManagerService在添加窗口的时候,就需要将这个Token的Binder和之前
ActivityManagerService保存在里面的Binder做比较,验证通过说明是合法的,否则,就会抛出BadTokenException这个异常。
activity界面最后是通过ViewRootImpl的setView方法连接WindowManagerService
从而让WindowManagerService将界面绘制到手机屏幕上
Dialog也是通过ViewRootImpl的setView连接Wms,完成界面的绘制
在创建dialog时,如果传入构造方法不是一个activity类型的上下文,则导致WindowManagerImpl类型为Window的变量mParentWindow,从而导致WindowManagerGlobal的addView不会调用Window的adjustLayoutParamsForSubWindow方法,从而不会给attr.token赋值,导致在WindowManagerService服务中的身份验证失败,抛出BadTokenException异常。