2024年最全android四大组件之Activity,2024年最新字节跳动三面是谁面

文末

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

典型情况下的生命周期分析

  • onCreate():Activity正在被创建。

  • onRestart():Activity正在重新启动。

  • onStart():Activity正在被启动;当前状态表示已经可见,但是无法交互,还没有显示在前台。

  • onResume():Activity已经可见了,并且出现在前台并开始活动。表示Activity已经显示在前台,并且可以交互了。

  • onPause():Activity正在停止,前端不可显示,但是还在后台运行。

  • onStop():Activity即将停止。

    onPause()和onStop()两个方法被执行的时候都不能做耗时操作。

  • onDestroy():Activity即将被销毁,这是生命周期最后一个回调,释放资源和内存。

onStart和onStop是从Activity是否可见来回调的。

onResume和onPause是从Activity是否位于前台来回调的。

图片来与网络

针对上图,再附加一下具体说明,但图中容易理解的不再赘述。

  • 当前已有一个Activity时,当用户打开新的Activity或者切换到桌面时,回调onPause -> onStop。

    即当前Activity已经看不见,因为切换到了桌面,所以当前Activity不可见,由于onPause关键在于是否位于前台,onStop关键在于是否可见,所以要执行到onStop才可以。

  • 有一种特殊情况,如果新的Activity采用了透明主题,那么当前的Activity不会回调onStop方法。

    是新打开的Activity是透明主题,不是原来的,所以原来那个Activity位于当前透明主题的Activity的下方,根据Activity栈,可以看见原来的Activity,但是无法和用户进行交互,所以是可见但是不位于前台,所以onStop不执行。

  • 当用户按back键回退时,从onPause一直回调至onDestroy。

    back键是返回上级菜单,即返回上一个Activity,所以当前Activity会被销毁,执行至onDestroy;home键是返回主菜单,就好像桌面一样,只执行到onStop。

异常情况下的生命周期分析

异常情况下Activity的生命周期

  1. 资源相关的系统配置发生改变导致Activity被杀死并重新创建。

    资源配置发生改变,比如屏幕的朝向(横竖屏),Activity会被销毁并且重新创建。

    由于在异常情况下终止的,系统调用onSaveInstanceState保存当前Activity的状态和数据,并将其封装为Bundle对象,在后面调用onRestoreInstanceState方法时作为参数传入,这个方法在onStop之前,并且只有在Activity异常终止的情况下才会被调用。

    重新创建后,系统在onCreate新建Activity之后,在onStart之后调用onRestoreInstanceState来恢复数据。这个方法也只有在异常终止恢复数据时才会被调用,不然不会调用这个方法,而是正常创建新的Activity。

  2. 系统内存不足导致低优先级的Activity被杀死。

    Activity优先级:

    • 前台Activity——正在和用户交互的Activity,优先级最高。

    • 可见但是非前台Activity——例如弹出一个对话框,使Activity位于后台,无法和用户直接交互,优先级较高。

    • 后台Activity——已经被暂停的Activity,如执行了onStop的,优先级最低。

      当内存不够时,按照上述优先级进行销毁,在后续通过onSaveInstanceState和onRestoreInstanceState方法来恢复使用。

想要不重新创建Activity也是有方法的,在系统资源配置中设置configChanges的属性即可。

启动模式

===================================================================

如何指定Activity的启动模式?

  1. 在AndroidMenifest中使用launchMode属性即可。

android:launchMode="singleTask"



  1. 通过Intent来设置标志位启动。

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);



  • 当两种方式同时存在时,以第二种为主,优先级高。
  • 第一种方式无法直接为Activity指定FLAG_ACTIVITY_CLEAR_TOP标识
  • 第二种方式无法为Activity直接设定singleInstance模式。

standard(标准模式)

标准模式是系统的默认启动模式,每次启动一个Activity都会建立一个新的实例,不在乎这个实例是否存在。这是一种多实例的实现,一个任务栈可以有多个实例,一个实例也可以在多个任务栈

启动一个Activity的必须是一个Activity,否则会报错,因为Activity一定有一个栈,被启动的Activity会进入启动它的Activity的任务栈中,但是如果启动它的对象没有任务栈,就会出现错误。防止其发生错误也有方法,就是为将要启动的Activity加一个标志位,但是这时已经不能算是一个真正的标准模式启动了。

singleTop(栈顶复用模式)

栈顶复用模式很简单,就如同它的名字一样,就是把位于栈顶的Activity复用

  1. 如果在一个任务栈中已存在待启动的Activity并且其位于栈顶,那么它不会被重新创建一个新的实例,即上面生命周期的onCreate和onStart不会被调用,而是调用onNewIntent方法(这个方法现在我也不了解),这个方法是用来取出当前请求的信息的。

  2. 如果这个Activity存在但是不位于栈顶,那么还是需要重新创建实例并压入栈内。

singleTask(栈内复用模式)

栈内复用模式是Activity启动模式中最复杂的一个模式,是一个单实例模式。

4. 当一个Activity以这个模式启动时,系统会寻找它要的任务栈,如果不存在这个栈,会创建这个栈并且实例化这个Activity并将其压入栈内。

5. 如果这个栈存在,但是当中没有待启动的Activity,则将Activity实例化并压入栈内。

6. 如果栈存在,并且其中有了待启动的Activity,位于栈顶,则是栈顶复用模式;不位于栈顶,则将其移到栈顶,调用onNewIntent方法,但是在其上的Activity全部要出栈。因为singleTask默认具有clearTop效果

