Android学习笔记4——Activity详解
在 Android 开发过程中,与程序员打交道最多的应该就是作为四大组件之一的 Activity 了。接下来我们就一起来揭开 Activity 的神秘面纱吧~
一、概述
什么是 Activity(活动)?当用户打开一个软件,首先看到的就是各种界面,这些界面就是 Activity。
二、使用 Intent 在 Activity 之间穿梭
一个程序不可能只有一个 Activity,在使用软件过程中必然会产生界面的跳转,这就涉及到 Activity 的转换。在 Android 开发中,开发者可以使用 Intent 在不同 Activity 之间跳转。
显式跳转
使用显示 Intent 进行跳转非常简单,只需在代码中创建一个 Intent 对象,调用 Intent() 方法即可。
示例:Intent intent = new Intent(ThisActivity.this,AnotherActivity.class);
startActivity(intent);
隐式跳转
使用隐式跳转则比较复杂,首先需要在 AndroidManifest.xml 文件内进行配置。每个 <activity> 标签内部都可以进行 <intent-filter> 标签的设置,在这个标签内部有两个标签:<action>、<category>
为这两个标签设置参数,然后在逻辑代码中进行匹配,即可跳转到指定的 Activity。
示例:首先配置两个标签内参数 <action android:name = "com.example.activitytest.ACTION_START" />
<category android:name = "android.intent.category.DEFAULT" />
<category android:name = "com.example.activitytest.MY_CATEGORY" /> ps:<category> 标签可以有多个,在进行匹配时可以灵活应用。
随后在逻辑代码中进行匹配 Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("com.example.activitytest.MY_CATEGORY");
startActivity(intent);
在使用隐式跳转的时候,<action>标签内的参数可以设置成调用系统浏览器、电话拨号盘等系统内置应用。最主要的优势在于你的程序中某个 Activity 是允许另外一个程序进行访问的,如支付宝的支付接口。
那么使用显示跳转显然是做不到的,这时候就需要配合 Activity 的启动模式以及隐式跳转就可以实现。
带数据跳转
使用 Intent 进行界面跳转的时候,其实可以通过 Intent 的 putExtra() 等方法进行数据的传递。如当前活动需要向下一个活动传递一个字符串,那么就可以这样实现:
在当前活动中:String data = "Hello NextActivity";
Intent intent = new Intent(ThisActivity.this,NextActivity.class); //使用显式跳转
intent.putExtra("extra_data",data); //putExtra()方法传递参数以键值对形式进行传送
startActivity(intent);
在下一个活动中:Intent intent = getIntent();
String data = intent.getStringExtra("extra_data"); //不同数据类型对应不同方法,getIntExtra()、getBooleanExtra()等
回传数据
其实当一个活动销毁的时候也能够返回数据给上一个活动,比如第三方登录接口,当软件通过微信进行授权登录时,会跳转的一个微信的授权界面,点击授权后返回登录界面发现登录成功了。
这时授权界面销毁后就回传了一些数据给登录界面使得用户登录成功。
在Activity中有一个startActivityForResult()的方法,这个方法有两个参数,一个依旧是Intent对象,另一个是请求码。
首先在FirstActivity中:Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivityFroResult(intent,1); //此方法内第二个参数是请求码,当下一个活动回传数据时会根据这个参数判断回传给哪一个活动
其次在SecondActivity中:Intent intent = new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK,intent); //返回数据给上一个活动的方法,第一个参数是处理结果,第二个是带有数据的 Intent 对象
finish(); //销毁当前活动
最后由于是使用startActivityFroResult()方法启动的SecondActivity,所以当SecondActivity销毁时会回调上一个活动的onActivityResult()方法,我们需要重写这个方法来接收数据。
在FirstActivity中:@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
//此方法内第一个参数就是startActivityFroResult()方法内第二个参数,此方法第二个参数就是setResult()方法内的第一个参数,此方法第三个参数就是setResult()方法内的第二个参数
{
switch(requestCode)
{
case 1:
if (resultCode == RESULT_OK)
{
String returnData = data.getStringExtra("data_retuen");
}
break;
}
}
三、生命周期
在 Android 中是使用 Task(任务)来管理活动的,任务是一组放在栈里的集合,这个栈也叫作返回栈(Back Stack)。
当活动被创建显示给用户时,活动会入栈并置于栈顶,系统总是将栈顶的活动显示给用户。当一个活动不在需要显示给用户时就会出栈或者被其他活动压如栈底。活动的出入栈遵循先进后出原则。
一个 Activity 拥有4种状态7种回调方法,灵活应用 Activity 的生命周期能使程序运行更顺畅,更合理利用程序资源内存。
7种回调方法分别是 onCreat()、onStart()、onResume()、onPause()、onStop()、onDestory()、onRestart()。
这7种方法中除了onRestart() 其他6种都是两两对应的。
完整生存期
活动在 onCreat() 到 onDestory() 之间经历就是一个完整生存期。一般会在 onCreat() 进行各种初始化操作,在 onDestory() 中进行释放内存操作。
可见生存期
活动在 onStart() 到 onStop() 之间经历的就是一个可见生存期。在这期间活动对于用户总是可见的,但不一定可以进行交互。一般可以在 onStart() 中对资源进行加载,在 onStop() 中释放资源。
前台生存期
活动在 onResume() 到 onPause() 之间经历的就是一个前台生存期。在这期间活动总是运行状态,平时接触最多的就是这种状态下的活动。
运行状态
当活动位于返回栈的栈顶时,就处于运行状态,此时活动对于用户是可见可交互状态。系统最不愿意回收的就是这种状态的活动,会带来非常差的体验,就好比程序突然崩溃一样。
暂停状态
当活动不处于栈顶但对于用户依然可见时,就处于暂停状态,此时活动对于用户可见但不可交互,如被弹框遮挡部分时。系统也不愿意回收这样的活动,只有在内存极低情况下系统才考虑回收这种活动。
停止状态
当活动不处于栈顶且对于用户完全不可见时,就处于停止状态,此时系统仍然会为活动保留相应状态和成员变量,但是其他地方需要内存时,活动可能会被系统回收。
销毁状态
当活动从返回栈中出栈后,就处于销毁状态,系统最喜欢回收这样的活动,保证系统内存充足。

