一篇就够了系列之Activity全解析

前言:

Activity作为Android四大组件之一Google官方文档,是Android开发中最基本最常用的东西,那么,Activity的定义到底是什么呢?
从下面几个方面介绍下Activity:

  1. 生命周期
  2. 任务栈
  3. 启动模式
  4. scheme跳转协议

生命周期

这其实是一个老生常谈的东西,更是每一个Android开发人员熟记于心的东西,直接上图:
这里写图片描述

每个状态的特点大致为:

  • onCreate:初始化操作,不可见,不可触摸
  • onStart:创建完成,可见,不可触摸
  • onResume:运行状态,可见,可触摸
  • onPause:暂定状态,可见,不可触摸
  • onStop:停止状态,不可见,不可触摸
  • onDestory:销毁状态

下面五个循环状态需要注意:

  1. onCreate->onStart->onResume->onPause->onStop->onDestory(Activity创建到销毁)
  2. onResume->onPause->onResume此时Activity一直是可见状态,比如此时弹出了一个Diglog,生命周期就是该流程
  3. onStart->onResume->onPause->onStop->onRestart->onStart Activity A被Activity B所覆盖,然后B销毁,A重新出现在屏幕上,此时就是该生命周期的流程,这个和将App直接按Home建退到后台是一样的流程
  4. onCreate->onStart->onResume->onPause->onStop->APP process killed->onCreate 这个流程主要是Activity在后台,内存不足时被系统给回收销毁,然后再重新打开了。
  5. 屏幕在进行旋转后,生命周期是:销毁->创建,同时,会增加两个方法:onSaveInstanceStateonRestoreInstanceState,此时完整的生命周期是:onCreate->onStart->onResume->onPause->onSaveInstanceState->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume->Running状态 ,利用那两个方法,可以在销毁之前进行信息保存,创建的时候再直接去除,比如代码:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.i("wy","oncreate");
        if(savedInstanceState!=null){
            String str=savedInstanceState.getString("wy");
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        Log.i("wy","onRestoreInstanceState");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("wy","wy");
        Log.i("wy","onSaveInstanceState");
    }

一般的视屏播放都是这样进行屏幕旋转状态保存的。

任务栈

定义:任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。
这里写图片描述
这张图片说明了Activity 1,2,3在同一个栈中创建及销毁的示意图。很明显,一般情况下,新创建的Activity实例会在栈的顶部,Running状态,销毁后,下面的Activity会出现在栈顶,此时该Activity就是Running状态,实际上,一个应用,可以有多个任务栈同时存在,这就涉及到Activity的启动模式了。

启动模式

在清单文件中声明 Activity 时,您可以使用 元素的 launchMode 属性指定 Activity 应该如何与任务关联。
launchMode 属性指定有关应如何将 Activity 启动到任务中的指令。您可以分配给 launchMode 属性的启动模式共有四种:

“standard”(默认模式)

默认。系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。

“singleTop”

如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例(但前提是位于返回栈顶部的 Activity 并不是 Activity 的现有实例)。
例如,假设任务的返回栈包含根 Activity A 以及 Activity B、C 和位于顶部的 D(堆栈是 A-B-C-D;D 位于顶部)。收到针对 D 类 Activity 的 Intent。如果 D 具有默认的 “standard” 启动模式,则会启动该类的新实例,且堆栈会变成 A-B-C-D-D。但是,如果 D 的启动模式是 “singleTop”,则 D 的现有实例会通过 onNewIntent() 接收 Intent,因为它位于堆栈的顶部;而堆栈仍为 A-B-C-D。但是,如果收到针对 B 类 Activity 的 Intent,则会向堆栈添加 B 的新实例,即便其启动模式为 “singleTop” 也是如此。

注:为某个 Activity 创建新实例时,用户可以按“返回”按钮返回到前一个 Activity。 但是,当 Activity 的现有实例处理新 Intent 时,则在新 Intent 到达 onNewIntent() 之前,用户无法按“返回”按钮返回到 Activity 的状态。

“singleTask”

系统创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。一次只能存在 Activity 的一个实例。
注:尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。

“singleInstance”.

与 “singleTask” 相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。

说到Manifest中的注册文件,关于Activity的一共有以下:

<activity android:allowEmbedded=["true" | "false"]
          android:allowTaskReparenting=["true" | "false"]
          android:alwaysRetainTaskState=["true" | "false"]
          android:autoRemoveFromRecents=["true" | "false"]
          android:banner="drawable resource"
          android:clearTaskOnLaunch=["true" | "false"]
          android:configChanges=["mcc", "mnc", "locale",
                                 "touchscreen", "keyboard", "keyboardHidden",
                                 "navigation", "screenLayout", "fontScale",
                                 "uiMode", "orientation", "screenSize",
                                 "smallestScreenSize"]
          android:documentLaunchMode=["intoExisting" | "always" |
                                  "none" | "never"]
          android:enabled=["true" | "false"]
          android:excludeFromRecents=["true" | "false"]
          android:exported=["true" | "false"]
          android:finishOnTaskLaunch=["true" | "false"]
          android:hardwareAccelerated=["true" | "false"]
          android:icon="drawable resource"
          android:label="string resource"
          android:launchMode=["standard" | "singleTop" |
                              "singleTask" | "singleInstance"]
          android:maxRecents="integer"
          android:multiprocess=["true" | "false"]
          android:name="string"
          android:noHistory=["true" | "false"]  
          android:parentActivityName="string" 
          android:permission="string"
          android:process="string"
          android:relinquishTaskIdentity=["true" | "false"]
          android:resizeableActivity=["true" | "false"]
          android:screenOrientation=["unspecified" | "behind" |
                                     "landscape" | "portrait" |
                                     "reverseLandscape" | "reversePortrait" |
                                     "sensorLandscape" | "sensorPortrait" |
                                     "userLandscape" | "userPortrait" |
                                     "sensor" | "fullSensor" | "nosensor" |
                                     "user" | "fullUser" | "locked"]
          android:stateNotNeeded=["true" | "false"]
          android:supportsPictureInPicture=["true" | "false"]
          android:taskAffinity="string"
          android:theme="resource or theme"
          android:uiOptions=["none" | "splitActionBarWhenNarrow"]
          android:windowSoftInputMode=["stateUnspecified",
                                       "stateUnchanged", "stateHidden",
                                       "stateAlwaysHidden", "stateVisible",
                                       "stateAlwaysVisible", "adjustUnspecified",
                                       "adjustResize", "adjustPan"] >   
    . . .
</activity>

具体意义可以参照:Google官方文档

scheme跳转协议

这里的scheme是一种页面内跳转协议,主要用于支持一下几种场景:

  • 服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面;

  • H5页面点击锚点,根据锚点具体跳转路径App端跳转具体的页面;

  • 从一个App跳转到另一个App的页面

    首先,我们需要知道URI的概念:
    URI:通用资源标识符(Universal Resource Identifier),URI主要分三个部分:scheme, authority and path。其中authority又分为host和port。格式如下:
    scheme://host:port/path, 比如:wy://myproject:8080/data/src/name,
    就安卓手机本身而言,比如手机联系人的信息,都是通过这样的格式进行提供,并且其scheme一般是“content”。

1.请求到服务器的请求数据后,可以前后端进行一个URI格式的定义,然后跳转相应的页面。比如
详情页:wy://myproject:8080/info
订单页:wy://myproject:8080/order
相应的Activity的manifest中的注册时这样的:

        <activity
            android:name=".InfoActivity"
            android:label="@string/title_info"
            android:theme="@style/AppTheme.NoActionBar">

            <intent-filter>

                <action android:name="android.intent.action.VIEW"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <category android:name="android.intent.category.BROWSABLE"></category>
                <data
                    android:scheme="wy"
                    android:host="myproject"
                    android:port="8080"
                    android:path="/info">
                </data>
            </intent-filter>
        </activity>

                <activity
            android:name=".OrderActivity"
            android:label="@string/title_Order"
            android:theme="@style/AppTheme.NoActionBar">

            <intent-filter>

                <action android:name="android.intent.action.VIEW"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <category android:name="android.intent.category.BROWSABLE"></category>
                <data
                    android:scheme="wy"
                    android:host="myproject"
                    android:port="8080"
                    android:path="/order">
                </data>
            </intent-filter>
        </activity>

