Activity相关面试题

1、Activity的启动流程

Activity 启动主要涉及到3个进程:

  • 系统进程 SystemServer (负责管理整个framework,是Zygote孵化的第一个进程)
  • App进程(App进程是用户点击桌面icon时,通过Launcher进程请求SystemServer,再调用Zygote孵化的)
  • Zygote进程(所有进程孵化都由Zygote完成,而Zygote是init进程的子进程,也由init进程孵化)
  • 如果点击桌面icon启动还会涉及到 Launcher进程(Zygote孵化的第一个应用进程)

以点击Launcher的一个icon为开始,整体扯一下Activity的启动过程,桌面其实就是LauncherApp的一个Activity

  1. 当点击Launchericon开始,Launcher进程会像AMS发送点击icon的启动信息(这些信息就是在AndroidMainifest.xml中标签定义的启动信息,数据由PackageManagerService解析出来);
  2. AMS收到信息后会先后经过ActivityTaskManagerService->ActivityStartController->ActivityStarter内部类Request,然后把信息存到Request中,并通知Launcher进程让Activity休眠;

(补充个小知识点,这个过程会检测ActivityAndroidMainifest.xml的注册,如果没有注册就报错了)

  1. Launcher进程的ApplicationThread对象收到消息后调用handlePauseActivity()进行暂停,并通知AMS已经暂停。实现细节:ActivityThread.sendMessage()通过ActivityThread的H类发送Handler消息,然后触发 mTransactionExecutor.execute(transaction),执行过程中依赖ActivityClientRecord.mLifecycleState数值并通过ClientTransactionHandler抽象类的实现(ActivityThread)进行分发;

注 :ActivityClientRecord.mLifecycleState(-1 ~ 7分别代表 UNDEFINED, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_RESTART)

  1. AMS收到Launcher的已暂停消息后,会检查要启动的Activity所在的进程是否已经启动了,如果已经启动了就打开,如果未启动则通过**Process.start(android.app.ActivityThread)**来启动一个新的进程;
  2. 进程创建好以后,会调用ActivityThread.main(),初始化MainLooper,并创建Application对象。然后Instrumentation.newApplication()反射创建Application,创建ContextImpl通过Applicationattach方法与Application进行绑定,最终会调用Instrumentation.callApplicationOnCreate执行ApplicationonCreate函数进行一些初始化的工作。完成后会通知AMS进程已经启动好了;

通知过程:通过IActivityManager.attachApplication(IApplicationThread thread,long startSeq),将Application对象传入AMS;

  1. AMS收到app进程启动成功的消息后,从ActivityTaskManagerService中取出对应的Activity启动信息, 并通过ApplicationThreadProxy对象,调用其scheduleTransaction(ClientTransaction transaction)方法,具体要启动的Activity都在ClientTransaction对象中;
  2. app进程的ApplicationThread收到消息后会调用ActiivtyThread.sendMessage(),通过H发送Handler消息,在handleMessage方法的内部又会调用 mTransactionExecutor.execute(transaction);具体参考第3步;

最终调用performLaunchActivity方法创建activitycontext并将其做关联,然后通过**mInstrumentation.callActivityOnCreate()->Activity.performCreate()->Activity.onCreate()**回调到了Activity的生命周期。

2、onSaveInstanceState(),onRestoreInstanceState()的掉用时机

Android系统的回收机制会在未经用户主动操作的情况下销毁Activity,而为了避免系统回收Activity导致数据丢失,Android为我们提供了onSaveInstanceState(Bundle outState)和onRestoreInstanceState(Bundle savedInstanceState)用于保存和恢复数据。

当activity有可能被系统回收的情况下,而且是在onStop()之前。注意是有可能,如果是已经确定会被销毁,比如用户按下了返回键,或者调用了finish()方法销毁activity,则onSaveInstanceState不会被调用。

总结下,onSaveInstanceState(Bundle outState)会在以下情况被调用:

  1. 当用户按下HOME键时。
  2. 从最近应用中选择运行其他的程序时。
  3. 按下电源按键(关闭屏幕显示)时。
  4. 从当前activity启动一个新的activity时。
  5. 屏幕方向切换时(无论竖屏切横屏还是横屏切竖屏都会调用)。

onRestoreInstanceState(Bundle savedInstanceState)只有在activity确实是被系统回收,重新创建activity的情况下才会被调用。

比如第5种情况屏幕方向切换时,activity生命周期如下:
onPause -> onSaveInstanceState -> onStop -> onDestroy -> onCreate -> onStart -> onRestoreInstanceState -> onResume
在这里onRestoreInstanceState被调用,是因为屏幕切换时原来的activity确实被系统回收了,又重新创建了一个新的activity。

而按HOME键返回桌面,又马上点击应用图标回到原来页面时,activity生命周期如下:
onPause -> onSaveInstanceState -> onStop -> onRestart -> onStart -> onResume
因为activity没有被系统回收,因此onRestoreInstanceState没有被调用。

如果onRestoreInstanceState被调用了,则页面必然被回收过,则onSaveInstanceState必然被调用过。

