探秘活动组件之道:揭开Android程序活动的魅力

第四章:程序活动单元Activity

  • Activity是Android app中的一个重要的组件。它为用户提供可交互的一个窗口。通常该窗口充满一屏,但有时比一屏小,并浮在其他窗口上

四大组件

应用组件是 Android 应用的基本构建基块.共有四种不同的应用组件类型

  • Activity:Activity 是与用户交互的入口点。它表示拥有界面的单个屏幕。
  • Service(服务):服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。 服务不提供用户界面。
  • ContentProvider(内容提供程序):内容提供程序管理一组共享的应用数据,是底层数据存储和上层应用的数据接口。
  • BroadcastReceiver(广播接收器):广播接收器是一种用于响应系统范围广播通知的组件。 许多广播都是由系统发起的 — 例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。
  • 启动组件:四种组件类型中的三种 — Activity、服务和广播接收器 — 通过名为 Intent(意图) 的异步消息进行启动。Intent 会在运行时将各个组件相互粘合(可以将 Intent 视为从其他组件请求操作的信使)。

Activity生命周期

Activity的神明周期指的是Activity从创建到销毁的整个状态。过程大致可以分为五个状态,启动状态、运行状态、暂停状态、停止状态、销毁状态。

在这里插入图片描述
在这里插入图片描述

Activity的启动模式

  • Android的任务栈是一种用来存放Activity实例的容器,任务栈最大的特点:先进后出,两个基本操作:入栈和出栈。打开Activity,执行Activity入栈操作;销毁Activity,执行出栈操作。不用配置<activity>android:launchMode属性,当然也可以指定该属性值为standard
  • activity的启动模式有四种:standard、singleTop、singleTask、singleInstance。

standard

  • standard模式是默认的启动模式,该方法的特点:每启动一个activity就会再栈顶创建一个新的实例。
  • 闹钟程序通常使用这种模式
    在这里插入图片描述

singleTop

  • 该模式只会判断要启动的activity是否位于栈顶,如果位于栈顶,则直接复用,否则创建新的实例。
  • <activity>指定属性android:launchMode="singleTop"
  • 浏览器的书签通常采用这种模式
    在这里插入图片描述

singleInstance

  • 这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。
  • Android中的桌面使用的就是该模式。

两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下
在这里插入图片描述

singleTask

  • :如果要启动的Activity已经存在于任务栈中,则不会创建新的实例,而是将该Activity上面的所有实例全部弹出栈,同时将该Activity实例移到栈顶,并调用其onNewIntent()方法;如果要启动的Activity不存在于任务栈中,则会创建新的实例,并将其加入到任务栈中。
  • FirstActivity的属性android:launchMode="singleTask"
  • 来电界面常用这种模式
    在这里插入图片描述

Intent

在这里插入图片描述

  • Intent(意图)是程序中各组件之间进行加护的一种重要方式,不仅可以指定当前组件要执行的动作,还可以在不同组件之间传递数据。
  • Intent分为显式Intent和隐式Intent
    • 显式Intent:需要直接指定目标组件
    //创建一个Intent对象,其中第1个参数为Context表示当前的Activity对象,第2个参数表示要启动的目标Activity。
    Intent intent = new Intent(this, SignInActivity.class);
    startActivity(intent);
    
    • 隐式Intent:无需明确指出需要激活的目标组件
      在这里插入图片描述
  • 当发送一个隐式Intent后,Android系统会将他与程序中的每一个组件的过滤器进行匹配,匹配属性有 action、data、category,需要这三个属性都匹配成功才能唤起相应的组件.
  • action:用于指定Intent对象的动
//在清单文件中为Activity添加<intent-filter>标签时,必须添加action属性,否则隐式Intent无法开启该Activity
<intent-filter>
    <action android:name="android.intent.action.EDIT"/>
    <action android:name="android.intent.action.VIEW"/>
</intent-filter>

  • data:指定数据的URI或者数据MIME类型他的值通常与Intent的action属性有关联
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http..."/>
    <data android:mimeType="audio/mpeg" android:scheme="http..."/>
</intent-filter>
  • 隐式Intent携带的data数据只要与IntentFilter中的任意一个data声明相同,data属性就匹配成功
  • category:用于为action添加额外信息
<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

  • 一个IntentFilter可以不声明category属性,也可以声明多个category属性。
  • 隐式Intent中声明的category必须全部能够与某一个IntentFilter中的category匹配才算匹配成功
  • 注意:IntentFilter中罗列的category属性数量必须大于或者等于隐式Intent携带的category属性数量时,category属性才能匹配成功。如果一个隐式Intent没有设置category属性,那么他可以通过任何一个IntentFilter(过滤器)的category匹配

