Android应用开发(四):Activity的四大启动模式

简介: <p></p> <p>本文主要介绍<span style="font-family:Times New Roman">Activity</span><span style="font-family:宋体">的启动模式,即</span><span style="background:rgb(249,249,249)">"standard"(<span style="font-family:

本文主要介绍Activity的启动模式,即"standard"(默认模式)"singleTop ""singleTask""singleInstance"四大启动模式,在此之前简单总结了一下Android组件的相关知识。

 

1Android组件的相关知识


对于Android应用,其应用程序的进程运行方式为:每一个应用程序都运行在它自己的Linux进程中,当应用程序中的任何代码需要执行时,Android将启动进程;当它不在需要且系统资源被其他应用程序请求时,Android将关闭进程。

同时,需要注意的是:Android应用程序不像别的应用程序那样有Main函数入口点,它没有单一的程序入口点,但是它必须要有四个组件中的一个或几个:活动(Activities)、服务(Services)、广播接收者(Broadcast receivers)、内容提供者(Content providers)。

 下面分别简单地介绍一下四个组件的概念和作用:

1)、活动(Activities):一个活动表示一个可视化的用户界面,关注一个用户从事的事件。例如,一个活动可能表示一个用户可选择的菜单项列表,或者可能显示照片连同它的标题。每个活动一起工作形成一个整体的用户界面,但是每个活动是独立于其他活动的。每一个都是作为Activity基类的一个子类的实现。

2)、服务(Services一个服务没有一个可视化用户界面,而是在后台无期限地运行。例如一个服务可能是播放背景音乐而用户做其他一些事情,或者它可能从网络获取数据,或计算一些东西并提供结果给需要的活动(activities)。每个服务都继承自Service基类。

3)、广播接收者(Broadcast receivers):一个广播接收者是这样一个组件,它不做什么事,仅是接受广播公告并作出相应的反应。许多广播源自于系统代码,例如公告时区的改变、电池电量低、已采取图片、用户改变了语言偏好。应用程序也可以发起广播,例如为了其他程序知道某些数据已经下载到设备且他们可以使用这些数据。

一个应用程序可以有任意数量的广播接收者去反应任何它认为重要的公告。所有的接受者继承自BroadcastReceiver基类。

4)、内容提供者(Content providers):内容提供者(content provider)使一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统中、在一个SQLite数据库、或以任何其他合理的方式。内容提供者继承自ContentProvider 基类并实现了一个标准的方法集,使得其他应用程序可以检索和存储数据。然而,应用程序并不直接调用这些方法。相反,替代的是它们使用一个ContentResolver对象并调用它的方法。ContentResolver能与任何内容提供者通信,它与提供者合作来管理参与进来的进程间的通信。

 

2Activity的启动模式(Launch modes


有四种不同的启动模式可以分配到<activity>元素的launchMody属性: "standard"(默认模式)"singleTop ""singleTask""singleInstance"

1)、"standard"(默认模式)

假设目标taskactivity栈为: A->B->C->D(栈底->栈顶)在程序中调用startActivityD如果Dstandard模式, activity栈变为:A->B->C->D->D, 也就是会重新创建一个D实例

2)、"singleTop "

假设目标taskactivity栈为: A->B->C->D(栈底->栈顶)在程序中调用startActivityD如果DsingleTop模式, activity栈变为:A->B->C->D,不会创建D实例,就是说如果D在目标task 的activity栈的栈顶,则不会创建新的实例,而是调用D的onNewIntent()方法,反之如果D不在目标task 的activity栈的栈顶,则会重新创建一个D实例。

3)、"singleTask"

假设目标taskactivity栈为: A->B->C->D(栈底->栈顶)如果A调用startActivity(B)启动B实例,则A和B位于同一个task中。

4)、"singleInstance"

假设目标taskactivity栈为: A->B->C->D(栈底->栈顶)如果A调用startActivity(B)启动B实例,则系统会自动给intent添加一个属性FLAG_ACTIVITY_NEW_TASK,将B实例放入到一个新的task中,也就是说A实例所在的task中只能有A自己,不能存在其他实例。


3、验证方法


编程设计两个Activity,一个是MainActivity,另一个是B Activity,在两个Activity中都设置两个按钮,都实现点击返回自身和另一个Activity的功能。在AndroidMainfest.xml中配置launchMode即可实现四种不同的Activity启动模式。

1)、按钮设计

按钮实现代码如下:

<Button
    android:textAllCaps="false"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="启动MainActivity"
    android:id="@+id/startMainAty" />

<Button
    android:textAllCaps="false"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="启动B Activity"
    android:id="@+id/startBAty" />

2)、实现两个Activity之间的切换功能

MainActivity中的实现代码如下:

private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv = (TextView) findViewById(R.id.tv);

    tv.setText(String.format("TaskID:%d\nMainActivityID:%s",getTaskId(),toString()));

    findViewById(R.id.startMainAty).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this,MainActivity.class));
        }
    });

    findViewById(R.id.startBAty).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this,BAty.class));
        }
    });
}

B Activity中的实现代码如下:

private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_baty);

    tv = (TextView) findViewById(R.id.tv);

    tv.setText(String.format("TaskID:%d\nB ActivityID:%s",getTaskId(),toString()));

    findViewById(R.id.startMainAty).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(BAty.this,MainActivity.class));
        }
    });

    findViewById(R.id.startBAty).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(BAty.this,BAty.class));
        }
    });

}