注意:

<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>

上面两句一定不能少,

<category android:name="android.intent.category.BROWSABLE"></category>

这句是想用js事件的,最好加上

                <data
                    android:scheme="wy"
                    android:host="myproject"
                    android:port="8080"
                    android:path="/order">
                </data>

这里面四个属性关系是一次下降,即scheme如果没有设置,下面三个设置的属性都会失效。

网页链接跳转为:

 tv.setText(Html.fromHtml("<a href='wy://myproject:8080/info'>点我一下</a>"));

注意:Java代码中的链接格式数据一定要**大于等于**manifest中注册的格式,比如针对以上的data格式,如果

tv.setText(Html.fromHtml("<a href='wy://myproject:8080'>点我一下</a>"));
tv.setText(Html.fromHtml("<a href='wy://myproject'>点我一下</a>"));
tv.setText(Html.fromHtml("<a href='wy://'>点我一下</a>"));

都是不行的,但是如果,manifest中data格式是:

                <data
                    android:scheme="wy"
                </data>

那么以上几种都是可以跳转的。主要就是上面要注意的几点问题,不然无法进行跳转。

App内部隐式跳转:

                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("wy://myproject:8080/info"));
                startActivity(intent);

从一个App跳转到另一个App也是类似。

以上,主要就是Activity在开发中使用到的设计知识点。欢迎大家留言评论交流。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ActivityManager是Android系统中非常重要的一个组件,负责管理系统中所有Activity生命周期、进程管理、任务管理等。在本篇文章中,我们将深入了解ActivityManager框架的实现原理。 ## Activity的启动过程 在Android系统中,Activity是应用程序中最基本的界面单元。当用户点击应用程序的图标时,ActivityManager会负责启动应用程序并启动相应的Activity。下面是Activity的启动过程: 1. 应用程序进程启动:ActivityManager会创建一个新的进程来运行应用程序。 2. 应用程序的Application对象创建:在应用程序进程启动之后,ActivityManager会负责创建应用程序的Application对象。 3. Activity对象创建:当用户点击应用程序的图标并选择启动Activity时,ActivityManager会负责创建相应的Activity对象。 4. Activity的onCreate方法调用:ActivityManager会调用Activity对象的onCreate方法,完成Activity的初始化工作。 5. Activity的onStart方法调用:ActivityManager会调用Activity对象的onStart方法,将Activity显示给用户。 6. Activity的onResume方法调用:ActivityManager会调用Activity对象的onResume方法,让Activity成为用户交互的焦点。 7. Activity生命周期结束:当用户退出Activity时,ActivityManager会负责销毁Activity对象。 ## 进程管理 在Android系统中,每个应用程序都运行在一个独立的进程中。ActivityManager负责管理所有进程,以确保系统的稳定和性能。 当应用程序被启动时,ActivityManager会为其创建一个新的进程并分配一定的内存资源。如果此时系统内存不足,ActivityManager会根据一定的策略来回收一些进程内存,以确保系统正常运行。 ActivityManager还负责监控进程的CPU使用情况和内存使用情况。如果一个进程的CPU使用率过高或者内存使用量过大,ActivityManager会考虑回收该进程的资源,以避免系统崩溃。 ## 任务管理 在Android系统中,任务是指一组相关的Activity。当用户启动一个应用程序时,ActivityManager会创建一个新的任务,并将应用程序的第一个Activity加入到该任务中。 当用户从一个Activity切换到另一个Activity时,ActivityManager会将前一个Activity加入到任务的后台,并将新的Activity显示给用户。当用户点击返回键时,ActivityManager会将当前Activity从任务中移除,并将前一个Activity重新显示给用户。 需要注意的是,当应用程序中的所有Activity都被销毁时,该应用程序的任务也会被销毁。这是因为Android系统中的Activity都是基于任务的,一个应用程序的所有Activity都属于同一个任务。 ## 总结 ActivityManager是Android系统中非常重要的一个组件,它负责管理系统中所有Activity生命周期、进程管理、任务管理等。在本篇文章中,我们深入了解了ActivityManager的实现原理。熟悉ActivityManager的工作原理对于开发高质量的Android应用程序非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值