Android基础之Activity

学Android就绕不开四大组件,那么说到四大组件,必然就要提到四大组件之首的Activity。
实际应用中,我们接触的最多的就是Activity,那么今天就来仔细的研究一下它。
本文的要点如下:

  • Activity简介
  • Manifest配置文件
  • Activity生命周期
  • Activity的启动模式

1、Activity简介

相信学过Android的人最先接触到的就是Activity,它是一种可以包含用户界面的组件,主要用于和用户交互。在一个应用程序中可以包含多个Activity。

2、Manifest配置文件

AndroidManifest.xml是整个应用的主配置清单文件,包括应用的包名、版本号、组件、权限等信息,它用来记录应用的相关的配置信息。
一个简单的AndroidManifest.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.retrofit2">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

manifest部分:

manifest是AndroidManifest.xml配置文件的根标签, 必须指定xlmns:android和package属性, 且只包含一个application节点。
xlmns:android指定了Android的命名空间,默认情况下是http://schemas.android.com/apk/res/android
package是标准的应用包名,也是一个应用进程的默认名称,为避免命名空间的冲突,一般会以应用的域名来作为包名。一般情况这部分不需要做改动。

application标签:

在application标签下有几个面向全局的属性:android:icon(图标)、android:label(标题)、android:theme(主题样式)。
而在application标签里面包裹着安卓四大组件:activity(活动)、service(服务)、content provider(内容提供者)以及broadcast receiver(广播接收器)。其中除了广播接收器可以动态注册外,其他三大组件都必须在application里注册才能使用。在这四个组件添加到application时,一定要声明android:name属性,值以包名.类名的形式,其中包名(package)可省写成.类名即可。

Activity标签:

application标签下的Activity标签声明了Activity的启动方式以及是否是LAUNCHER即程序入口。

uses-permission标签:

可用uses-permission标签声明一系列系统权限,需要的时候添加就可以。

3、Activity的生命周期

先上个经典的图:

Activity生命周期

这张图相信大家在初学android的时候肯定都见过,那么我们下面就来仔细聊聊这个图的内容。
在正常情况下,一个Activity从启动到结束会以如下顺序经历整个生命周期:
onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory()。包含了六个部分,还剩一个onRestart()没有调用。
那么每一部分具体是什么用处呢?

  • onCreate()表示Activity 正在创建,常做初始化工作,如setContentView界面资源、初始化数据;
  • onStart()表示Activity 正在启动,这时Activity 可见但不在前台,无法和用户交互;
  • onResume()表示Activity 获得焦点,此时Activity 可见且在前台并开始活动
  • onPause()表示Activity 暂停,可做数据存储、停止动画等操作
  • onStop()表示activity 即将停止,可做稍微重量级回收工作,如取消网络连接、注销广播接收器等
  • onDestroy()表示Activity 即将销毁,常做回收工作、资源释放
  • 当Activity由后台切换到前台,由不可见到可见时会调用onRestart(),表示Activity 重新启动。

onStart()和onResume()/onPause()和onStop()的区别

onStart()与onStop()是从Activity是否可见这个角度调用的,onResume()和onPause()是从Activity是否显示在前台这个角度来回调的,在实际使用没其他明显区别。

Activity A启动另一个Activity B会回调哪些方法

既然onStart()与onStop()是从Activity是否可见这个角度调用的,那么Activity A启动另一个Activity B回调的方法的顺序就应该是:Activity A的onPause() -->Activity B的onCreate()-->onStart()-->onResume()-->Activity A的onStop();如果Activity B是完全透明的或是对话框Activity,则最后不会调用Activity A的onStop()。

Activity的异常恢复

当非人为终止Activity时,比如横竖屏切换、系统配置发生改变时导致Activity被杀死并重新创建、资源内存不足导致低优先级的Activity被杀死,会调用 onSavaInstanceState() 来保存状态,该方法调用在onStop之前。
那么就有疑问了,为什么不直接用onPause()方法来保存状态呢?
因为onSaveInstanceState()只在Activity异常退出时才会调用,适用于对临时性状态的保存,而onPause()适用于对数据的持久化保存。
之后具体要怎么恢复呢?
异常关闭的Activity被重新创建时会调用onRestoreInstanceState(该方法在onStart之后),并将onSavaInstanceState保存的Bundle对象作为参数传到onRestoreInstanceState与onCreate方法。因此可通过onRestoreInstanceState(Bundle savedInstanceState)onCreate(Bundle savedInstanceState)来判断Activity是否被重建,并取出数据进行恢复。但需要注意的是,onCreate方法是无论是否异常退出都会调用的,因此在onCreate中的savedInstanceState是可能为空的,所以在onCreate取出数据时一定要先判断savedInstanceState是否为空。另外,谷歌更推荐使用onRestoreInstanceState进行数据恢复,因为这个这个方法的意义所在。

如何避免横竖屏切换Activity销毁和重建

可以通过在AndroidManifest文件的Activity中指定如下属性:

android:configChanges = "orientation| screenSize"

这样的话,横竖屏切换时就会回调 onConfigurationChanged方法:

@Override
  public void onConfigurationChanged(Configuration newConfig) {
       super.onConfigurationChanged(newConfig);
   }

4、Activity的启动模式

相信大家都知道,Activity有四种启动模式。Activity的管理是采用任务栈的形式,任务栈采用“后进先出”的栈结构。

Standard标准模式:每次启动一个Activity就会创建一个新的实例。
SingleTop栈顶复用模式:如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调 onNewIntent(intent) 方法。
SingleTask栈内复用模式:只要该Activity在一个任务栈中存在,都不会重新创建,并回调 onNewIntent(intent) 方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity放进去;如果存在,就会创建到已经存在的栈中。
SingleInstance单实例模式:具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。

为什么要有这四种启动模式呢?都用Standard有什么不好么?
先说SingleTop,在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。另外,在某个场景下连续快速点击,如果是Standard模式,就会启动了两个Activity,而singleTop则不会。
再说SingleTask,对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。
最后是SingleInstance,这种模式的使用情况就比较罕见了,呼叫来电界面是用了这种方式。

具体使用:
启动模式有2种设置方式:

  1. 在AndroidMainifest设置;
<activity android:launchMode="启动模式"
//属性
//standard:标准模式
//singleTop:栈顶复用模式
//singleTask:栈内复用模式
//singleInstance:单例模式
//如不设置,Activity的启动模式默认为**标准模式(standard)**
</activity>
  1. 通过Intent设置标志位。
Intent inten = new Intent (ActivityA.this,ActivityB.class);
intent,addFlags(Intent,FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
标记位 启动模式
FLAG_ACTIVITY_SINGLE_TOP SingleTop
FLAG_ACTIVITY_NEW_TASK SingleTask
FLAG_ACTIVITY_CLEAR_TOP 所有位于其上层的Activity都要移除,SingleTask模式默认具有此标记效果
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 具有该标记的Activity不会出现在历史Activity的列表中,即无法通过历史列表回到该Activity上

区别:

  • 优先级不同
    Intent设置方式的优先级 > Manifest设置方式,即 以前者为准
  • 限定范围不同
    Manifest设置方式无法设定 FLAG_ACTIVITY_CLEAR_TOP;Intent设置方式无法设置单例模式(SingleInstance)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容