Android入门(六) | Activity 的启动模式 及 生产环境中关于 Activity 的小技巧

文章目录

  • Activity 的启动模式
    • standard
    • singleTop
    • singleTask
    • singleInstance
  • 技巧
    • 了解当前界面是哪个 Activity
    • 随时随地退出程序
    • 启动活动的最佳写法


Activity 的启动模式

  • standard:默认的启动方式,每次启动一个活动都会重新创建
  • singleTop:如果该活动处于栈顶,则不会创建新活动,不处于栈顶则创建新活动
  • singleTask:如果返回栈中存在该活动,那么将该活动之上的所有活动统统出栈,将该活动置于栈顶,如果不存在该活动则创建
  • singleInstance:会重新启用一个新的返回栈来创建该活动,通常用于共享活动的实例

standard

standard 是 Activity 默认的启动模式,在不进行显式指定的情况下,都使用这种模式。

在本模式下,每当启动一个新的活动,系统不会确认返回栈中是否已存在这个活动,而是直接创建该活动的一个新的实例并入栈。

在这里插入图片描述


singleTop

如果启动活动时发现返回栈栈顶已经是这个活动,则认为可以直接使用它,不会创建新的实例。

AndroidManifest.xml 中添加如下配置:
在这里插入图片描述
在这里插入图片描述


singleTask

每次启动该活动时,系统首先会在返回栈中检查是否存在该活动的实例:

  • 如果发现已经存在则直接使用该实例,并把在这个活动之上的活动统统出栈;
  • 如果没有就创建新的实例。

举个例子:

  1. 我们为 FirstActivity 配置 singleTask ;
  2. 然后在 FirstActivity 的 Button 上启动 SecondActivity
  3. 然后 SecondActivity 的 Button 上回到 FirstActivity
    在这里插入图片描述

我们可以得到这样的推断:

  1. SecondActivity 中启动 FirstActivity 时,会发现返回栈中已经存在一个 FirstActivity 的实例;
  2. 于是 SecondActivity 会从返回栈中出栈,而 FirstActivity 重新成为了栈顶活动;
  3. 因此 FirstActivity 的 onRestart()方法 和 SecondActivity 的 onDestroy() 方法会得到执行。

singleInstance

在本模式下,活动会启用一个新的返回栈来管理(如果 singleTask 模式指定了不同的 taskAffinity,也会启动一个新的返回栈)。如果我们想实现其他程序和我们的程序可以共享某个活动的实例,就可以用 singleInstance 模式创建一个单独的返回栈来管理这个活动,以此实现让任意应用程序都可以调用该活动。

举个例子:

  • FirstActivity 通过 Button 跳转到 SecondActivity
  • SecondActivity 通过 Button 跳转到 ThirdActivity,且修改 SecondActivity 的启动模式为 singleInstance
<activity android:name=".SecondActivity" android:launchMode="singleInstance">

倘若我们通过 log 来监测三个活动分属的返回栈,我们会发现:
在这里插入图片描述
SecondActivity 是存放在一个单独的返回栈里的。

而在 ThirdActivity 中按 Back 键,那么会直接返回到 FirstActivity,再按下返回键会回到 SecondActivity,再按下返回键才会退出程序。

原理很简单:

  • 由于 FirstActivityThirdActivity 是存放在同一个返回栈里的,当在 ThirdActivity 的界面按下 Back 键, ThirdActivity 会从返回栈中出栈,那么 FirstActivity 就成为了栈顶活动显示在界面上。
  • 然后在 FirstActivity 界面再次按下 Back 键,这时当前的返回栈已经空了,于是就显示了另一个返回栈的栈顶活动,即 SecondActivity
  • 最后再次按下 Back 键,这时所有返回栈都已经空了,也就自然退出了程序。

在这里插入图片描述


技巧

了解当前界面是哪个 Activity

新建一个普通 java 类 —— BaseActivity

public class BaseActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);Log.d("BaseActivity", getClass().getSimpleName());}
}

然后让每个活动类都改为继承自 BaseActivity,这样就可以在 LogCat 中看到当前类名。


随时随地退出程序

当在程序运行中的一个活动,要退出可能会需要按多次 Back 键(按 Home 键只是把程序挂起,并没有退出程序。),所以需要一个直接退出活动的方法。

新建一个 ActivityCollector 类作为活动管理器:

public class ActivityCollector {public static List<Activity> activities = new ArrayList<Activity>();public static void addActivity(Activity activity){ // 用于向 List 中添加一个 Activityactivities.add(activity);}public static void removeActivity(Activity activity){ // 用于从 List 中删除一个 Activityactivities.remove(activity);}public static void finishAll(){ // 用于将 List 中存储的所有活动全部销毁for (Activity activity : activities)if (!activity.isFinishing())activity.finish();}
}

接下来修改 BaseActivity

public class BaseActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);Log.d("BaseActivity", getClass().getSimpleName());ActivityCollector.addActivity(this);// 将当前正在创建的活动添加到活动管理器 ActivityCollector 里}@Overrideprotected void onDestroy(){super.onDestroy();ActivityCollector.removeActivity(this);// 将一个马上要销毁的活动从管理器 ActivityCollector 中移除}
}