3、activity的启动模式和使用场景

  1. standard:标准模式:如果在mainfest中不设置就默认standard;standard就是新建一个Activity就在栈中新建一个activity实例;
  2. singleTop:栈顶复用模式:与standard相比栈顶复用可以有效减少activity重复创建对资源的消耗,但是这要根据具体情况而定,不能一概而论;
  3. singleTask:栈内单例模式,栈内只有一个activity实例,栈内已存activity实例,在其他activity中start这个activity,Android直接把这个实例上面其他activity实例踢出栈GC掉;
  4. singleInstance :堆内单例:整个手机操作系统里面只有一个实例存在就是内存单例;
LauchModeInstance
standard邮件、mainfest中没有配置就默认标准模式
singleTop登录页面、WXPayEntryActivity、WXEntryActivity 、推送通知栏
singleTask程序模块逻辑入口:主页面(Fragment的containerActivity)、WebView页面、扫一扫页面、电商中:购物界面,确认订单界面,付款界面
singleInstance系统Launcher、锁屏键、来电显示等系统应用

4、Activity A跳转Activity B,再按返回键,生命周期执行的顺序

当A跳转到B的时候,A先执行onPause,然后是B执行onCreate -> onStart -> onResume,最后才执行A的onStop。

当B按下返回键,B先执行onPause,然后是A执行onRestart -> onStart -> onResume,最后才是B执行onStop -> onDestroy。

5、横竖屏切换,按home键,按返回键,锁屏与解锁屏幕,跳转透明Activity界面,启动一个 Theme 为 Dialog 的 Activity,弹出Dialog时Activity的生命周期

  1. 横竖屏切换:onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume
  2. 按Home键:onPause -> onStop
  3. 按返回键:onPause -> onStop -> onDestroy
  4. 锁屏与解锁: onPause -> onStop -> onRestart -> onStart -> onResume
  5. 跳转透明Activity: A onPasue -> B onCreate -> B onStart -> B onResume -> B onPasue-> A onResume -> B onStop -> B onDestroy
  6. 启动一个 Theme 为 Dialog 的 Activity: 同5
  7. 弹出Dialog:什么都不调用

6、onStart和onResume、onPause和onStop有什么不同

首先来说一下onStart和onResume,虽然onStart已经是启动了,但是界面只是在后台运行并没有显示在前台,而是到onResume时界面才运行到了前台;onPause和onStop也是如此,到了onStop时界面已经在前台不可见了。

7、Activity之间传递数据的方式Intent是否有大小限制,如果传递的数据量偏大,有哪些方案

  1. 传512K以下的数据的数据可以正常传递。
  2. 传512K~1024K的数据会出错,闪退。
  3. 传1024K以上的数据会报错:TransactionTooLargeException。
  4. 考虑到Intent还包括要启动的Activity等信息,实际可以传的数据略小于512K

数据偏大时的方案:

  1. 将数据保存早全局Application中
  2. 使用单例数据类
  3. 持久化数据

8、Activity的onNewIntent()方法什么时候会执行

前提:Activity A已经启动过,处于当前应用的Activity堆栈中:

  1. 当Activity A的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法;
  2. 当Activity A的LaunchMode为SingleInstance,SingleTask时,如果已经Activity A已经在堆栈中,那么此时会调用onNewIntent()方法;
  3. 当Activity A的LaunchMode为Standard时,由于每次启动Activity A都是启动新的实例,和原来启动的没关系,所以不会调用原来ActivityA的onNewIntent方法。

9、显示启动和隐式启动

1、隐式启动Activity
优点:

  • 只要知道被启动Activity的Action和Category即可,不用知道对应的类名或者是包名。
  • 只要Activity有对应的action和Category都会被启动起来。然后提供给用户选择要启动哪一个。

2、显式的启动

  • 通过类名类启动Activity, 一般是同一个APK里面使用
  • 通过包名加类名启动
    不足:被启动的应用的包名或者类名发生变化后,就会无法启动。
  • 通过ComponentName启动
    不足:被启动的应用的包名或者类名发生变化后,就会无法启动。

10、ANR 的四种场景

  1. Service Timeout:Service在特定的时间内无法处理完成
  2. BroadcastQueue Timeout:BroadcastReceiver在特定时间内无法处理完成
  3. ContentProvider Timeout:内容提供者执行超时
  4. inputDispatching Timeout: 按键或触摸事件在特定时间内无响应。

11、onCreate和onRestoreInstance方法中恢复数据时的区别

  1. 因为onSaveInstanceState 不一定会被调用,所以onCreate()里的Bundle参数可能为空,如果使用onCreate()来恢复数据,一定要做非空判断。而onRestoreInstanceState的Bundle参数一定不会是空值,因为它只有在上次activity被回收了才会调用。
  2. onRestoreInstanceState是在onStart()之后被调用的。有时候我们需要onCreate()中做的一些初始化完成之后再恢复数据,用onRestoreInstanceState会比较方便。

Activity相关基础知识可以参考之前的文章:

Activity相关基础知识

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值