Activity 及其 Views 生命周期如何在 android 中重叠

Posted

技术标签:

【中文标题】Activity 及其 Views 生命周期如何在 android 中重叠【英文标题】:How can Activity and its Views lifecycles overlap in android 【发布时间】:2020-06-08 17:16:33 【问题描述】:

android 中有两个生命周期,基本上是一个 Activity 生命周期和一个 View LifeCycle,但是 View LifeCycle 在 Activity 生命周期的哪个阶段启动? 从 View Lifecycle 启动的那一刻起,它一直贯穿它的生命周期,还是在活动生命周期的各个部分完成? (如果是,请说明在哪些部分调用了哪些方法)

【问题讨论】:

特别是对于生命周期,我建议您阅读 android 文档,因为它是一个非常基本且重要的概念。 @SazzadHissainKhan ,我有,但没有给出重叠 【参考方案1】:

这里不是一个 100% 的官方图表,它是我从官方 activity life cycle 和 view life cycle 混合而成的,因为我在 android 文档中没有看到任何关于视图生命周期的图表(如果我们可以调用它是一个生命周期)。

因此,在图表中,橙色箭头是在观察以下演示应用程序时添加的,仅用于演示两个生命周期的关系;我在其中创建了一个虚拟自定义 TextView 并记录了它的超类生命周期方法及其持有活动生命周期方法;并相应地添加橙色箭头。

因此,如图所示,活动由其onCreate() 创建,并且在活动的布局被setContentView() 膨胀之后,系统调用布局视图的构造函数来构造它们。

现在刚刚创建了活动并且构建了视图的实例;屏幕上仍然看不到任何东西;那么活动的onStart(),&onResume()方法被分别调用,因此活动现在在屏幕上可见;仍然没有画出来。

然后,当 Activity 的窗口已附加到窗口管理器时,将调用 Activity 的 onAttachedToWindow(),向要在 Activity 上绘制的底层视图发出绿灯。

此时,活动的生命被认为处于运行/活动状态。 在activity的onAttachedToWindow()之后,视图的onAttachedToWindow()在附加到activity的窗口时被调用,现在视图可以开始在屏幕上绘制了。

在屏幕上绘制视图会通过一系列调用来确定一些测量值,例如大小和属性;宽度、高度、颜色、文本、填充等内容。这需要调用measure() 几次;随后 onMeasure() 被调用

最终,onDraw() 被调用,它有一个画布参数,用作绘制视图的目标表面。

您可以在图中找到其余的绘图相关方法,您可以在here 中深入了解它们。

当activity被onDestroy()销毁时,那么在activity的主窗口从窗口管理器中分离出来之前,底层视图将首先抓住机会从activity的窗口中分离出来;当它到位时,视图的onDetachedFromWindow() 被调用以声明它已从屏幕上移除,因此现在可以将活动从窗口管理器中分离出来;发生这种情况时,将相应地调用活动的onDetachedFromWindow()

因此,除非所有视图都先从窗口中分离,否则 Activity 不会从窗口管理器中分离。

所以,视图上没有像onDestroy() 这样的东西,视图可以从活动的窗口附加或分离;您可以查看this 的答案。另外views的onDetachedFromWindow()和activity的onDestroy()是高度耦合的,如果调用activity的onStop(),view仍然是附着在activity的窗口上的。

所以,没有这样的事情可以称为视图被销毁,而是视图被分离。

还要注意,活动和视图的onAttachedToWindow() 与活动的onCreate() 非常耦合;所以当activity的onRestart()被调用时,activity及其视图已经与窗口相关联,所以onAttachedToWindow()没有被调用(这在图上不太清楚)。

同样,onDetachedFromWindow() 的视图和活动仅与 onDestroy() 相关联;所以当活动暂停或停止时,onDetachedFromWindow() 不会调用,因此视图仍然附加到窗口。

您也可以使用parentLayout.removeView(customView); 并观察回调。

以下是用于进行此观察的演示示例

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:gravity="center"
    android:orientation="vertical">

    <com.example.android.androidxtest.CustomTextView
        android:layout_
        android:layout_
        android:text="@string/long_text"
        android:textSize="22sp" />

</LinearLayout>

活动