以后,不管想在什么地方退出程序,只需要 ActivityCollector.finishAll() 就可以了。

保险起见也可以在销毁所有活动后杀掉当前进程,以保证程序完全退出:

android.os.Process.killProcess(android.os.Process.myPid());

killProcess() 方法用于杀掉一个进程,它接收一个进程 id 参数,通过 myPid() 方法来获得当前程序的进程 id。需要注意的是 killProcess() 方法只能用于杀掉当前程序的进程,我们不能使用这个方法去杀掉其他程序。


启动活动的最佳写法

之前启动的方法是构建一个新的 Intent,然后调用 startActivity() 或者 startActivityForResult() 来启动活动。如果 SecondActivity 需要用到两个字符串参数,那么 FirstActivity 可能会写成下面这样:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data1", s1);
intent.putExtra("extra_data2", s2);
startActivity(intent);

这样虽然可以,但是在 SecondActivity 是一个黑盒子时,是会出现问题的。可以修改 SecondActivity 的代码:

public static void actionStart(Context context, String s1, String s2){Intent intent = new Intent(context, SecondActivity.class);intent.putExtra("extra_data1", s1);intent.putExtra("extra_data2", s2);context.startActivity(intent);
}

和以往不同,在 actionStart() 方法中完成了 Intent 的构建,而非 onClick() 方法,所有 SecondActivity 中需要的数据都是通过 actionStart() 方法的参数传递过来的,然后把它们存储到 Intent 中,最后调用 startActivity() 方法启动。

这样在 onClick() 方法中只需一行代码即可启动 SecondActivity

