haohao

Android 四大组件之 Activity

Cover

唉!最近拖延症又犯了

最近真的是越来越懒了,总是找各种理由不写博客。虽然最近各种事,又搞论文,又搞项目的,再拖下去实在是对不住 “不忘初心” 这一句话。惭愧!
虽然关于 Activity 已经被写烂了,但是从本篇文章里,你一定会发现不同的东西。

Activity 生命周期

一般情况下

haohaochang.cn

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}

异常情况下

系统配置变化导致Activity销毁重建

  1. 旋转屏幕,Activity 销毁并重新创建,在异常情况下系统会在 onStop 之前调用 onSaveInstanceState 来保存状态。Activity 重新创建后,会在 onStart 之后调用 onRestoreInstanceState 恢复之前保存的数据。
  2. 系统只在 Activity 异常终止的时候才会调用 onSaveInstanceState 和 onRestoreInstanceState 方法。其他情况不会触发。

资源内存不足导致低优先级的 Activity 被回收

  1. 前台- 可见非前台(被对话框遮挡的 Activity )-后台,这三种 Activity 优先级从高到低。
  2. android:configChanges="orientation" 在 manifest 中指定 configChanges 在系统配置变化后不重新创建 Activity,也不会执行onSaveInstanceState 和 onRestoreInstanceState 方法,而是调用 onConfigurationChnaged 方法。
  3. configChanges 一般常用三个选项:
    • locale 系统语言变化
    • keyborardHidden 键盘的可访问性发生了变化,比如用户调出了键盘
    • orientation 屏幕方向变化

场景

首次启动 Activity

1
2
3
MainActivity onCreate
MainActivity onStart
MainActivity onResume

跳转到 SecondActivity

1
2
3
4
5
MainActivity onPause
SecondActivity onCreate
SecondActivity onStart
SecondActivity onResume
MainActivity onStop

Back 返回 MainActivity

1
2
3
4
5
6
SecondActivity onPause
MainActivity onRestart
MainActivity onStart
MainActivity onResume
SecondActivity onStop
SecondActivity onDestroy

Home 回退桌面

1
2
MainActivity onPause
MainActivity onStop

桌面返回可见

1
2
3
MainActivity onRestart
MainActivity onStart
MainActivity onResume

锁屏

1
2
MainActivity onPause
MainActivity onStop

解锁屏

1
2
3
MainActivity onRestart
MainActivity onStart
MainActivity onResume

注意

onStart 开始到 onStop 之前, Activity 可见。
onResume 开始到 onPause 之前, Activity 可接受用户交互。
在新Activity启动之前,栈顶的Activity需要先onPause后,新Activity才能启动。所以不能在onPause执行耗时操作。

Activity 数据传递

Activity 传递数据一般有以下几种方式:

Intent 传递数据

MainActivity

1
2
3
4
5
6
Intent intent=new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);
Bundle bundle = new Bundle();
bundle.putString(KEY, VALUE);
intent.putExtras(bundle);
startActivity(intent);

OtherActivity

1
2
3
Intent intent = getIntent();
Bundle bundle = intent.getEtras();
String value = bundle.getString(KEY);

利用 Intent 对象在 Activity 之间传递数据是 Android 开发最常用的方式。
利用 Intent 对象可以传递基本数据类型,以及一些可序列化的对象。

public 型的静态变量

public 型的静态变量,在类被加载的时候,就被创建在静态存储区,不依赖于对象。

Application 对象

在整个应用程序中就一个Application单例,它的生命周期贯穿整个程序,堆内存中只存在一个对象实例,所以程序内所有它的引用指向的是同一块堆内存,所以可以在不同activity对application实例变量进行值的存取。
不推荐

Clipboard 剪切板

ClipboardManager:该类是系统剪切板服务的接口,用来放入或取出全局剪切板中的文本。

1
2
3
4
ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setText(DATA.toString());
}
1
2
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String data = clipboardManager.getText().toString();

Clipboard 也可以传递可序列化对象。

文件传值

通过向本地文件写入和读取来传递数据。
常用的如 SharedPrefrences 对象等。

数据库

你自己想吧!

Activity 启动模式

启动模式,简单地说就是 Activity 启动时的策略,在AndroidManifest.xml 中的标签的 android:launchMode 属性设置;

启动模式有4种,分别为 standard、singleTop、singleTask、singleInstance;

standard 模式

每次 startActivity 时,都创建 Activity 实例,并放入任务栈,该任务栈中,可以有多个同类 Activity 的实例。

应用场景:Your idea。

singleTop 模式

栈顶不是该类型的 Activity,则创建一个新的 Activity。否则,回调该 Activity 实例的 onNewIntent 方法。

应用场景:接收通知消息启动的页面。

例如,对于推送比较频繁的应用,如果收到多个推送,每次都打开一个页面显示内容是不妥的。

singleTask 模式

任务栈中不存在启动 Activity 的实例,则创建 Activity 放入任务栈。
否则,回调该 Activity 的 onNewIntent 方法,并将该 Activity 置于栈顶,其以上的 Activity 都被弹出 (pop)。[onNewIntent + clearTop]

应用场景:作为应用的入口点。

例如,对于浏览器的主界面,不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走 onNewIntent ,并且会清空主界面上面的其他页面。

singleInstance 模式

回退栈中,只有这一个Activity,没有其他Activity。

应用场景:闹铃的响铃界面。正在进行 QQ 聊天室时,闹铃响了,弹出一个对话形式的(以 SingleInstance 加载模式打开的)AlarmActivity,按了返回键之后回到 QQ 聊天界面,这是因为 Alarm Activity 所在的任务栈只有它一个元素, 因此退出之后这个任务栈空了。如果是以 SingleTask 打开 AlarmActivity,那么当闹铃响了的时候,按返回键应该进入闹铃设置界面。



联系我

Wechat ID

公众号

生活不止于眼前的苟且, 还有诗和远方的田野