热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android程序前后台切换,Android中应用前后台切换监听的实现详解

前言最近在工作中遇到了这么一个需求:如何实现Android应用前后台切换的监听?下面来一起看看详细的介绍:iOS内边是可以实现的ÿ

前言

最近在工作中遇到了这么一个需求:如何实现 Android 应用前后台切换的监听?下面来一起看看详细的介绍:

iOS 内边是可以实现的,AppDelegate 给了一个回调监听:

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

func applicationWillResignActive(_ application: UIApplication) {

// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

}

func applicationDidEnterBackground(_ application: UIApplication) {

// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

}

func applicationWillEnterForeground(_ application: UIApplication) {

// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

}

func applicationDidBecomeActive(_ application: UIApplication) {

// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

}

}

我保留了系统注释。一个iOS应用周期,大概的流程是这样的。

应用从前台进入到后台:

applicationWillResignActive() -> applicationDidEnterBackground()

应用从后台恢复到前台:

applicationWillEnterForeground() -> applicationDidBecomeActive()

Android 中也存在 Application,但是并没有提供前后台切换的监听。

倒不如说,在 Android 中,压根就没有应用前后台的概念。

Android 中基本页面单位是 Activity。

Activity 有自己的生命周期,但是 Application 却没有一个整体的生命周期。

我们可以通过监听 Activity 的生命周期,来模拟实现一个 Application 的生命周期。

Activity 的生命周期不在阐述,写过 Android 的都应该知道。

我们假设现在有两个 Activity 分别是 A 和 B,A 是启动页面,那么生命周期回调是这样的:(我们忽略掉一些不关心的回调)

A 被启动或者 A 进入前台

A.onStart()

A.onResume()

从 A 跳转到 B:

A.onPause()

B.onStart()

B.onResume()

A.onStop()

从 B 返回 A:

B.onPause()

A.onStart()

A.onResume()

B.onStop()

A 被关闭或者 A 进入后台

A.onPause()

A.onStop()

注意上面两个页面回调的启动顺序。

onResume 和 onPause 是一组,两个页面之间是顺序调用。

onStart 和 onStop 是一组,两个页面之间是交叉调用。

也就是说,A 启动到 B,会先调用 B.onStart() ,然后再调用 A.onStop() ;而 B 返回 A 则是相反的,会先调用 A.onStart() ,然后再调用 B.onStop() 。

利用这个特性,我们可以做一个全局计数器,来记录前台页面的数量,在所有 Activity.onStart()中计数器 +1,在所有 Activity.onStop()中计数器 -1。计数器数目大于0,说明应用在前台;计数器数目等于0,说明应用在后台。计数器从1变成0,说明应用从前台进入后台;计数器从0变成1,说明应用从后台进入前台。

有了思路,我们来实现。

Application 提供了一个监听器用于监听整个应用中 Activity 声明周期:Application.ActivityLifecycleCallbacks 。

这个监听器要求 API >&#61; 14。对应 API <14 的情况&#xff0c;可以通过编写一个 BaseActivity&#xff0c;然后让所有的 Activity 都集成这个类来实现整个应用 Activity 声明周期的监听&#xff0c;效果是相同的。

API >&#61; 14&#xff0c;实现如下&#xff1a;

public class ApplicationListener implements Application.ActivityLifecycleCallbacks {

private int foregroundCount &#61; 0; // 位于前台的 Activity 的数目

&#64;Override

public void onActivityStarted(final Activity activity) {

if (foregroundCount <&#61; 0) {

// TODO 这里处理从后台恢复到前台的逻辑

}

foregroundCount&#43;&#43;;

}

&#64;Override

public void onActivityStopped(Activity activity) {

foregroundCount--;

if (foregroundCount <&#61; 0) {

// TODO 这里处理从前台进入到后台的逻辑

}

}

/*

* 下面回调&#xff0c;我们都不需要

*/

&#64;Override

public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

&#64;Override

public void onActivityResumed(Activity activity) {}

&#64;Override

public void onActivityPaused(Activity activity) {}

&#64;Override

public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}

&#64;Override

public void onActivityDestroyed(Activity activity) {}

}

我们在 Application 中注册这个监听器来发挥效果&#xff1a;

public class MyApplication extends Application {

&#64;Override

public void onCreate() {

super.onCreate();

registerActivityLifecycleCallbacks(new ApplicationListener());

}

}

对于 API <14 的情况&#xff0c;BaseActivity 实现如下&#xff1a;

public class BaseActivity extends AppCompatActivity {

private static int foregroundCount &#61; 0; // 注意是个静态变量

&#64;Override

protected void onStart() {

super.onStart();

if (foregroundCount <&#61; 0) {

// TODO 这里处理从后台恢复到前台的逻辑

}

foregroundCount&#43;&#43;;

}

&#64;Override

protected void onStop() {

foregroundCount--;

if (foregroundCount <&#61; 0) {

// TODO 这里处理从前台进入到后台的逻辑

}

super.onStop();

}

}

总结

以上就是这篇文章的全部内容了&#xff0c;希望本文的内容对大家的学习或者工作能带来一定的帮助&#xff0c;如有疑问大家可以留言交流&#xff0c;谢谢大家对脚本之家的支持。



推荐阅读
  • 在C#中,使用关键字abstract来定义抽象类和抽象方法。抽象类是一种不能被实例化的类,它只提供部分实现,但可以被其他类继承并创建实例。抽象类可以用于类、方法、属性、索引器和事件。在一个类声明中使用abstract表示该类倾向于作为其他类的基类成员被标识为抽象,或者被包含在一个抽象类中,必须由其派生类实现。本文介绍了C#中抽象类和抽象方法的基础知识,并提供了一个示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • HBase干货 | 如何优雅的通过Key与Value分离降低写放大难题?
    本文将为大家介绍为什么这样能够有效的降低写放大,然后聊聊几个keyvalue分离系统的结构,包括两篇影响比较广泛的学术论文,以及HBase在keyvalue ... [详细]
author-avatar
坨大大
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有