android开发笔记之 Activity四种加载模式
既然是安卓开发,我们就免不了和Activity打交道,因为它是前台的界面,也是android四大组件之一,那我们就来谈谈Activity的四种加载模式。
为什么要为Activity指定加载模式?
Android对Activity的管理,采用Task(即栈)来管理多个Activity,当我们启动一个应用时,Android就会为之创建了一个Task,然后启动这个应用的入口Activity。
Android的Task是一个有点麻烦的概念,因为Android并没有为Task提供API,因此开发者无法真正访问Task,只能调用Activity的getTaskId()方法来获取它所在的Task的ID。
事实上,我们可以把Task理解成Activity栈,Task以栈的样式来管理Activity,先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。
那么Activity的加载模式,就负责管理实例化,加载Activity的方式,并可以控制Activity与Task之间的加载关系。
先看看哪四种模式:
①standard —>默认(标准)
不管Activity实例是否存在,都会创建一个新的实例装入Task。(每次通过这种模式来启动目标Activity时,android总会为目标Activity创建一个新的实例,并将该Activity添加到目前的Task栈中。这种模式不会启动新的Task,新的Activity将被添加到原有的Task中)例子:10个应用程序都要调用浏览器的应用, 那么你需要创建10个浏览器对象的Activity的对象吗?
②singleTop —>栈顶单例(栈顶不会出现相邻的相同activity实例)
被跳转的Activity位于Task顶部时: 不会创建新的实例,直接复用已有的Activity实例被跳转的Activity不是位于顶部时: 创建一个新的实例,同standard模式相似
③singleTask —>栈内单例(在同一个Task内只有一个实例)
采用这种模式分三种情况: a)如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,并将它加入Task栈顶。 b)如果将要启动的目标Activity已经位于Task栈顶,此时同singleTop模式 c)如果将要启动的目标Activity没有位于Task栈顶,系统将会把位于该Activity上面的所有Activity移除Task栈,从而使得目标Activity转入栈顶。
④singleInstance —->全局单例(会单独拥有一个栈)
采用这种模式启动目标Activity时,可分为如下两种情况: a)如果将要启动的目标Activity不存在,系统会先创建一个全新的Task,在创建目标Activity的实例,并将它加入新的Task的栈顶。 b)如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,无论它位于哪个Task中,系统会把该Activity所在的Task转到前台,从而使用该Activity显示出来。 需要指出:采用单例模式加载Activity总是位于Task栈顶, 采用单例模式加载Activity所在Task只包含该Activity
那如何设置呢??
这些启动模式可以在功能清单文件AndroidManifest.xml中进行设置,中的launchMode属性。
相关的代码中也有一些标志可以使用,比如我们想只启用一个实例,则可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 标志,这个标志表示:如果这个activity已经启动了,就不产生新的activity,而只是把这个activity实例加到栈顶来就可以了。
Intent intent = new Intent(ReorderFour.this, ReorderTwo.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent);
核心的Intent Flag有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
大家看这张图应该能够明白栈的含义(画的有点丑):
我在这里就简单做点示例:
public class AActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); } public void goAActivity(View view) { Intent intent = new Intent(AActivity.this,BActivity.class); }}activity_a.xml<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.briup.lauchmodetest.AActivity"> <Button android:onClick="goAActivity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转到AActivity"/></RelativeLayout>
public class BActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); } public void goBActivity(View view) { Intent intent = new Intent(BActivity.this,AActivity.class); }}activity_b.xml<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.briup.lauchmodetest.AActivity"> <Button android:onClick="goBActivity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转到BActivity"/></RelativeLayout>
①现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,都采用默认的加载模式,栈的情况是怎么样的呢
②现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用栈顶单例加载模式,栈的情况是怎么样的呢
③现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用栈内单例加载模式,栈的情况是怎么样的呢
④现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用全局单例加载模式,栈的情况是怎么样的呢
大家有没有理解呢,去试试吧,有什么不懂可以在下方提问或者和我一起探讨。
更多相关文章
- Android如何加载大图,防止OOM
- Android从SD卡中加载图片或读取信息
- android实现虚拟按键实例
- android 加载进度条动画
- Android ListView异步加载网络图片
- Android 动态切换全屏和非全屏模式
- android加载进度条
- Android binder 实例
- android 加载 网络图片