这张图详细说明了活动的生命周期。
四、启动模式
活动有四种启动模式:standard、singleTop、singleTask、singleInstance。
在 AndroidManifest.xml 文件中可以对活动设置启动模式:<activity android:name=".SecondActivity" android:launchMode="singleInstance" />
默认模式 standard
没有指定启动模式的活动都是默认指定为 standard 启动模式。
在次模式下,每当启动一个活动时,就会在返回栈顶创建一个该活动的实例,这样会导致同一个活动被重复创建多次。
栈顶模式 singleTop
在该模式下,每当启动一个活动时,系统会判断返回栈顶的活动是不是该活动,如果是则直接调用,如果不是则重新创建。
如:现在栈顶的活动是FirstActivity,在FirstActivity中启动SecondActivity,此时栈顶的活动是SecondActivity,然后在SecondActivity启动FirstActivity;由于FirstActivity未处于栈顶,系统在栈顶重新创建了一个FirstActivity。
这样会导致之前第一个创建的FirstActivity上的数据丢失,因为用户可能在第一个FirstActivity上输入了一些文字,但是第二次的FirstActivity是新创建的,并没有用户输入的文字。
返回栈模式singleTask
在该模式下,每当启动一个活动时,系统会在整个返回栈内搜索判断有没有这个活动,如果有则直接调用,没有就创建一个放在栈顶。
开小灶模式singleInstance
若是一个活动被设置为这种启动模式,系统会为活动单独开辟一个返回栈进行管理,此时的活动是可以被其他程序进行访问的。
我的GitHub内有Demo对活动的启动模式和生命周期进行展示:点我点我!
五、关于 Intent 带数据跳转的"BUG"
不论是使用 Intent 向下一个活动传递数据还是回传数据给上一个活动,对活动的启动模式都要要求。
我在测试的时候发现,活动的启动模式设为 singleTask 和 singleInstance 的时候,数据的传递会在某些情况下失效。
具体原因还没有研究明白,不过 standard 和 singleTop 模式是没有任何问题的。
Android学习笔记4——Activity详解的更多相关文章
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- Android学习笔记_21_ViewFlipper使用详解 手势识别器
一.介绍ViewFilpper类 1.1 屏幕切换 屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置 ...
- Android学习笔记之Toast详解
1. 贴一段Android API-Toast Toast public class Toast extends Object java.lang.Object ↳ android.widget.T ...
- expect学习笔记及实例详解【转】
1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...
- Android学习笔记:Activity生命周期详解
进行android的开发,必须深入了解Activity的生命周期.而对这个讲述最权威.最好的莫过于google的开发文档了. 本文的讲述主要是对 http://developer.android.co ...
- Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解
前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY <源路径> .. ...
- Redis学习笔记4-Redis配置详解
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...
- Android四大组件之Activity详解——创建和启动Activity
前面我们已经对Activity有过简单的介绍: Android开发——初始Activity Android开发——响应用户事件 Android开发——Activity生命周期 先来看一下最终结果 项目 ...
- android学习笔记26——Activity
Activity ==> android中四大组件:Activity.Service.BroadcastReceiver.ContentProvider Activity组件用于对用户呈现操作界 ...
随机推荐
- 商品录入功能v1.0【持续优化中...】
# 录入商品 def goods_record(): print("欢迎使用铜锣辉的购物商城[商品管理][录入商品]".center(30, "*")) whi ...
- Charles使用方法简介
Charles是一个web代理器,用来记录和展示你所发出和接收到的所有数据. 主要特性: SSL Proxying——易清晰地文本展示SSL请求和响应Bandwidth Throttling是用来模拟 ...
- Django 07 Django模型基础2 (常用查询和多表关联)
Django 07 Django模型基础2 (常用查询和多表关联) 一.常用查询 #查找数据 def search_user(request): #获取 rs = User.objects.first ...
- Luogu P1608 路径统计 最短路计数
颓了...重边导致我乖乖用邻接矩阵.... 好吧就是个最短路计数....如果更新时d[v]==d[u]+w[i],就可以接起来,把两个加在一起.. 如果d[v]>d[u]+w[i],那么c[v] ...
- 缓存算法及Redis、Memcached、Guava、Ehcache中的算法
https://my.oschina.net/ffy/blog/501003 https://yq.aliyun.com/articles/622757 https://blog.csdn.net/s ...
- IOS开发-基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建
导引 iOS自动化测试一直使用的appium,iOS系统升级至10.0 Xcode8.0之后,改用WebDriverAgent代理服务作为server,编写了一套基于WebDriverAgent服务 ...
- Wireshark抓取TCP包分析
介绍 本篇文章是使用wireshrak对某个https请求的tcp包进行分析. 目的 通过抓包实际分析了解tcp包. 准备工作 在我自己机子上安装的是wireshark2.2.6版本,随机查找了某个T ...
- java中所有开源注解收集
@resource: resource全名为@Resource ,用来激活一个命名资源(namedresource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDI conte ...
- Ubuntu14.04配置python接口,测试的小问题
当遇到“ImportError:No module named google.protobuf.internal”(import enum_type_wrapper)的问题时候 solution: P ...
- ubuntu14.04下 安装matlabR2015b遇到的一些问题及其解决方法
问题1:错误提示关于未取得权限,不能再/crack/bin文件中复制文件到安装matlab的/usr/bin文件中? 采取解决方法: 再终端里输入 sudo nautilus,在弹出文件夹里即可进行相 ...