4.Android开发笔记:Activity的生命周期、启动方式、最佳实践

1.活动状态和生存期

4个状态,6个方法,3个生存期

状态:运行、暂停、停止、销毁

方法: onCreate、onResume、onPause、onStop、onDestroy、onRestart

生存期:

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

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

Android官方提供了一张活动生命周期的示意图,

4.Android开发笔记:Activity的生命周期、启动方式、最佳实践

2.活动的启动模式

standard

? 活动默认的启动模式

? 在standard模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例

singleTop

? 在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。

修改AndroidManifest.xml中FirstActivity的启动模式:

<activity
    android:name=".FirstActivity"
    android:launchMode="singleTop"
          ...

singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。 我们还是通过代码来更加直观地理解一下。修改AndroidManifest.xml中FirstActivity的启动模式:

<activity
    android:name=".FirstActivity"
    android:launchMode="singleTask"
          ...

singleInstance模式,指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面3种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。

修改AndroidManifest.xml中SecondActivity的启动模式:

<activity
    android:name=".FirstActivity"
    android:launchMode="singleInstance"
          ...

4.Android开发笔记:Activity的生命周期、启动方式、最佳实践

3.活动的最佳实践

(1)知晓当前是在哪一个活动

创建 BaseActivity,

首先需要新建一个BaseActivity类。右击com.example.activitytest包→New→Java Class,在弹出的窗口出输入BaseActivity,

和普通活动的创建方式并不一样,因为我们不需要让BaseActivity在AndroidManifest.xml中注册,所以选择创建一个普通的Java类就可以了。然后让BaseActivity 继承自 AppCompatActivity ,

并重写 onCreate()方法,如下所示:

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity:", getClass().getName());
    }
}

其它所以Activity继承BaseActivity.

public class FirstActivity extends  BaseActivity {//AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        .....
    }

(2)随时随地退出程序

? 如果目前你手机的界面还停留在ThirdActivity,你会发现当前想退出程序是非常不方便的,需要连按3次Back键才行。按Home键只是把程序挂起,并没有退出程序。其实这个问题就足以引起你的思考,如果我们的程序需要一个注销或者退出的功能该怎么办呢?必须要有一个随时随地都能退出程序的方案才行。 其实解决思路也很简单,只需要用一个专门的集合类对所有的活动进行管理就可以了,下面我们就来实现一下。

? 1) 创建Activity管理类:

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 removeAllActivity(){
        for (Activity activity : activities) {
            if (!activity.isFinishing()){
                activity.finish();
            }
        }
        activities.clear();
    }
}

? 2) 修改BaseActivity类:

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity:", getClass().getName());

        ActivityCollector.activities.add(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

3)全部退出:

            ActivityCollector.finishAll();

你还可以在销毁所有活动的代码后面再加上杀掉当前进程的代码,以保证程序完全退出,杀掉进程的代码如下所示:

android.os.Process.killProcess(android.os.Process.myPid());

其中, killProcess()方法用于杀掉一个进程,它接收一个进程id参数,我们可以通过myPid()方法来获得当前程序的进程id。需要注意的是,killProcess()方法只能用于杀掉当前程序的进程,我们不能使用这个方法去杀掉其他程序。

(3)启动活动的最佳写法

? Activity自己封装启动它的方法,

public class SecondActivity extends BaseActivity {//AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
            
        Intent intent = getIntent();
        String data1 = intent.getStringExtra("param1");
        String data2 = intent.getStringExtra("param2");
        Log.i("param1", data1);
        Log.i("param1", data2);
        Toast.makeText(SecondActivity.this, data1 + "/" + data2,Toast.LENGTH_LONG).show();
        
        ...
    }

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

? 其它地方调用该方法启动该 Activity:

public class FirstActivity extends  BaseActivity {//AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(FirstActivity.this, "Button被点击", Toast.LENGTH_LONG)
                        .show();

                SecondActivity.actionStart(FirstActivity.this,"参数1", "参数2");
            }
        });
    }

4.Android开发笔记:Activity的生命周期、启动方式、最佳实践

上一篇:List 多次排序


下一篇:本地时间转化成 GMT 时间