说到singleTask模式还要说一个参数:TaskAffinity。

可翻译为任务相关性,就是用来存Activity所在的任务栈的名字

  • 这个属性值不能和包名相同,否则相当于没有指定。

  • 这个属性要和singleTask模式或者allowTaskReparenting属性配对使用,其他情况下无意义。

举个例子,方便理解,allowTaskReparenting属性我也不清楚意思,但是当一个Activity的这个属性值为true时,好像就是允许Activity的迁移,有点像小狗认主人。

假设应用A启动了应用B的一个Activity C,B的allowTaskReparenting属性值为true,当A启动C时,C跑到A的任务栈里了,但是当B启动时,由于C的TaskAffinity的属性值为B的任务栈,并且其allowTaskRepareting属性为true,所以C又回到了B的任务栈中。

简单来说,就是你在路边捡到一只小狗,你养了几天,以为小狗是自己的了,然后它主人来了,小狗还是跟着主人走了。(此例子参考了一个博客)

singleInstance(单实例模式)

单实例模式是一种加强的栈内复用模式,除了具有singleTask模式的所有特性外,还有独特的一点。即具有这种启动模式的Activity只能单独的在一个任务栈中,这个任务栈也只能有其一个Activity,也就是多了一个任务栈

应用场景


  • Standard:非以下特殊场景的普通Activity

  • SingleTop:APP接收到多条推送消息,点开不同消息,均由同一实例展示。singleTop适合接收推送通知的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。

  • SingleTask:应用APP的主界面(Fragment的containerActivity)。singleTask适合作为程序入口点。例如淘宝的主界面,在淘宝陆续打开商品搜索界面、商品详细界面、订单界面、付款成功界面后,在付款成功界面一键返回主界面。

  • SingleInstance:如APP经常调用的拨打电话、系统通讯录、系统Launcher、锁屏键、来电显示等系统应用。singleInstance适合需要与程序分离开的页面。例如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。

工作原理

===================================================================

Activity的启动


Intent intent = new Intent(this,TestActivity.class);

startActivity(intent);



Activty的启动过程中的方法调用过程

  1. Activity的startActivity
  1. startActivityForResult
  1. Instrumentation.execStartActivity
  1. ActivityManagerNative.getDefault().startActivity
  1. AMS.startActivity
  1. startActivityAsUser
  1. ActivityStackSupervisor.startActivityMayWait
  1. startActivityLocked
  1. startstartActivityUncheckedLocked
  1. ActivityStack.resumeTopActivitiesLocked
  1. ActivityStack.resumeTopActivityInnerLocked
  1. startSpecificActivityLocked
  1. realStartActivityLocked
  1. app.thread.scheduleLaunchActivity
  1. ApplicationThead.scheduleLaunchActivity
  1. handleLaunchActivity
  1. ActivityThread.performLaunchActivity

1到2

虽然startActivity有很多重载方式,但它们最终都会调用startActivityForResult方法。

2到3

startActivityForResult方法中有如下代码:

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread(),mToken,this,intent,requestCode,options);

注意:

mMainThread.getApplicationThread()这个参数,它的类型是ApplicationThread,ApplicationThread是ActivityThread的一个内部类。

3到4

execStartActivity 的代码如下:


int result = ActivityManagerNative.getDefault()

   .startActivity(whoThread,who.getBasePackageName(),intent,

           intent.resolveTypeIfNeeded(who.getContentResolver()),

           token,target != null ? target.mEmbeddedID : null,

           requestCode, 0, null, options);

checkStartActivityResult(result,intent);



由上述代码可见,Activity的真正实现由ActivityManagerNative.getDefault()的startActivity方法来完成。

checkStartActivityResult的作用:检查启动的Activity的结果。无法启动时,抛出一个异常。

4到5

ActivityManagerService(AMS) extends ActivityManagerNative

ActivityManagerNative extends Binder implements IActivityManager(Binder接口)

所以AMS也是一个Binder,是IActivityManager的具体实现。

结语

  • 现在随着短视频,抖音,快手的流行NDK模块开发也显得越发重要,需要这块人才的企业也越来越多,随之学习这块的人也变多了,音视频的开发,往往是比较难的,而这个比较难的技术就是NDK里面的技术。
  • 音视频/高清大图片/人工智能/直播/抖音等等这年与用户最紧密,与我们生活最相关的技术一直都在寻找最终的技术落地平台,以前是windows系统,而现在则是移动系统了,移动系统中又是以Android占比绝大部分为前提,所以AndroidNDK技术已经是我们必备技能了。
  • 要学习好NDK,其中的关于C/C++,jni,Linux基础都是需要学习的,除此之外,音视频的编解码技术,流媒体协议,ffmpeg这些都是音视频开发必备技能,而且
  • OpenCV/OpenGl/这些又是图像处理必备知识,下面这些我都是当年自己搜集的资料和做的一些图,因为当年我就感觉视频这块会是一个大的趋势。所以提前做了一些准备。现在拿出来分享给大家。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

料和做的一些图,因为当年我就感觉视频这块会是一个大的趋势。所以提前做了一些准备。现在拿出来分享给大家。

[外链图片转存中…(img-5iJHR0ac-1715850321073)]

[外链图片转存中…(img-Zapyv6bc-1715850321073)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值