• Activity 不只有跳转。功能篇(一)


    Activity生命周期

    1:activity四种启动方式

    standard,SingleTask,SingleTop,SingleInstance
    standard:是系统默认的,每次启动该activity都会创建一个实例放在返回栈中,并且置于栈顶。
    SingleTop:在每次启动活动的时候如果发现栈的栈顶已经有该活动了,那么就直接使用它,不会再创建新的活动实例。如果启动的时候没有在栈顶,那么还是会创建一个新的实例,比如说A->B ,返回栈存放过程是创建A,创建B,然后B->A(并非通过back回到A),创建A实例,因为此时返回栈中栈顶是B,所以会创建A实例。
    SingleTask:整个返回栈中只有一个实例。每次启动的时候,就会在返回栈中检查是否有实例,如果有实例但不在栈顶,那么就会让栈顶出栈,它称为栈顶。例子:A->B,创建A实例,创建B实例,从B->A,此时返回栈中有A实例,就会让B实例出栈,此时栈中只有A的实例,所以点击Back后就会退出程序。(只要是在A上的实例全部出栈,如ABCD,需要用到B,此时栈中AB,CD出栈)
    SingleInstance:对于设置该模式的活动(Activity),会创建一个实例保存在新的返回栈中,这是因为可供其他的程序调用这个活动,达到了共享这个实例,在单个程序中如:A->B(模式SingleInstance)->C,创建A实例,创建B实例(新返回栈中),创建C实例,当点击back键时,会C弹出栈,显示A,再次点击back键,A弹出栈,显示B。原因是A和C在一个返回栈中,而B在一个新的返回栈中。
     

    2:Activity正确使用

      在实际开发中,页面很多,activity很多,所以,想要通过运行程序来判断当前所看的页面是对应哪一个activity就要创建一个父类activity,这样的话,让他们都来继承这个父类,在父类中通过OnCreate方法来执行一些公用的代码和Log日志即可。主要BaseActivity不需要在清单中注册。

    所有继承该父类的activity都要调用一个父类的onCreate方法。
    public class BaseActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.e("BaseActivity",getClass().getSimpleName());
        }
    }

    3:Activity随时随地都可以退出

      一个程序中有退出登录,这个时候就要保所有的activity,然后可以销毁所有的activity并且之后跳转到登录页面,如果想要退出到桌面,也可以加入杀死进程的代码,防止该程序进程在后台一直运行。
    杀死进程代码
    android.os.Process.killProcess(Process.myPid());//获取id,杀死当前id,并杀死当前进程,不可杀死其他程序进程
    Activity管理类
    public class ActivityCollector {
        public static List<Activity> listActivity = new ArrayList<>();
        /**
         * 添加活动
         * */
        public static void addActivity(Activity activity){
            listActivity.add(activity);
        }
        /*删除活动*/
        public static void removeActivity(Activity activity){
            listActivity.remove(activity);
        }
        /*销毁所有活动*/
        public static void finishAllActivity(){
            for (Activity activity:listActivity) {
                if(!activity.isFinishing()){
                    activity.finish();
                }
            }
        }
    }

    4:启动Activity最佳写法

      问题:假设两个Activity,FirstActivity和SecondActivity,第二个活动不是你写的,但是你需要跳转到该页面,同时需要传一些参数,此时,你可以问你同事需要传什么参数,或者自己去看需要什么参数,这样太麻烦。这时就需要优化代码,你同事可以在第二个界面就留一个方法入口,把需要的参数都列出来,你只需要用类名.方法名即可
    该方法写在第二个活动里,也就是需要跳转到的页面。
    /*启动最佳写法*/
    public static void actionStart(Context context,String param1,String param2){
        Intent intent  = new Intent(context,MainActivity2.class);
        intent.putExtra("param1",param1);
        intent.putExtra("param2",param2);
        context.startActivity(intent);
    }
    在MAinActivity1里调用。
    MainActivity2.actionStart(this,"ceshi1","ceshi2");

    5:生命周期以外的方法

    • onSaveInstanceState()
    • onRestoreInstanceState()
     
    onSaveInstanceState()和onRestoreInstanceState()使用详解 
    注意
    1、如果是用户自动按下返回键,或程序调用finish()退出程序,是不会触发onSaveInstanceState()和onRestoreInstanceState()的。
    2、每次用户旋转屏幕时,您的Activity将被破坏并重新创建。当屏幕改变方向时,系统会破坏并重新创建前台Activity,因为屏幕配置已更改,您的Activity可能需要加载替代资源(例如布局)。即会执行onSaveInstanceState()和onRestoreInstanceState()的。
    • 1.配置改变导致Activity被杀死,横屏变竖屏:在onStop之前会调用onSaveInstanceState()保存数据在重建Activity之后,会在onStart()之后调用onRestoreInstanceState(),并把保存下来的Bundle传给onCreate()和它会默认重建Activity当前的视图,我们可以在onCreate()中,回复自己的数据。
    • 2.内存不足杀掉Activity,优先级分别是:前台可见,可见非前台,后台。
    在stop()之前系统会调用onSaveInstanceState()方法,以便您的Activity可以使用一组键值对来保存状态信息。此方法的默认实现保存有关Activity视图层次结构状态的信息,例如EditText小部件中的文本或ListView的滚动位置。
    static final String STATE_SCORE = "playerScore";
    static final String STATE_LEVEL = "playerLevel";
    ...
    
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // 保存用户自定义的状态
        savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
        savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
        
        // 调用父类交给系统处理,这样系统能保存视图层次结构状态
        super.onSaveInstanceState(savedInstanceState);
    }

    恢复您的Activity状态

      当您的Activity在之前被破坏后重新创建时,您可以从Bundle系统通过您的Activity中恢复您的保存状态。这两个方法onCreate()和onRestoreInstanceState()回调方法都会收到Bundle包含实例状态信息的相同方法。因为onCreate()调用该方法是系统正在创建一个新的Activity实例或重新创建一个以前的实例,所以您必须Bundle在尝试读取之前检查该状态是否为空。如果它为空,那么系统正在创建一个Activity的新实例,而不是恢复之前被销毁的实例。

     
    例如,下面是如何恢复一些状态数据onCreate():
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // 记得总是调用父类
       
        // 检查是否正在重新创建一个以前销毁的实例
        if (savedInstanceState != null) {
            // 从已保存状态恢复成员的值
            mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
            mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
        } else {
            // 可能初始化一个新实例的默认值的成员
        }
        ...
    }
    onCreate()您可以选择执行onRestoreInstanceState(),而不是在系统调用onStart()方法之后恢复状态。系统onRestoreInstanceState()只有在存在保存状态的情况下才会恢复,因此您不需要检查是否Bundle为空:
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // 总是调用超类,以便它可以恢复视图层次超级
        super.onRestoreInstanceState(savedInstanceState);
       
        // 从已保存的实例中恢复状态成员
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    }

    6:onNewIntent()方法

    该方法和启动模式紧密相关
    前提:ActivityA已经启动过,处于当前应用的Activity任务栈中;
     
    当ActivityA的LaunchMode为Standard时:
    由于每次启动ActivityA都是启动新的实例,和原来启动的没关系,所以不会调用原来ActivityA的onNewIntent方法
    当ActivityA的LaunchMode为SingleTop时:
    如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法 ,生命周期顺序为:
    onCreate--->onStart--->onResume---onPause>onNewIntent--->onResume
    当ActivityA的LaunchMode为SingleInstance,SingleTask:
    如果ActivityA已经在堆栈中,那么此时会调用onNewIntent()方法,生命周期调用顺序为:
    onCreate--->onStart--->onResume---按下Home键>onPause--->onstop--->onNewIntent--->onRestart--->onstart--->onResume
     
    注意:在内存吃紧的情况下,系统可能会kill掉后台运行的 Activity ,如果不巧要启动的那个activity实例被系统kill了,那么系统就会调用 onCreate 方法,而不调用 onNewIntent 方法。这里有个解决方法就是在 onCreate 和 onNewIntent 方法中调用同一个处理数据的方法,
    总结:在activityA中设置了对应的启动模式后,其他(自己也行)activityB往A中使用intent跳转,携带值时就会调用onNewIntent()方法,然后是onRestart->onStart()->onResume();

    7:Activity的启动过程

    启动过程不是启动模式,所谓启动过程,就是从你看到应用图标点击后到正式开启所经过的过程
    • 第一种是从桌面launcher上点击相应的应用图标
    • 第二种是在activity中通过调用startActivity来启动一个新的activity
    由于launcher也是一个程序,所以当我们点击应用图标的时候系统会调用startActivitySately()。(具体在第二篇作答)

    8:Activity和fragment绑定后流程

    fragment存在被activity动态加载和静态加载,静态加载实在xml文件中加载,

  • 相关阅读:
    [设计模式整理笔记 五] 创建者模式(Builder)
    ArrayList与List<T>笔记
    asp.net站点URLRewrite小记
    ArrayList Array List<T>性能比较
    C# Socket SSL通讯笔记
    [设计模式整理笔记 六] 工厂模式与创建者模式总结
    [设计模式整理笔记 七] 原型模式(ProtoType)
    实现页面提交时显示"正在处理.."
    [设计模式整理笔记 四] 抽象工厂模式(Abstract Factory)
    在 ASP.NET 中执行 URL 重写 [转MSDN]
  • 原文地址:https://www.cnblogs.com/cmusketeer/p/15872322.html
Copyright © 2020-2023  润新知