button1.setOnclickListener(new OnclickListener() {@Overridepublic void onclick(View v) {SecondActivity.actionStart(FirstActivity.this, "data1", "data2");}
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android入门(七) | 常用控件

文章目录TextView 控件&#xff1a;文本信息Button 控件&#xff1a;按钮EditText 控件&#xff1a;输入框ImageView 控件&#xff1a;图片ProgressBar 控件&#xff1a;进度条AlertDialog 控件&#xff1a;提示框ProgressDialog 控件&#xff1a;带有进度条的提示框TextView 控…

Android入门(八) | 常用的界面布局 及 自定义控件

文章目录LinearLayout &#xff1a;线性布局android:layout_gravity &#xff1a;控件的对齐方式android:layout_weight&#xff1a;权重RelativeLayout &#xff1a;相对布局相对于父布局进行定位相对于控件进行定位边缘对齐FrameLayout &#xff1a;帧布局Percent &#xff1…

Android入门(九)| 滚动控件 ListView 与 RecyclerView

文章目录ListView内置类型的简单运用定制数据类型提升效率点击事件RecyclerView布局管理器点击事件ListView 内置类型的简单运用 由于手机屏幕空间有限&#xff0c;能够一次性在屏幕上显示的内容不多&#xff0c;当我们的程序有大量数据需要显示的时候就可以借助 ListView 来…

Android入门(10)| Fragment碎片详解

文章目录为什么要使用碎片&#xff08;Fragment&#xff09;实例布局文件FragmentActivity动态添加碎片布局文件FragmentActivity碎片通信Fragment布局文件Activity生命周期为什么要使用碎片&#xff08;Fragment&#xff09; 我们在手机上看新闻可能是这样的&#xff1a; Re…

Android开发(1) | Fragment 的应用——新闻应用

文章目录Item&#xff1a;标题子项布局文件Java代码标题碎片布局文件Java代码新闻内容碎片布局文件Java代码新闻内容活动布局文件Java代码首界面布局文件Java代码Item&#xff1a;标题子项 布局文件 news_item.xml&#xff1a; <TextViewxmlns:android"http://schema…

Android入门(11)| 全局广播与本地广播

文章目录广播概念接收广播动态注册实例静态注册实例发送广播发送标准广播广播的跨进程特性发送有序广播本地广播广播概念 Android 中的每个应用程序都可以对自己感兴趣的广播进行注册&#xff0c;这样该程序就只会接收到自己所关心的广播内容&#xff0c;这些广播可能是来自系…

Android开发(2) | 广播 Broadcast 的应用——强制下线功能

文章目录功能简介关闭所有活动登陆界面发送强制下线的广播广播接收器AndroidManifest.xml运行结果功能简介 强制下线功能只需要弹出一个对话框&#xff0c;让用户只能点击确定按钮&#xff0c;回到登录界面。 如果在每一个活动中添加一个对话框的话太过繁琐&#xff0c;用广播…

Android入门(12)| 数据持久化

文章目录数据持久化文件存储将数据存储进文件实例从文件中读取数据实例SharedPreferences存储将数据存储进文件实例从文件中读取数据实例实现记住密码的功能SQLite数据库存储创建自己的帮助类调用自己的帮助类补全 onUpgrade() 方法增删查改增&#xff1a;SQLiteDatabase.inser…

Android入门(13)| Android权限 与 内容提供器

文章目录普通权限与危险权限运行时申请权限内容提供器运用安卓封装好的内容提供器自实现的内容提供器概念实现普通权限与危险权限 主要用于不同应用程序之间在保证被访数据的安全性的基础上&#xff0c;实现数据共享的功能。 在 Android 6.0 开始引入了运行时权限的功能&…

Android入门(14)| 通知

文章目录创建通知点击效果其它小功能实例创建通知 创建通知的步骤&#xff1a; 管理通知的 NotificationManager&#xff0c;通常通过当前 Context 的 getSystemService() 获取实例。它接受一个字符串参数用于确定获取系统的什么服务。Android 8.0(O) 版本后需要通知通道&…

Android开发(3) | 权限和内容提供器的应用——调用相机和相册

文章目录拍照并保存到 ImageView 控件布局文件 notice_layout.xml按钮 button_takePhoto 的点击操作隐式 Intent 启动后的回调AndroidManifest.xml从相册选取照片并在 ImageView 控件中显示布局文件 notice_layout.xml按钮 button_takePhoto 的点击操作自定义打开相册的方法 op…

Android开发(4) | 系统权限、MediaPlayer类 和 VideoView类 的应用——播放多媒体文件

文章目录MediaPlayer类播放音频的实例VideoView类播放视频的实例MediaPlayer类 对多种格式的音频文件提供了全面的控制方法&#xff1a; 如何获得MediaPlayer实例&#xff1f; 通过构造函数&#xff1a; MediaPlayer mp new MediaPlayer();调用 MediaPlayer.create() 方法&…

Android入门(15)| 网络

文章目录WebViewHTTP使用HttpURLConnection使用OkHttp封装网络操作封装HttpURLConnection封装OkHttpWebView WebView 可以在 应用程序中&#xff08;而不是浏览器&#xff09; 展示一些网页。 布局文件 web_layout.xml&#xff1a; <LinearLayoutxmlns:android"http…

Android入门(16)| 服务

文章目录概念Android 多线程继承 Thread继承 Runable 接口匿名类异步消息处理AsyncTask使用服务框架启动/停止服务绑定/解绑服务服务的生命周期前台服务IntentService完整版下载示例下载过程的回调接口&#xff1a;DownloadListener继承 AsyncTask 实现下载功能&#xff1a;Dow…

2020德勤面试开始了吗_2020国考面试开始,近期面试公告汇总,附结构化小组面试流程...

2020年国家公务员考试面试环节逐步恢复考试&#xff0c;各个招录部门已经发布面试考察公告&#xff0c;对于进入面试环节的国考考生来说&#xff0c;有必要了解近期国考面试的招录动态&#xff0c;提前做好面试准备。2020国考国家统计局机关面试面试确认&#xff1a;请进入面试…

项目积压需求项目计划_需求变更频繁,项目经理如何做好需求管理?

项目实施过程中&#xff0c;项目经理常常面临一个重大挑战——需求变更。需求变更无处不在&#xff0c;市场条件变化、新业务出现、战略目标调整、客户需求修改、资源限制等&#xff0c;都会造成需求变更。需求变更会影响项目的时间、成本和质量&#xff0c;对整个项目和团队成…

Android | Sensor.TYPE_ORIENTATION被废弃后的解决办法

文章目录概述getOrientation 方法根据 旋转矩阵R 获取 设备旋转弧度getRotationMatrix 方法根据 地磁场、加速度传感器对象 获取 旋转矩阵R代码参考资料概述 Sensor.TYPE_ORIENTATION 常数在 API 8 中已弃用&#xff0c;官方推荐使用 SensorManager.getOrientation() 替代。关…

【JAVA 开发小问题】 | String操作合集

文章目录截取特定两个字符之间的字符串截取特定两个字符之间的字符串 利用正则表达式&#xff0c;图片来源

uniapp 刷新后数据都没有了_环境温度传感器都没有连接,竟然还会有数据?

福田欧曼GTL(福康发动机、康明斯2880系统)匹配ECoffit尿素泵●故障现象&#xff1a;OBD故障灯点亮&#xff0c;不烧尿素&#xff0c;油耗高&#xff0c;动力不足●故障码&#xff1a;●维修分析&#xff1a;①故障指出加热器问题&#xff0c;摸下尿素箱温度&#xff0c;发现烫手…

保姆级教学!Xcode 配置 OpenGL 环境

文章目录GLFW获取 GLFWGLAD获取 GLAD在 Xcode 中配置下载好的 GLFW 和 GLAD配置流程检测是否配置成功无关配置的题外话——Xcode 下安全的删除移动操作GLFW Graphics Library Framework&#xff08;图形库框架&#xff09;&#xff0c;可以让我们通过其封装好的 通用API 来正确…