Android基础知识回顾之Activity

开篇废话

最近公司忙着搬迁,没有太多的精力去分享一些比较耗时间分析的知识点,随之就跟着之前的计划,开始回顾一下Android相关的基础知识。

今天我们一起来回顾一下我们接触最多,相对来说最熟悉的四大组件之一,Activity。

其实,当我在想什么是Activity的时候,确实有那么一会儿懵逼的感觉,因为不知道该如何组织语言去表达。

在这里,我大概说一下我的理解,到时候与别人交谈的时候,可以用这个思路来表达:

在我们日常应用中,Android是与用户交互的接口,它提供了一个界面让用户进行点击、各种滑动操作,这就是Activity的意义


技术详情

这次的内容比较简单,看起来会比较轻松,我主要分四个角度来进行讲述:

1. Activity的生命周期

2. Android系统中的任务栈

3. Activity的启动模式

4. scheme跳转协议

1. Activity的生命周期

1.1 Activity的四种状态

running:
表明activity处于活动状态,用户点击屏幕,屏幕可以作出响应,它是一个处于activity栈顶的状态

paused:
表明activity失去焦点的时候,也许是被一个非全屏的activity占据,或者被一个透明的activity放置在activity栈顶,这种情况下,就处于paused状态,用户操作对它不会有响应,但并不代表它被销毁了,这时候,他所有的状态信息和成员变量都还在,除非系统内存非常紧张的时候,就有可能被销毁掉。

stopped:

当activity被另一个Activity完全覆盖的时候,被覆盖的那个activity就会处于stopped状态,当内存不紧张的时候,状态信息和成员变量也是还在的。

killed:

表明activity已经被系统回收掉了,状态信息和成员变量都已经不存在了。

1.2 Activity的生命周期分析

首先,我们都需要看懂下面这张图:

Android基础知识回顾之Activity_第1张图片
Activity生命周期

大概分析几个场景的调用流程:

1.Activity启动 -->  onCreate() --> onStart() --> onResume()

2.点击Home键回到系统主界面的时候 --> onPause() --> onStop()

3.当我们再次回到原来的那个Activity的时候 --> onRestart() --> onStart() --> onResume()

4.退出当前的Activity的时候 --> onPause() --> onStop() --> onDestory()

5.A Activity 调用弹出B Activity的时候(完全覆盖) --> A onPause() --> B onCreate() --> B onStart() --> B onResume --> A onStop()

6.Activity异常退出的时候 --> onPause() --> onSaveInstanceState() --> onStop() --> onDestory(),
需要注意的是onSaveInstanceState() 方法与onPause并没有严格的先后关系,有可能在onPause之前,也有可能在其后面调用,但会在onStop()方法之前调用

7.异常退出后又重新启动该Activity --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()

1.3 Android中的进程优先级

Android系统中,主要有这样五个进程优先级(按优先级高到低排列):

1. 前台进程:一般情况下处于与用户进行交互的Activity或者与前台Activity绑定的Service

2. 可见进程:如果一个Activity处于可见但是不是处于前台,就是用户不能点击的情况下就是可见进程

3. 服务进程:就是在后台开启了一个Service服务,这就是服务进程

4. 后台进程:假设我们当前的Activity是前台进程,然后我们按下Home键,前台进程就变成了后台进程

5. 空进程:五个进程里面,优先级是最低的,如果我们的进程不属于上面四个进程的进程,那就是空进程,空进程系统可以随时杀死

2. Android系统中的任务栈

我们的Android系统为了记录用户开启了哪些Activity,记录这些Activity开启的先后顺序,所以引入了任务栈(Task Stack)的概念,可以增强用户的体验。

Android基础知识回顾之Activity_第2张图片
任务栈

任务栈与下面讲的启动模式其实密切相关,关于任务栈相关的知识点如下:

1. 任务栈,Task Stack,别名Back Stack(后退栈),记录存放用户开启的Activity

2. 我们的App开启的时候,Android系统就给这个App分配了一个任务栈,当所有的Activity都退出的时候,任务栈就清空了

3. 我们的App的任务栈并不是唯一的,可能不止一个任务栈,一个Activity也可以独享一个任务栈

4. 清空了任务栈,我们的App的进程并不会销毁,还是会保留

5. 任务栈可以移动到后台,并且保留了每一个Activity的状态信息和成员变量

6. 只有在栈顶的Activity才能与用户进行交互

3. Activity的启动模式

Android系统中Activity的启动模式主要有四种:

1. standard

2. singleTop

3. singleTask

4. singleInstance

3.1 standard

这个模式,我们平时开发中使用得比较多,属于默认模式,可以指定,也可以不用配置。

