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组件用于对用户呈现操作界 ...
随机推荐
- linux select代码框架
#define PORT 1234 #define BACKLOG 5 #define MAXDATASIZE 1000 typedef struct CLIENT{ int fd; char* na ...
- C++基础学习6:内联函数
C++语言新增关键字 inline,用于将一个函数声明为内联函数.在程序编译时,编译器会将内联函数调用处用函数体替换,这一点类似于C语言中的宏扩展. 采用内联函数可以有效避免函数调用的开销,程序执行效 ...
- 【模板】割点(割顶) Tarjan
题目背景 割点 题目描述 给出一个nnn个点,mmm条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,mn,mn,m 下面mmm行每行输入x,yx,yx,y表示xxx到yyy有一条边 ...
- zabbix监控java内存的脚本
#!/bin/bash # 截取java的pid号 java_pid=`netstat -lnpt |grep |awk -F '/' '{print $1'}` # 截取$jstat命令的位置 js ...
- sublime 配置主题
默认主题可能看不清楚: 安装 PackageResourceViewer 安装Soda 主题 setting中加入 "theme": "Soda Light 3.subl ...
- Linux安装与分区解释
Linux安装过程中最重要的就是对硬盘进行分区: Linux是先建立一个根目录“/”,然后在根目录上建立一系列的空目录,接着把硬盘分区挂载到相应目录上. 在linux系统中至少必须有两个挂载点(磁盘分 ...
- Django之ORM其他骚操作 执行原生SQl
Django ORM执行原生SQL # extra # 在QuerySet的基础上继续执行子语句 # extra(self, select=None, where=None, params=Non ...
- datatables通过ajax调用渲染数据,怎么根据数据给td添加class
html: <table id="table8" cellpadding="0" cellspacing="0" border=&qu ...
- Java 类型转换(int->String)
1 如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([ ...
- IIS Express 无法启动
IIS Express 无法启动1. \.vs\config\applicationhost.config2. 打开.csproject 中把 <UseIIS> 改成 False ---- ...