Android-(3)活动-下

返回栈


活动的生命周期

Activity 类中定义了七个回调方法,覆盖了活动生命周期的每一个环节,下面我来一一 介绍下这七个方法。

1.    onCreate()

这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它会在活动 第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如说加载布 局、绑定事件等。

2.    onStart()

这个方法在活动由不可见变为可见的时候调用。

3.    onResume()

这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的 栈顶,并且处于运行状态。

4.    onPause()

这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方 法中将一些消耗 CPU 的资源释放掉,以及保存一些关键数据,但这个方法的执行速度 一定要快,不然会影响到新的栈顶活动的使用。

5.    onStop()

这个方法在活动完全不可见的时候调用。它和 onPause()方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么 onPause()方法会得到执行,而 onStop()方法并不会执行。

6.    onDestroy()

这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。

7.    onRestart()

这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。 以上七个方法中除了 onRestart()方法,其他都是两两相对的,从而又可以将活动分为三种生存期。

1.    完整生存期

活动在 onCreate()方法和 onDestroy()方法之间所经历的,就是完整生存期。一般情 况下,一个活动会在 onCreate()方法中完成各种初始化操作,而在 onDestroy()方法中完 成释放内的操作。

2.    可见生存期

活动在 onStart()方法和 onStop()方法之间所经历的,就是可见生存期。在可见生存 期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两 个方法,合理地管理那些对用户可见的资源。比如在 onStart()方法中对资源进行加载, 而在 onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。

3.    前台生存期

活动在 onResume()方法和 onPause()方法之间所经历的,就是前台生存期。在前台 生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行相互的,我们平时 看到和接触最多的也这个状态下的活动。


体验活动的生命周期

新建一个类BaseActivity,它继承AppCompatActivity但是不需要注册,因为不需要直接用到, 需要让别的类来继承

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;

@SuppressLint("Registered")
public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onDestroy");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("ShowLifeCircle",getClass().getSimpleName() + " onRestart");
    }
}

然后让其他的所有活动类继承这个类。

打开AndroidManiFest.xml 文件将 ThirActivity活动标签修改:

<activity android:name=".ThirActivity"
    android:theme="@style/Theme.AppCompat.Dialog"> 
 <!--增加一个属性,这个说明这个活动是一个弹窗型的,不会覆盖整个屏幕-->

运行,可以看到打开app后,点击打开活动二和打开活动三的稍有不同。


活动被回收保存回收前数据

可以在活动中重写下面这个方法,就可以保留数据

//停止的活动有可能被系统回收,如果被回收这个方法会保留数据
@Override
protected void onSaveInstanceState(@Nullable Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    String data_string = "some data you just left";   //要保留的数据
    savedInstanceState.putString("data",data_string); //前面是键,后面是数据,取数据的时候需要用到键
}

重新创建活动后恢复数据

在onCreate方法中有个参数savedInstanceState参数,这个往往为空,如果这个活动之前有过调用onSaveInstanceState方法保存了数据,那么就都会存在 savedInstanceState 参数里。在OnCreate方法中添加:

if(savedInstanceState != null)
{
    String data = savedInstanceState.getString("keep_data");  //这样数据就回来了。
}

活动的启动模式

共有四个模式: standardsingleTopsingleTasksingleInstance

默认的是 standard ,可以在AndroidManiFest.xml对活动的申明标签中修改:

<activity android:name=".ThirActivity"
    android:theme="@style/Theme.AppCompat.Dialog"
    android:launchMode="singleTop">

简单说明四个模式什么意思,一个app有很多活动,一个活动可以打开另外一个活动,它们存贮在栈中。每次有新的活动,不一定就会创建。 standard 默认模式,只要有新的活动就会创建。 singleTop 模式,如果要创建的活动和最顶部的活动一样那就不创建了,直接使用最顶部的。 singleTask 模式,会检测整个栈有没有同名活动,如果没有就创建,有,就不停出栈直到存在的同名活动在栈顶。 singleInstance 模式,会把活动单独存在另外一个栈里。

standard
singleTop
singleTask
singleInstance

最佳实践

知晓当前在哪个活动

其实之前已经有涉及就是BaseActivity活动,这个活动是父活动,别的活动要来继承他。

当别的活动使用代码:

getClass().getSimpleName();

可以知道当前活动。

随时退出程序

之前说过活动是在栈中,要退出有三个活动的程序,就要点三次back。有更好的解决方法:

写一个专门的集合类ActivityCollector:

import android.app.Activity;
import java.util.ArrayList;
import java.util.List;

public class ActivityCollector {

    public static List<Activity> activities = new ArrayList<>();

    //添加
    public static void addActivity(Activity activity)
    {
        activities.add(activity);
    }

    //移除
    public static void removeActivity(Activity activity)
    {
        activities.remove(activity);
    }

    //关闭所有
    public static void finishAll() {
        for(Activity activity : activities)
        {
            if(!activity.isFinishing())
            {
                activity.finish();
            }
        }
    }
}

修改BaseActivity类的OnCreate方法和OnDestroy方法,主要两行代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityCollector.addActivity(this);  //将创建的活动加入到活动管理器中
    Log.d("ShowLifeCircle",getClass().getSimpleName() + " onCreate");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.d("ShowLifeCircle",getClass().getSimpleName() + " onDestroy");
    ActivityCollector.removeActivity(this);  //将准备销毁的活动从活动管理器中移除
}

如果要直接退出程序,可以使用:

ActivityCollector.finishAll();

活动最佳写法:

在启动一个活动时如果有参数要传递过来可以这么写,比如说MyActivity,如果别的地方需要启动这个活动,且启动的时候要带两个字符串参数,那么在MyActivity中可以写一个方法:

public static void actionStart(Context context, String data1, String data2) {
    Intent intent = new Intent(context, MyActivity.class);
    intent.putExtra("param1", data1);
    intent.putExtra("param2", data2);
    context.startActivity(intent);
}

那么,比如说在MainActivity中要启动 MyActivity 活动就简单多了:

MyActivity.actionStart(MainActivity.this, "data1", "data2");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值