当前位置: 首页 > 科技观察

如何理解onStart可见但不可交互

时间:2023-03-15 01:37:43 科技观察

前言今天朋友遇到一道面试题分享给大家:onStart生命周期说明Activity是可见的,那为什么不能交互呢?这个问题看似简单,但还是涉及到很多方面,比如Activity生命周期的理解,流程的理解,View绘制的时机等。一起来看看吧。onStart介绍首先是关于onStart生命周期的理解。官网是这样的:当Activity进入“启动”状态时,系统会调用这个回调。onStart()调用使活动对用户可见,因为应用程序准备活动进入前台并支持交互。对用户可见?奇怪,用户可见,不就是我们能看到吗,为什么不能交互呢?更何况onStart的时候界面还没有画出来,这个visible怎么理解呢?做个小实验首先科普官方定义了两种状态。onStart和onStop之间的状态称为“已启动”状态。onResume和onPause之间的状态称为“已恢复”状态。然后我们做一个小实验,定义ActivityA和ActivityB,ActivityB是Dialog主题,在ActivityA中点击跳转到B:image.setOnClickListener{startActivity(Intent(this,ActivityB::class.java))}进入ActivityA后,点击按钮跳转到B,此时A的生命周期到达onPause,即回到started状态。此时界面是这样的:ActivityA处于启动状态,对用户可见。这里的可见性容易理解吗?它确实对我们可见,但它不在前台,无法交互。所以延伸到普通的Activity,这个可见性并不是说用户可以肉眼看到,而是想表达:Activity已经被显示了,但是它不在前台,所以只是可见,而不是交互的。这个可见状态从onStart开始,到onStop结束。我们可以把它分为两个阶段:onStart到onResume。这个阶段创建了Activity,加载了布局,但是还没有绘制界面,可以说界面不存在。onPause到onStop。这个阶段就是我们刚才做的实验。Activity有界面了,但是被新界面挡住了,也就是不在前台了。因此,结合这两个阶段,我们称这个activity被创建或显示,但不在前台,两者之间的状态称为可见状态。onStart和onResume至此,我们知道了可见性的含义,但是我们也知道了另外一个问题,就是为什么要设计onStart和onResume这两个状态。onStart和onStop是从Activity是否可见的角度来设计的。onResume和onPause是从Activity是否在前台的角度来设计的。所以Activity的生命周期可以理解为:创建(onCreate)—>可见(onStart)—>位于前台(onResume)—>可见但不在前台(onPause)可见的过程从另一个角度来看,这是可见的可以引用可见进程。这就涉及到流程的分类。为了确定内存不足时应终止哪些进程,Android根据其中运行的组件和这些组件的状态将每个进程放入“重要性层次结构”。这些进程类型包括(按重要性排序):前台进程、可见进程、服务进程和缓存进程。这些过程是什么意思?前台进程是用户当前需要执行操作的进程。例如,一个Activity(其onResume()方法已被调用)正在用户的交互屏幕上运行。可见进度是用户当前知道的任务。例如,一个正在运行的Activity在屏幕上对用户可见,但在前台不可见(它的onPause()方法已被调用)一个服务进程包含一个已使用startService()方法启动的Service。缓存进程是当前不需要的进程。例如当前不可见的一个或多个Activity实例(onStop()方法已经被调用并返回),那么Activity的生命周期可以分为进程:可见进程(onStart)-->前台进程(onResume)--->可见进程(onPause)-->缓存进程(onStop)这些进程有什么用?我们都知道Android系统中有很多正在运行的APP,它们分别代表着不同的进程。当内存不足(达到一定阈值)时,系统会先通过onTrimMemory()回调方法告诉应用程序,让应用程序在内存不足的情况下处理减内存操作。之后如果内存还是比较紧张,会杀掉一些进程来释放内存。这里需要判断进程的优先级,从优先级低的开始依次终止进程。所以,进程的分类函数就在这里。优先级的高低其实代表了进程终止的先后顺序,也代表了对用户的影响程度。当然,在实际代码中,进程优先级是用一个数字来表示的,即ADJ,上面提到的进程类型都有一个对应的进程优先级数字范围。例如:publicfinalclassProcessList{//可见进程staticfinalintVISIBLE_APP_ADJ=100;//前台进程staticfinalintFOREGROUND_APP_ADJ=0;//服务进程staticfinalintSERVICE_ADJ=500;//缓存进程staticfinalintCACHED_APP_MIN_ADJ=900;//...}回到我们的问题:其中,可见的概念在可见的过程中也出现在这里,给出的解释是:用户知道。当我们点击一??个页面的时候,我们知道会显示这个页面,同时我们也知道这个页面后面是上一个页面。所以这些页面和进程是我们所知道的,只是它们不在前台。所以onStart表示的visibility也可以理解为进程可见,也就是说这个Activity所在的进程任务已经创建并显示出来了。我们知道它,但它不在前台。Interactable那么在什么阶段可以发生交互呢?我们之前说过,在Activity的启动过程中会调用handleResumeActivity方法。在该方法中调用onResume方法和addView方法完成View的第一次绘制并显示在界面上。@OverridepublicvoidhandleResumeActivity(){//onResumefinalActivityClientRecordr=performResumeActivity(token,finalStateRequest,reason);//addViewif(r.window==null&&!a.mFinished&&willBeVisible){wm.addView(decor,l);}}onResume,View它被绘制并显示到前台。官网是这样解释onResume的:当Activity进入“resumed”状态时,会来到前台,然后系统调用onResume()回调。这是应用程序与用户交互的状态。应用程序将保持此状态,直到发生某些事件将焦点从应用程序上移开。此类事件包括来电、用户导航到另一个活动或设备屏幕关闭。所以交互状态应该在onResume之后,即Activity可见且在前台。总结:onStart状态表示Activity可见,visible表示Activity已经被创建并为用户所知,但是它不在前台,界面还没有绘制,所以无法进行交互。也可以表示它所在的进程是可见进程。它的可见的意思应该和onStop一起使用,即从onStart到onStop的阶段称为可见阶段。而真正可以交互的显示发生在onResume之后,也就是View被绘制出来,处于前台的时候。参考《Android开发艺术探索》https://juejin.cn/post/6896751245722615815https://juejin.cn/post/6891911483379482637本文转载自微信公众号“码上积木”,可通过以下二维码关注代码。转载本文请联系代码上的积木公众号。