Activity
概念
android四大组件之一。Activity是独立平等的,用来处理用户操作。Android中的activity全部归属于task管理。task 是多个 activity 的集合,这些 activity 按照启动顺序排队存入一个栈(即“back stack”)。android默认会为每个App维持一个task来存放该app的所有activity,task的默认name为该app的packagename。
清单文件中taskAffinity属性可自定义task,但不安全,如其他app申明相同task,有可能启动到你的activity。
Activity的4种状态
running 运行状态,当前Activity获取了焦点
paused 暂停状态,当前Activity可见,但失去焦点,内存中的成员变量,状态信息等仍然存在
stopped 当前Activity不可见,内存中的成员变量,状态信息仍然存在
killed 当前Activity不可见,内存里面的成员变量,状态信息等GC有空,立即回收
Activity间数据传递
A → B
//启动ActivityB,同时等待ActivityB销毁时回传数据,需设置requestCode
startActivityForResult(Intent intent, int requestCode)
//获取ActivityB回传的数据,最好验证requestCode和resultCode正确性
onActivityResult(int requestCode, int resultCode, Intent data)
//设置回传数据。用于传递数据的Intent:Context.getIntent();
setResult(int resultCode, Intent data)
生命周期
方法名 | 特点 |
---|---|
OnCreate | Activity 第一次创建时被调用 |
onStart | Activity 对用户可见前被系统调用 |
onResume | Activity 可以跟用户交互前被调用 |
onPause | 另外一个Activity 即将成为Resumed 状态前调用 |
onStop | Activity 不可见时被调用 |
onDestor | Activity 被销毁前调用 |
onRestart | Activity 处于onStop 状态之后,重新启动被调用 |
常用操作对Activity生命周期的影响
打开
onCreate()
onStart()
onResume()
按下主屏幕键/锁屏
onPause()
onStop()
重新打开应用
onRestart()
onStart()
onResume()
按下后退键
onPause()
onStop()
onDestroy()
有Dialog时按home键
onPause()
onStop()
onSaveInstanceState()与onRestoreInstanceState()
onSaveInstanceState():在布局切换前或当前Activity被推入历史栈前保存当前的窗口状态,如果Activity在后台没有因为运行内存吃紧被清理,则切换回时会触发onRestoreInstanceState(),调用时机:onStop()之前被调用,与onPause()没有严格的前后顺序关系
onRestoreInstanceState():恢复以保存的窗口状态,调用时机:onStart()之后
onNewIntent()
Activity的launchMode为singleTask时,通过Intent启动一个Activity
如系统已存在实例,则会发请求到这个实例上,生命周期:onNewIntent() --> onRestart() --> onStart() --> onResume()
如系统不存在实例,如Activity被系统回收,生命周期:onNewIntent() --> onRestart() --> onStart() --> onResume()
横竖屏切换
切换时会触发onsaveinstancestate,而还原时会产生onrestoreinstancestate
Android 手机在横竖屏切换时,默认情况下会把Activity 先销毁再创建,模拟器横竖屏切换的快捷键是Ctrl+F11。
解决办法:清单文件声明Activity时配置activity标签的几个属性
4.0 以下版本:android:configChanges="orientation|keyboardHidden"
4.0 以上版本:android:configChanges="orientation|screenSize"
4.0 以上版本:android:configChanges="orientation|keyboardHidden|screenSize"
configChanges常用属性 | 含义 | 备注 |
---|---|---|
locale | 地址改变了 | 用户选择了一个新的语言会显示出来 |
touchscreen | 触摸屏时改变了 | 通常是不会发生的 |
keyboard | 键盘发生了改变 | 用户用了外部的键盘 |
keyboardHidden | 键盘的可用性发生了改变 | |
screenLayout | 屏幕的显示发生了变化 | 不同的显示被激活 |
fontScale | 字体比例发生了变化 | 选择了不同的全局字体 |
uiMode | 用户的模式发生了变化 | |
orientation | 屏幕方向改变了 | |
screenSize | 屏幕大小改变了 | |
smallestScreenSize | 屏幕的物理大小改变了 | 连接到一个外部的屏幕上 |
案例——横竖屏加载不同布局
方法一
//1 创建两个文件夹,layout-land,layout-port,并在其中放置对应的activity_main.xml
//2 清单文件中的Activity标签下设置screenOrientation属性
//3 在oncreat()或其他适合时机触发布局切换
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化操作
initView();
}
方法二
//1 创建两个自定义布局activity_main.xml和activity_main_land.xml
//2 清单文件中的Activity标签下设置screenOrientation属性
//3 在oncreat()
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
setContentView(R.layout.activity_main_land);
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
setContentView(R.layout.activity_main);
}
//初始化操作
initView();
}
//4 重写onConfigurationChanged()
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
int mCurrentOrientation = getResources().getConfiguration().orientation;
if (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.activity_main);
}else {
setContentView(R.layout.activity_main_land);
}
//注意本地数据的保存
//此处初始化根据实际情况而定。如涉及到按钮等,其状态会丢失,需要重新初始化。如只涉及到本地数据保存,则不需要。
initView();
}
固定Activity方向
方法一:通过配置文件
在AndroidManifest.xml中activity节点中添加如下属性,portrait:垂直方向,landscape:水平方向,sensor或不设置:随感应器方向(屏幕旋转设置打开)
android:screenOrientation="portrait"
方法二:通过代码
在Activity 的onCreate 方法中执行如下方法。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //垂直方向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //水平方向
启动模式
原因:避免频繁生成Activity实例
standard | 标准启动模式 | 创建即新增 | 应用场景 |
---|---|---|---|
singleTop | 单一顶部模式 | 顶部有就复用,否则新增 | 消息推送 |
singleTask | 单一任务栈模式 | 栈中存在即复用,并移除上面所有activity,否则新增 | 程序入口等启动页面 |
singleinstance | 单一实例模式 | 手机操作系统中有就复用,否则增加(单独占用一个栈, 全局唯一) | 完全独立的,类似闹钟提示 |
scheme跳转协议
待更新
问题
下拉状态栏是不是影响activity的生命周期
不影响
如果在onStop的时候做了网络请求,onResume的时候怎么恢复?
请求操作:stop()请求操作被暂停,onstart()检测重新恢复请求
数据:如Activity被销毁,使用saveInstanceState()存储数据,onRestoreInstanceState()恢复数据;如Activity被销毁,不需要恢复
Activity,Window,View三者的联系和区别
Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