在这个模式下,都会默认创建一个新的实例。也就意味着在一个任务栈中,可能存在多个相同的实例,也可以多个相同的Activity进行叠加

可以在清单文件里面进行指定该启动模式:

当前栈内顺序是A B C D,这个时候,在栈顶的D Activity启动A Activity,由于是A是Standard模式,那么就会在当前任务栈重新创建一个新的实例A,那么任务栈就变成了A B C D A。

Android基础知识回顾之Activity_第3张图片
standard

3.2 singleTop

我们一般都称此模式为栈顶复用,表明与Standard不同的是,并不是每次都无脑的进行重新创建一个实例,需要进行判断。当被启动的Activity已经处于栈顶,就不会进行创建新的实例,而是调用栈顶Activity的onNewIntent方法,当然,如果栈顶的Activity并不是被启动的但是同一个任务栈的,依然会重新创建一个实例

Android基础知识回顾之Activity_第4张图片
singleTop_1
Android基础知识回顾之Activity_第5张图片
singleTop_2

3.3 singleTask

这个模式,我们中文称作栈内复用,与栈顶复用差不太多,只是,判断的是当前Activity处于的整个任务栈。如果在整个任务栈中,已经有当前Activity的实例,那就是调用该Activity的onNewIntent方法,而不会重新创建实例。

这个模式值得注意的是,当需要复用当前任务栈中的某一个Activity实例的时候,会直接把该实例上面的Activity进行出栈进行销毁,从而将该Activity实例放于栈顶。

Android基础知识回顾之Activity_第6张图片
singleTask_1
Android基础知识回顾之Activity_第7张图片
singleTask_2

3.3 singleInstance

这个模式比较特殊,当使用该模式的时候,会创建一个新的任务栈,而且,这个任务栈有且仅有这一个Activity实例。

如果再一次调用这个Activity实例,就会发生发用,调用它的onNewIntent方法,反正不会再重新创建一个了。

值得注意的是,按返回退出的时候,是一个任务栈都出栈完了之后,再操作另一个任务栈。

Android基础知识回顾之Activity_第8张图片
singleInstance

4. scheme跳转协议

Android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转到我们App中的各个页面;

通过scheme协议,服务器也可以定制化告诉App跳转到那个页面,可以通过通知栏消息定制化跳转页面,也可以通过H5页面跳转到页面等。

下面简单讲一下scheme的使用。

第一步,将满足scheme协议的Activity在清单文件里面进行注册:


    
        

        

        
    

第二步,在需要调用的地方,定义URI格式(也就是我们自定义的协议),其中格式URI格式如下:

[scheme:][//domain][path][?query][#fragment]

代码举例说明如下:

tvDomain = (TextView) findViewById(R.id.tvDomain);
tvDomainWithParams = (TextView) findViewById(R.id.tvDomainWithParams);

tvDomain.setText(Html.fromHtml("无参示例"));
tvDomain.setMovementMethod(LinkMovementMethod.getInstance());


tvDomainWithParams.setText(Html.fromHtml("有参示例"));
tvDomainWithParams.setMovementMethod(LinkMovementMethod.getInstance());

第三步,在onCreate方法或者onNewIntent方法中进行URI的解析,根据实际的业务逻辑进行处理

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Uri uri = intent.getData();
    if (uri != null) {
        dispatchUri(uri);
    } else {
        Log.e(TAG, "Uri is null");
    }
}



//URI的解析
private void dispatchUri(Uri uri) {
    try {
        final String domain = uri.getAuthority();
        if (TextUtils.equals(SECOND_DOMAIN, domain)) {
            final int id = Integer.valueOf(uri.getQueryParameter("id"));
            final String name = uri.getQueryParameter("name");
            Toast.makeText(this, id + "  " + name, Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        Log.e(TAG, "Uri Parse Error");
    }
}

关于scheme的调用,可以根据具体的实际业务场景进行自行设计,像通知栏的跳转,网页的跳转啥的,具体的内容可以查看相关博客进行更深一步的学习。


干货总结

以上,是这一次关于Activity知识的一个整理,其实,Activity的知识点可以讲的很简单,也可以深入Framework层进行分析,那样理解起来会比较吃力,但收获也将不少。奈何最近各种需要干苦力,这些分析就留到Android源码分析的时候再深入了解吧。

我们作为一个Android开发人员来讲,Activity是四大组件中离我们最近,接触得最多的一个,需要对它的一些原理,机制有一定的了解,希望通过这一篇文章,能够提供一个清晰的思路来回顾Activity,能够回答以下问题:

1. 什么是Activity

2. activity有哪些状态

3. 手绘Activity的生命周期图

4. Android系统中的进程优先级

5. Activity的四种启动模式简述

6. scheme跳转协议是什么

你可能感兴趣的:(Android基础知识回顾之Activity)