public class LifeCycleActivity extends AppCompatActivity 

    private static final String TAG = "LOG_TAG_ACTIVITY";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        setContentView(R.layout.activity_view_lifecycle);
        Log.d(TAG, "onCreate: after setContentView()");
    

    @Override
    protected void onPause() 
        super.onPause();
        Log.d(TAG, "onPause: ");
    

    @Override
    protected void onDestroy() 
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    

    @Override
    protected void onResume() 
        super.onResume();
        Log.d(TAG, "onResume: ");
    

    @Override
    protected void onStop() 
        super.onStop();
        Log.d(TAG, "onStop: ");
    

    @Override
    protected void onStart() 
        super.onStart();
        Log.d(TAG, "onStart: ");
    

    @Override
    protected void onRestart() 
        super.onRestart();
        Log.d(TAG, "onRestart: ");
    


    @Override
    public void onAttachedToWindow() 
        super.onAttachedToWindow();
        Log.d(TAG, "onAttachedToWindow: ");
    

    @Override
    public boolean isDestroyed() 
        Log.d(TAG, "isDestroyed: ");
        return super.isDestroyed();
    

    @Override
    public void onDetachedFromWindow() 
        super.onDetachedFromWindow();
        Log.d(TAG, "onDetachedFromWindow: ");
    



自定义视图

public class CustomTextView extends TextView 

    private static final String TAG = "LOG_TAG_VIEW";

    public CustomTextView(Context context) 
        super(context);
        Log.d(TAG, "CustomTextView: Constructor");
    

    public CustomTextView(Context context, @Nullable AttributeSet attrs) 
        super(context, attrs);
        Log.d(TAG, "CustomTextView: Constructor");
    

    public CustomTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        Log.d(TAG, "CustomTextView: Constructor");
    

    public CustomTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) 
        super(context, attrs, defStyleAttr, defStyleRes);
        Log.d(TAG, "CustomTextView: Constructor");
    

    @Override
    protected void onAttachedToWindow() 
        super.onAttachedToWindow();
        Log.d(TAG, "onAttachedToWindow: ");
    

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d(TAG, "onMeasure: ");
    

    @Override
    public void layout(int l, int t, int r, int b) 
        super.layout(l, t, r, b);
        Log.d(TAG, "layout: ");
    


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
        super.onLayout(changed, left, top, right, bottom);
        Log.d(TAG, "onLayout: ");
    

    @Override
    protected void dispatchDraw(Canvas canvas) 
        super.dispatchDraw(canvas);
        Log.d(TAG, "dispatchDraw: ");
    

    @Override
    public void draw(Canvas canvas) 
        super.draw(canvas);
        Log.d(TAG, "draw: ");
    

    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        Log.d(TAG, "onDraw: ");
    

    @Override
    protected void onDetachedFromWindow() 
        super.onDetachedFromWindow();
        Log.d(TAG, "onDetachedFromWindow: ");
    


登录应用启动

2020-02-25 14:09:41.859 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onCreate: 
2020-02-25 14:09:41.945 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: CustomTextView: Constructor
2020-02-25 14:09:41.945 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onCreate: after setContentView()
2020-02-25 14:09:41.947 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStart: 
2020-02-25 14:09:41.954 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onResume: 
2020-02-25 14:09:41.984 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onAttachedToWindow: 
2020-02-25 14:09:41.985 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onAttachedToWindow: 
2020-02-25 14:09:41.993 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 14:09:42.005 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 14:09:42.006 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onLayout: 
2020-02-25 14:09:42.006 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: layout: 
2020-02-25 14:09:42.032 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onDraw: 
2020-02-25 14:09:42.032 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: dispatchDraw: 
2020-02-25 14:09:42.032 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: draw: 

登录菜单按钮(应用历史记录)

2020-02-25 13:44:44.462 32357-32357/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onPause: 
2020-02-25 13:44:44.511 32357-32357/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStop: 

从菜单按钮(应用历史记录)重新登录到我们的应用

