Android组件系列——Activity

本文深入讲解Android中的Activity组件,涵盖其基本概念、四种状态、生命周期方法及常见操作的影响。同时,详细介绍了Activity间的数据传递方式、启动模式以及如何处理横竖屏切换,包括配置和代码实现方法。

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)

生命周期

方法名特点
OnCreateActivity 第一次创建时被调用
onStartActivity 对用户可见前被系统调用
onResumeActivity 可以跟用户交互前被调用
onPause另外一个Activity 即将成为Resumed 状态前调用
onStopActivity 不可见时被调用
onDestorActivity 被销毁前调用
onRestartActivity 处于onStop 状态之后,重新启动被调用

1529498668281

常用操作对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配置像窗花图纸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值