IntentFilter

  • <activity>中使用<intent-filter>可以指定各种intent过滤器,过滤器的作用就是声明其他app组件是如何激活该activity的.
  • 当创建一个新的app时,会自动创建一个根activity,它里面会包含一个intent过滤器,该过滤器声明本activity对"main"动作进行响应,并处于"launcher"这个类别中,如下:
    <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    

Activity之间的数据传递

putExtra()方法传递数据

putExtra()是Intent类中的一个方法,用于向Intent中添加附加信息,以便在启动Activity时传递数据。它的基本用法如下:

  1. 向Intent中添加一个字符串类型的附加信息:

    Intent intent = new Intent(this, TargetActivity.class);
    intent.putExtra("key", "value");
    startActivity(intent);
    
  2. 向Intent中添加一个整型类型的附加信息:

    Intent intent = new Intent(this, TargetActivity.class);
    intent.putExtra("key", 123);
    startActivity(intent);
    
  3. 向Intent中添加一个布尔型类型的附加信息:

    Intent intent = new Intent(this, TargetActivity.class);
    intent.putExtra("key", true);
    startActivity(intent);
    
  4. 向Intent中添加一个序列化对象类型的附加信息:

    Intent intent = new Intent(this, TargetActivity.class);
    MyObject myObject = new MyObject();
    intent.putExtra("key", myObject);
    startActivity(intent);
    
  • 需要注意的是,putExtra()方法支持传递多个附加信息,可以通过多次调用putExtra()方法来实现。在接收端的Activity中,可以通过getIntent()方法获取传递过来的Intent对象,并通过getXXXExtra()方法来获取附加信息的值。

Bundle类传递数据

Bundle是一个用于传递数据的类,它可以在不同的组件之间传递数据,如Activity、Service、BroadcastReceiver等。Bundle可以存储多种类型的数据,如字符串、整型、布尔型、序列化对象等,使用非常方便。下面是Bundle类传递数据的使用方法:

  1. 在发送端的组件中创建Bundle对象,并向其中添加需要传递的数据:
    Intent intent = new Intent(this, TargetActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString("key1", "value1");
    bundle.putInt("key2", 123);
    bundle.putBoolean("key3", true);
    MyObject myObject = new MyObject();
    bundle.putSerializable("key4", myObject);
    intent.putExtras(bundle);
    startActivity(intent);
    
  2. 在接收端的组件中获取Bundle对象,并从其中获取需要的数据:
    Intent intent = getIntent();
    Bundle bundle = intent.getExtras();
    String value1 = bundle.getString("key1");
    int value2 = bundle.getInt("key2");
    boolean value3 = bundle.getBoolean("key3");
    MyObject myObject = (MyObject) bundle.getSerializable("key4");
    
  • 需要注意的是,Bundle类传递数据时,数据的类型需要与接收端的组件能够处理的类型相匹配,否则会导致类型转换异常。同时,在传递大量数据时,应该考虑使用Parcelable接口来代替Serializable接口,以提高性能。

Activity之间的数据回传

  • startActivityForResult()方法用于开启一个Activity,当开启的Activity销毁时,希望从中返回数据
Intent intent = new Intent(this, TargetActivity.class);
startActivityForResult(intent, requestCode);
// 意图 请求码(用于标识请求的来源)
  • setResult()方法用于携带数据回传
Intent intent = new Intent();
intent.putExtra("result", resultData);
// 返回码 意图(用于携带数据并传回上一个界面)
setResult(Activity.RESULT_OK, intent);
finish();
  • OnActivityResult()方法用于接收回传的数据,并根据传递的参数requestCode、resultCode来标识数据的来源
@Override
// A、requestCode,表示在启动Activity时传递的请求码
// resultCode,表示在返回数据时传入结果码
// data,表示携带返回数据的Intent
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
    
    if (resultCode == Activity.RESULT_OK && requestCode == requestCode) {
    
    
        String resultData = data.getStringExtra("result");
        // 处理返回结果
    }
}

