一、问题来源
最近学习安卓开发activity的生命周期,对单个活动的生命周期较为熟悉。此时师兄抛出问题,当一个activity进入onStop()
时,如何得知时由于用户点击了主页键,还是由于进入了另一个本程序的activity?
二、方法探究
查阅网络资源后,得知可以通过安卓本身的多种方法来判断。不过某些方法的使用需要获取用户授权,或者需要较高版本的安卓系统。不过本文主要介绍通过activity本身的生命周期回调函数来判断。
三、基本原理和思路
由于设计两个activity的跳转,所以我们应该去考虑多个activity的生命周期回调函数顺序。查阅并测试可知,当进行activity跳转时,先执行原来activity的onPause()
和,然后执行第二个activity的onCreate()
、onStart()
、onResume()
,再执行第一个activity的onStop
。如图所示,红色是第一个activity的回调函数执行,蓝色是第二个。
我们可以利用这个特点,通过一个static变量来记录当前run的activity数量,当这个数量为0的时候,即程序被压入后台,当这个数量不为0,则表明当前执行了一个跳转操作。
四、代码实现
4.1 BaseActivity类
首先新建一个BaseActivity
类,声明一个static变量,让别的activity全部继承。并在onStart()
和onStop()
中修改count
。
public class BaseActivity extends AppCompatActivity {
static int count = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onStart() {
count++;
super.onStart();
}
@Override
protected void onStop() {
count--;
super.onStop();
}
}
4.2 MainActivity类
创建MainActivity
类,继承自BaseActivity
类,同时修改onStop()
,检查count
的值,判断此次导致onStop()
的原因。我在这个activity中添加了一个button用于跳转到第二个activity。
public class MainActivity extends BaseActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
protected void onStop() {
super.onStop();
Toast toast;
if (count == 0){
toast = Toast.makeText(getApplicationContext(), "程序进入后台", Toast.LENGTH_SHORT);
}else {
toast = Toast.makeText(getApplicationContext(), "程序进入第二个活动", Toast.LENGTH_SHORT);
}
toast.show();
}
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
}
4.3 SecondActivity类
这个类很简单,没有什么功能,只是跳转过来后,执行基类的onCreate()
方法。
public class SecondActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
五、总结
至此,我们便实现了通过activity生命周期回调函数判断是否被压入后台。不过,后来学长针对我的这种方式提出了漏洞——当引用外部SDK,且外部SDK中可以弹出未继承我们自定义的base基类的activity,那么怎么处理这种情况呢?这里就要用到安卓SDK提供的全局生命周期类了——Application.registerActivityLifecycleCallbaks,这里我们之后再谈。