3)、Activity启动模式切换方法

AndroidMainfest.xml中配置launchMode即可实现四种不同的Activity启动模式。

更改的对应代码如下:

android:launchMode="singleInstance" >

可以配置为:standard(默认方式)/singleTop/singleTask/singleInstance四种方式之一。


4、测试结果


1)、"standard"(默认模式)

第一个启动的界面如下:

点击“启动MainActivity”,界面为:

点击“启动MainActivity”,界面为:

点击“启动B Activity”,界面为:

点击“启动B Activity”,界面为:

点击“启动MainActivity”,界面为:

测试结果为:任务ID不变,但是每点击一次按钮,实例的ID发生一次变化;B Activity的测试结果也一样,即任务ID不变,但是每点击一次按钮,实例的ID发生一次变化。

结果分析:默认情况下,在同一个任务栈中创建了不同的实例。

应用:可以实现Activity任务之间的跳转机制,原理就是任务栈是先进后出的。


2)、"singleTop "

第一个启动的界面如下:

点击“启动MainActivity”,界面为:

点击“启动B Activity”,界面为:


点击“启动B Activity”,界面为:

点击“启动MainActivity”,界面为:

测试结果为:点击MainActivity,没有发生变化,说明没有创建新的实例;点击B Activity,实例ID发生变化,说明B Activity创建了新的实例。

结果分析:如果当前Activity处于栈顶,只能创建一个实例;如果当前Activity不处于栈顶,可以创建新的实例。


3)、"singleTask"

第一个启动的界面如下:

点击“启动MainActivity”,界面为:

点击“启动B Activity”,界面为:


点击“启动B Activity”,界面为:


点击“启动 MainActivity ”,界面为:


点击返回键,APP退出。

测试结果为:点击MainActivity,没有发生变化,说明没有创建新的实例;点击B Activity,实例ID发生变化,说明B Activity创建了新的实例,但是在B Activity中点击MainActivity,会发现其实例ID与刚开始的实例ID一致,再次点击返回,APP退出。

结果分析:singleTask使得任务栈中只能存在一个任务,若存在两个Activity,会将之前的Activity自动弹出。


4)、"singleInstance"

第一个启动的界面如下:

点击“启动MainActivity”,界面为:

点击“启动B Activity”,界面为:

点击“启动B Activity”,界面为:

点击“启动MainActivity”,界面为:

测试结果为:不同的Activity的任务ID不同。

结果分析:一个任务栈中只能有一个Activity,两个任务栈可以互相切换。




目录
相关文章
|
17天前
|
存储 XML 开发工具
探索安卓应用开发:从基础到进阶
在这篇文章中,我们将一起踏上安卓应用开发的旅程。不论你是编程新手还是希望提升技能的开发者,这里都有你需要的东西。我们会从最基础的概念开始,逐步深入到更复杂的主题。文章将涵盖开发环境设置、用户界面设计、数据处理以及性能优化等方面。通过理论与实践的结合,你将能够构建出既美观又高效的安卓应用。让我们一起开启这段技术之旅吧!
|
24天前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
7天前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
21天前
|
缓存 监控 前端开发
探索Android应用开发之旅:从新手到专家
【10月更文挑战第42天】本文将带你踏上Android应用开发的旅程,无论你是初学者还是有经验的开发者。我们将一起探索如何从零开始创建你的第一个Android应用,并逐步深入到更高级的主题,如自定义视图、网络编程和性能优化。通过实际示例和清晰的解释,你将学会如何构建高效、吸引人的Android应用。让我们一起开启这段激动人心的旅程吧!
|
21天前
|
开发框架 前端开发 Android开发
探索安卓和iOS应用开发中的跨平台解决方案
【10月更文挑战第42天】在移动应用开发的广阔天地中,安卓和iOS系统如同两座巍峨的山峰,分别占据着半壁江山。开发者们在这两座山峰之间穿梭,努力寻找一种既能节省资源又能提高效率的跨平台开发方案。本文将带你走进跨平台开发的世界,探讨各种解决方案的优势与局限,并分享一些实用的代码示例,助你在应用开发的道路上更加游刃有余。
|
1月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
1月前
|
Android开发 Swift iOS开发
探索iOS与安卓应用开发的差异性
探索iOS与安卓应用开发的差异性
47 2
|
1月前
|
传感器 XML IDE
探索安卓应用开发:从基础到进阶
【10月更文挑战第23天】在数字化时代的浪潮中,移动应用已成为人们日常生活的延伸。本文以安卓平台为例,深入浅出地介绍了如何从零开始构建一个安卓应用,涵盖了开发环境搭建、基本组件使用、界面设计原则以及进阶技巧等关键步骤。通过实例演示和代码片段,引导读者逐步掌握安卓应用开发的核心技能,旨在激发更多开发者对安卓平台的探索热情,并为初学者提供一条清晰的学习路径。
|
28天前
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
1月前
|
开发工具 Android开发 Swift
探索iOS与安卓应用开发的异同点
【10月更文挑战第24天】本文通过比较iOS和安卓开发环境,旨在揭示两大移动平台在开发过程中的相似性与差异性。我们将探讨开发工具、编程语言、用户界面设计、性能优化及市场分布等方面,以期为开发者提供全面的视角。通过深入浅出的分析,文章将帮助读者更好地理解每个平台的独特之处及其对应用开发的影响。