Activity总结

作者: DageHao | 来源:发表于2018-12-03 18:04 被阅读10次

    前言:Activity是android四大组件之一,同时也是在开发时用到最多的组件,但要细分的话知识点也是挺多的,通过这篇文章进行总结。

    一.Activity的四种状态

    activity的四种状态

    二.Activity的生命周期(正常情况下)

    activity生命周期
    生命周期 说明
    onCreate() Activity已经被创建完毕,当Activity第一次启动的时候,触发该方法,可以在此时完成Activity的初始化工作。
    onStart() 此方法在活动由不可见变为可见时调用,此时activity已经显示在屏幕上,但没有获得焦点
    onResume() 此方法在活动准备好和用户交互时地阿偶用,activity得到焦点。此时的活动已定位与返回栈的栈顶,并且处于运行状态
    onPause() 此方法在活动失去焦点,无法再与用户交互,但依然可见。当一个正在前台运行的Activity因为其他的Activity需要前台运行而转入后台运行的时候,触发该方法。
    onStop() 此方法在活动完全不可见时调用。但注意,所有保存信息的工作都不应该在此方法中进行,应该在onPause中进行
    onDestroy() 此方法在活动被销毁前调用。但是注意,内存紧张时,系统会直接杀死活动而不会调用onDestory或onStop方法
    onResstart() 当处于停止状态的Activity需要再次展现给用户的时候,触发该方法,即从不可见变成可见时会执行此方法

    以上的7个方法除了onResstart方法外,其他都是两两相对的,从而又可以将活动分为3种生存期

    • 完整生存期:onCreate→onDestory
    • 可见生存期:onStart→onStop
    • 前台生存期:onResume→onPause
    正常生命周期中一些常见的问题

    1.什么情况下会执行:onPause()->onResume()

    1.在当前Activity上面有个Dialog,并且退出Dialog
    2.Activity先执行onPause()处于可见、不可交互,然后回到onResume()进入可交互状态。

    2.什么情况下会执行:onStop()->onRestart()->onResume()

    1.从新的Activity返回到当前Activity时
    2.切换到桌面,又切换回当前Activity。

    3.什么情况下执行: onPause()->onCreate() 或者 onStop()->onCreate()

    系统内存不足,导致Activity在对应周期被杀死。然后重建该Activity

    4.onCreate()和onStart()的区别

    1.执行1次/执行多次
    2.onCreate()能做的, onStart()都能做, 除非只适合执行一次的逻辑
    3.onCreate()处于不可见,onStart()可见但不可交互

    5.什么情况下执行: onPause()->onCreate() 或者 onStop()->onCreate()

    系统内存不足,导致Activity在对应周期被杀死。然后重建该Activity

    6.onStart和onResume的区别

    1.均可见,前者不可交互,后者可交互
    2.官方建议onResume()中可以做开启动画和独占设备的操作

    7.onPause和onStop的区别

    1.前者可见,后者不可见
    2.内存不足时一定会执行onPause(),onStop()不一定执行
    3.保存数据最好在onPause()中,但不能太耗时
    4.尽量将重量级操作放在onStop()中能够提高打开新Activity的速度(onPause()会影响新Activity的创健)

    8.onStop和onDestory的区别

    1.onStop()时,Activity依旧在内存中,可以切换回该Activity。
    2.onDestory()时,已经被系统释放了

    三.Activity的生命周期(异常情况下)

    1.Activity异常生命周期

    是指Activity被系统回收或者由于当前设备的Configuration(方向)发生改变从而导致Activity被销毁重建

    生命周期 说明
    onSaveInstanceState(bundle outState) Activity被销毁时调用,保存重要信息,用于恢复
    onRestoreInstanceState(bundle savedInstanceState) 重建时调用,会将bundle传递到onCreate()

    1.用户主动销毁Activity不会触发onSaveInstanceState(),如finish()、按下回退键退出Activity
    2.按下HOME键、按下电源键、启动其他Activity、横竖屏切换: 如果导致了Activity的重建,会触发onSaveInstanceState()

    2.什么情况下可能会导致Activity的重建?

    1.按下HOME键
    2.按下电源键
    3.启动其他Activity
    4.横竖屏切换

    3.如果Activity被意外关闭,如何判断Activity是否被重建?

    1.通过onRestoreInstanceState()onCreate()方法来判断。
    2.onRestoreInstanceStae()被调用,或者onCreate()的参数Bundle不为null。都表明Activity被重建
    3.因为Activity被异常关闭后,那么系统会调用onSaveInstanceState()保存当前Activity的状态。

    4.资源相关的系统配置改变导致Activity的杀死并重建
    场景: Activity的横竖屏切换

    1.系统配置改变后,Activity会被销毁,其onPause()onStop()onDestory()均会被调用
    2.系统会额外调用onSaveInstanceState()来保存当前Activity的状态, 调用时机在onPause()前后(onStop()之前)
    3.Activity重新创建后,会调用onRestoreInstanceState()并且把onSaveInstanceState()保存的Bundle对象作为参数同时传递给onRestoreInstanceState()onCreate(), 其调用时机在onStart()之后
    4.系统会默认保存当前Activity的视图结构并且恢复一定数据。根据每个View的onSaveInstanceState()onRestoreInstanceState()可以知道系统能自动恢复哪些数据。

    5.系统保存和恢复View层次结构的工作流程

    1.Activity被意外终止时,会调用onSaveInstanceState()去保存数据
    2.Activity去委托Window保存数据
    3.Window再委托顶层容器去保存数据(ViewGroup:一般是DecorView)
    4.顶层容器最后一一通知其子元素保存数据

    横竖屏切换

    1.如何在Activity禁止横竖屏切换?

    1.在AndroidManifest中给相应的Activity添加上属性android:screenOrientation="portrait"
    2.portrait为竖屏
    3.landscape为横屏
    4.或者可以在onCreate中添加代码setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT/LANDSCAPE);
    5.最终会禁止横竖屏切换,也不会触发保存数据/恢复数据的回调

    2.如何实现Activity在横竖屏切换时,禁止Activity的重建?(通过configChanges实现)

    1.给Activity添加属性:android:configChanges="orientation|screenSize"
    2.Activity不会再销毁和重建,只会调用onConfigurationChanged()方法,可以进行特殊处理。

    3.禁止了Activity的横竖屏切换(重建)后, 什么回调方法会在横竖屏切换时被调用?

    onConfigurationChanged()

    4.通过禁止了横竖屏从而禁止了Activity的重建,既然Activity不再会重建,也就不需要再去处理数据的保存和恢复?

    错误!
    内存不足时,依旧可能会出现Activity被杀死并且重建的情况。

    四.Activity的跳转和数据传输

    显式 Intent:按名称(完全限定类名)指定要启动的组件。 通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务的类名。例如,启动新 Activity 以响应用户操作,或者启动服务以在后台下载文件。
    隐式 Intent:不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。 例如,如需在地图上向用户显示位置,则可以使用隐式 Intent,请求另一具有此功能的应用在地图上显示指定的位置。

    1.使用显示intent

    Intent intent = new Intent(MainActivity.this,SecondActivity.class);
    startActivity(intent);
    
    intent_1

    2.使用隐式intent
    通过配置在<activity>标签下的<intent-filter>的内容,制定当前活动能够响应的action和category。

      <activity android:name=".SecondActivity">
                <intent-filter>
                    <action android:name="com.example.activitytest.ACTION_START"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
      </activity>
    

    修改点击事件中的代码

    Intent intent = new Intent("com.example.activitytest.ACTION_START");
    //如果需要添加Category,需要在intent-filter标签中加上声明
    //intent.addCategory("com.example.activitytest.MY_CATEGORY_1");
    //intent.addCategory("com.example.activitytest.MY_CATEGORY_2");
    startActivity(intent);
    

    3.向下一个活动传递数据
    修改mainactivity中的代码,存入传输数据

                    String data = "hello android";
                    Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                    intent.putExtra("extra_data",data);
                    startActivity(intent);
    

    在下一个活动提取数据

            Intent intent = getIntent();
            String data = intent.getStringExtra("extra_data");
            Log.d("SecondActivity",data);
    

    3.返回数据给上一个活动
    使用startActivityForResult()开启下一个活动,请求码唯一即可

    Intent intent = new Intent(MainActivity.this,SecondActivity.class);
    startActivityForResult(intent,1);
    

    在下一个活动准备返回第一个活动的数据

    Intent intent = new Intent();
    intent.putExtra("data_return","hello android");
    setResult(RESULT_OK,intent);
    finish();
    

    在第一个活动中重写onActivityResult()方法获取数据

      @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            if(resultCode==RESULT_OK){
                String returnData = data.getStringExtra("data_return");
                Log.d("MainActivity",returnData);
            }
        }
    

    四.Activity的四种启动模式

    1.standard(默认)

    不会复用任务栈中的Activity,而是新建Activity实例添加到栈顶。新Activity位于启动者的任务栈中

    standard

    2.栈顶复用模式singleTop

    在该模式下,如果栈顶Activity为我们要新建的Activity(目标Activity),那么就不会重复创建新的Activity。

    singleTop

    使用场景

    1.IM消息
    2.新闻客户端推送
    

    3.栈内复用模式singleTask

    与singleTop模式相似,只不过singleTop模式是只是针对栈顶的元素,而singleTask模式下,如果task栈内存在目标Activity实例,则:
    1.将task内的对应Activity实例之上的所有Activity弹出栈。
    2.将对应Activity置于栈顶,获得焦点。

    使用场景

    应用主界面
    
    singleTask

    4.全局唯一模式singleInstance

    1.在该模式下,我们会为目标Activity分配一个新的affinity,并创建一个新的Task栈,将目标Activity放入新的Task,并让目标Activity获得焦点。
    2.新的Task有且只有这一个Activity实例。如果已经创建过目标Activity实例,则不会创建新的Task,而是将以前创建过的Activity唤醒(对应Task设为Foreground状态)。
    3.具有全局唯一性和独占性

    使用场景

    拨打电话
    
    singleInstance

    相关文章

      网友评论

        本文标题:Activity总结

        本文链接:https://www.haomeiwen.com/subject/nlcufqtx.html