练习总结

  1. 简述Android中Activity的生命周期的方法及什么时候被调用?
    在这里插入图片描述

  1. onCreate():当Activity被创建时调用,用于进行一些初始化操作,如加载布局文件、绑定控件等。
  2. onStart():当Activity变为可见状态时调用,此时Activity还未获得用户焦点,无法与用户交互。
  3. onResume():当Activity获得用户焦点并开始与用户交互时调用,此时Activity处于前台运行状态。
  4. onPause():当Activity失去用户焦点但仍可见时调用,此时可以保存一些临时数据或暂停一些动画效果等。
  5. onStop():当Activity完全不可见时调用,可以在此时释放一些资源或停止一些服务等。
  6. onRestart():当Activity从停止状态重新启动时调用,此时Activity会重新执行onStart()和onResume()方法。
  7. onDestroy():当Activity被销毁时调用,可以在此时释放一些资源或停止一些服务等。

  1. Android中Activity的四种启动模式分别为:
    1. standard(标准模式):每次启动Activity都会创建一个新的实例,无论这个实例是否已经存在,即使是同一个应用程序中的Activity也是如此。如闹钟程序
    2. singleTop(栈顶复用模式):如果要启动的Activity已经位于任务的栈顶,则不会创建新的实例,而是直接使用该实例,并调用其onNewIntent()方法;如果要启动的Activity不在栈顶,则会创建新的实例。
    3. singleTask(栈内复用模式):如果要启动的Activity已经存在于任务栈中,则不会创建新的实例,而是将该Activity上面的所有实例全部弹出栈,同时将该Activity实例移到栈顶,并调用其onNewIntent()方法;如果要启动的Activity不存在于任务栈中,则会创建新的实例,并将其加入到任务栈中。
    4. singleInstance(单实例模式):在一个独立的任务栈中只有一个实例,即使是不同的应用程序也无法在该任务栈中创建新的实例。该模式一般用于需要全局唯一的应用程序组件,如拨号界面。

  1. 简述Activity、Intent、IntentFilter的作用?
    1. Activity:Activity是Android应用程序的界面部分,它负责与用户进行交互,接收用户输入,显示数据等。每个Activity都有自己的生命周期和状态,可以通过Intent来启动和传递数据。
    2. Intent:Intent是Android中用于传递消息和启动组件的一种机制,它可以在不同的组件之间传递数据、启动Activity、Service或BroadcastReceiver等。Intent可以包含数据和操作,用于描述需要执行的动作和要操作的数据。
    3. IntentFilter:IntentFilter是用于声明组件可以接收哪些Intent的一种机制,它可以指定Intent的action、category和data等属性,用于过滤可以被接收的Intent。当一个Intent被发送时,系统会根据Intent的属性和已注册的IntentFilter来匹配合适的组件来处理该Intent。

  1. Activity通过()方法可以设置它的布局文件
    A、setContentViews()
    B、setContentView()
    C、setLayoutView()
    D、setLayoutViews()

  1. Activity通过()方法可以设置它的布局文件,并把视图显示在界面上。
    A、setLayoutView()
    B、setContentView()
    C、setLayoutViews()
    D、setContentViews()

  1. Activity获取焦点时执行方法是
    A、onStart()
    B、onResume()
    C、onPause()
    D、onDestroy()

  1. ProgressBar通常用于访问网络展示loading对话框以及下载文件时显示的进度。它有两种表现形式,一种是水平的,另一种是环形的(

  1. Activity可以不用在AndroidManifest.xml文件中注册就可以运行(×
    • 在Android中,如果要启动一个Activity,必须在AndroidManifest.xml文件中注册该Activity,否则会导致运行时错误。AndroidManifest.xml文件是Android应用程序的配置文件,其中包含了应用程序的各种信息,包括Activity、Service、BroadcastReceiver、ContentProvider等组件的声明信息。在应用程序启动时,系统会读取AndroidManifest.xml文件中的信息,并根据其中的配置来启动相应的组件。
    • 如果一个Activity没有在AndroidManifest.xml文件中注册,那么当我们尝试启动该Activity时,系统会抛出ActivityNotFoundException异常,因为系统无法找到该Activity的声明信息。因此,必须在AndroidManifest.xml文件中注册每一个需要启动的Activity,否则应用程序将无法正常运行。

  1. Activity不是Context的子类(×
    • Activity是Context的子类。Activity继承自ContextThemeWrapper类,而ContextThemeWrapper类又继承自ContextWrapper类,而ContextWrapper类又继承自Context类。因此,Activity继承了Context类的所有方法和属性,并且还添加了一些自己的方法和属性。所以,我们可以在Activity中直接使用Context的方法和属性。

  1. 在目标Activity中,通常使用setResult方法设置返回数据(

  1. 通常一个应用程序对应一个任务栈,默认情况下每启动一个Activity都会入栈,并处于栈顶位置(

  1. Activity的startActivityForResult()方法接收两个参数,第一个参数是Intent,第二个参数是(请求码),用于在判断数据的来源

  1. ProgressBar)通常用于访问网络展示loading对话框以及下载文件时显示的进度

  1. Activity的生命周期中分为三种状态,分别是运行状态、(暂停状态)和停止状态

  1. Activity从启动到完全出现在用户面前会执行onCreate(),(onStart()),onResume()三个方法

  1. 在Activity生命周期的方法中, (onCreate())方法是在Activity实例对象被创建后用来初始化这个实例对象的

  1. 创建(Activity)时需要继承父类android.app.Activity或者其子类

猜你喜欢

转载自blog.csdn.net/yang2330648064/article/details/131177462