2020-02-25 14:11:23.387 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onRestart: 
2020-02-25 14:11:23.392 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStart: 
2020-02-25 14:11:23.394 2043-2043/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onResume: 
2020-02-25 14:11:23.405 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 14:11:23.420 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onLayout: 
2020-02-25 14:11:23.420 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: layout: 
2020-02-25 14:11:23.424 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onDraw: 
2020-02-25 14:11:23.424 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: dispatchDraw: 
2020-02-25 14:11:23.424 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: draw: 
2020-02-25 14:11:23.455 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 14:11:23.460 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 14:11:23.460 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onLayout: 
2020-02-25 14:11:23.460 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: layout: 
2020-02-25 14:11:23.461 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: onDraw: 
2020-02-25 14:11:23.461 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: dispatchDraw: 
2020-02-25 14:11:23.462 2043-2043/com.example.android.androidxtest D/LOG_TAG_VIEW: draw: 

登录配置更改(轮换)

2020-02-25 17:05:00.481 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onPause: 
2020-02-25 17:05:00.492 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStop: 
2020-02-25 17:05:00.493 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onDestroy: 
2020-02-25 17:05:00.512 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onDetachedFromWindow: 
2020-02-25 17:05:00.517 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onDetachedFromWindow: 
2020-02-25 17:05:00.563 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onCreate: 
2020-02-25 17:05:00.600 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: CustomTextView: Constructor
2020-02-25 17:05:00.601 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onCreate: after setContentView()
2020-02-25 17:05:00.604 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStart: 
2020-02-25 17:05:00.611 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onResume: 
2020-02-25 17:05:00.626 8058-8058/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onAttachedToWindow: 
2020-02-25 17:05:00.626 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onAttachedToWindow: 
2020-02-25 17:05:00.629 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 17:05:00.659 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onMeasure: 
2020-02-25 17:05:00.659 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onLayout: 
2020-02-25 17:05:00.660 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: layout: 
2020-02-25 17:05:00.674 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: onDraw: 
2020-02-25 17:05:00.674 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: dispatchDraw: 
2020-02-25 17:05:00.674 8058-8058/com.example.android.androidxtest D/LOG_TAG_VIEW: draw: 

后按

2020-02-25 16:10:24.743 7314-7314/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onPause: 
2020-02-25 16:10:25.341 7314-7314/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onStop: 
2020-02-25 16:10:25.343 7314-7314/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onDestroy: 
2020-02-25 16:10:25.343 7314-7314/com.example.android.androidxtest D/LOG_TAG_VIEW: onDetachedFromWindow: 
2020-02-25 16:10:25.344 7314-7314/com.example.android.androidxtest D/LOG_TAG_ACTIVITY: onDetachedFromWindow: 

【讨论】:

感谢您的出色回答,但视图如何被破坏?它是否会被 Activity 的onDestroy 销毁(这意味着会有重叠)? @juztcode 欢迎,我们可以称视图正在从窗口分离;文档中没有提到可以销毁视图;这样他们就可以从窗口附加/分离;在调用onDestroy() 之后发生的所有事情...请检查答案并更新图表和 logcat 输出...抱歉,如果那很长 时间不长就不好玩了。 ;-) 感谢伙伴的帮助。但是,如果你知道我想问你这个问题:***.com/questions/60390655/…,如果我问的是窃听你,请忽略它,但我非常感谢任何帮助。 :)【参考方案2】:

每个 android 组件都有自己的生命周期。服务,视图,片段,活动,... 我建议您先查阅 Android 文档以了解它的基本概念。

【讨论】:

我有,但没有给出重叠(但我记得还有其他生命周期,如你提到的片段和服务_) 也许您可以尝试添加一个包含所有可能日志的示例,以查看何时发生任何事件 =) 我想这是一种方式,但(人)我不知道为什么这个 android 文档甚至没有某种框架描述他们的东西是如何工作的,【参考方案3】:

视图生命周期不会干扰活动生命周期。与其他类型的生命周期相同。视图的生命周期只有在视图被添加到屏幕时才会启动。

【讨论】:

那是activity生命周期结束的时间?

以上是关于Activity 及其 Views 生命周期如何在 android 中重叠的主要内容,如果未能解决你的问题,请参考以下文章

监听Activity生命周期方式及案例讲解

Activity和Fragment的生命周期及其各个阶段的状态

Android之Activity生命周期的浅析

android对应生命周期中应该释放哪些资源

android之Activity的生命周期

如何理解Activity 的生命周期