Android 启动模式详细介绍
android 启动模式:
启动模式:launchmode在多个activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的activity实例,是否重用已存在的activity实例,是否和其他activity实例公用一个task里。
这里简单介绍一下任务栈task的概念,task是一个具有栈结构的对象,一个task可以管理多个activity,启动一个应用,也就创建一个与之对应的task。任务栈里面的activity是按照先进后出的形式保存的,比如:你打开一个页面,在页面中打开另一个页面,另一个页面退出后,返回的是第一个打开的页面,这就是任务栈的简单原来。
但是在实际程序中多次页面跳转后,不想再回到上次打开的页面,这时候页面显示的启动模式就很有必要了。
activity一共有以下四种launchmode启动模式:
1.standard
2.singletop
3.singletask
4.singleinstance
我们可以在androidmanifest.xml配置的android:launchmode属性为以上四种之一即可。如图所示:
下面分别介绍这四种启动模式。
这里要先理解栈顶的概念:只要是页面刚打开,不管他是什么模式的,它都是栈顶页面。
栈底的概念虽然书上没说,但是要理解透彻栈的模式,还是要知道有这个说法,比如:首先打开的页面是位于最底下的,然后后面打开的页面一次往上堆。只有最底下的页面关闭,程序才算完成关闭。
一.四种启动模式的概念和理解
(一)standard标准模式
是默认的启动模式,不用为配置android:launchmode属性即可,当然也可以指定值为standard。
每次启动standard模式的activity时,都创建activity实例,并放入任务栈;
简单的理解:如果几个页面都是standard模式启动的,那么页面无论是跳转到别的页面还是自己跳转到自己页面,跳转多少次后,就要点击多少次退出键最后才能关闭所有的。
(二)singletop栈顶单例模式
指定属性android:launchmode=”singletop”,系统就会按照singletop启动模式处理跳转行为。这个在实际中并不常用。
如果某个activity自己激活自己,即任务栈栈顶就是该activity,则不需要创建,只需复用自己已有的activity示例即可。但是如果自己不是栈顶的话,还是会创建自己的示例的。
简单的理解:如果页面的启动类型是singletop类型的,它点击跳转到自己的页面,只需要点击一次退出就退出程序了。因为当它处于栈顶时,它无论点击多少次跳转到自己,都自有一个activity实例,点击一次退出就会退出程序。和standard模式对比的话,standard模式下点击多少次自己就要退出多少次后才能退出程序。
(三)singletask内单例模式
指定属性android:launchmode=”singleletask”,这是应用中比较常用到的模式。也是我们要重点理解的模式。
如果要启动的那个singletask模式的activity在任务栈中存在该实例,则不需要创建,只需要把此activity放入栈顶,并把该activity以上的activity实例都移出栈里面;如果不存在该模式的activity就创建给模式的activity放在该栈顶。也就是说:一个栈里面只能有一个singletask模式的activity。
上面几句重点理解一下:
如果singletask模式的activity已经存在栈顶,那么再次跳转到自己页面,它是不会创建自己的activity实例对象的,这个和singletop是一样的。
但是如果singletask模式的activity已经不在栈顶,那么再次跳转到自己页面,它是不会创建自己的activity实例对象的,也会直接跳转到自己的实例activity,并且把压在该模式之上的所有activity实例都移除栈,但是该模式底下的activity实例它是没有办法移除的。
如果singletask模式的activity都还没有创建,那么它会新建它的activity实例对象,并把自己放在栈顶,这个和所有的activity实例对象都是一样的。
关于singletask的应用是特别值得注意的,比如主页面的设计一般使用singletask模式来设计,因为用户点击多次页面的相互跳转后,在点击回到主页,再次点击退出,这时他的实际需求就是要退出程序,而不是一次一次关闭刚才跳转过的页面,最后才退出。这就需要用到singletask模式。
(四)singleinstance全局单例模式
指定属性android:launchmode=”singleleinstance”。
该模式下,无论是从哪一个任务栈task中启动activity,只会创建一个目标的activity实例,并且使用一个全新的task栈来加载该activity实例。
可以看出singleinstance模式比singletask模式更加霸道,打开一个singletask模式的activity,它如果已经存在它会把在它之上的该task里面的activity实例移除;而打开singleinstance模式的activity,不管它存不存在,他都会新建一个task,把自己放在里面,也就就是说刚打开的singleinstance的activity在自己新建的栈里面只有自己一个实例对象。
但是它和新建自己的task时,是不会移除自己之前activity实例上面或下面的activity实例,之前的task里面的activity依然存在。
如果应用1的任务栈中创建了mainactivity实例,如果应用2也要激活mainactivity,则不需要创建,两应用共享该activity实例;
singleinstance模式一般是用于资源的共享。比如有软件a打开的qq和用软件b打开的qq是打开的是同一个qq软件。并且退出qq程序后,原来打开的程序并没有被关闭。
这就是singleinstance模式作用。
二.编程程序加强理解
本程序只是简单页面的跳转,用来验证上面的模式的正确性和加强对模式过程的理解。
本程序设计一份之后简单复制就可以完成。
设计后的结果:四个activity和四个布局文件,如图所示:
(一)布局文件activity.xml的设计
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="standard模式" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="tomainactivity" android:text="去主页面" android:textallcaps="false" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="tosingletopactivity" android:text="singletop模式页面" android:textallcaps="false"/> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="tosingletaskactivity" android:text="tosingletask模式页面" android:textallcaps="false"/> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="tosingleinstanceactivity" android:text="tosingleinstance模式页面" android:textallcaps="false" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="tofinish" android:text="关闭页面" android:textallcaps="false"/> </linearlayout>
其中上面的textview控件的内容要改为该页面设计的模式名。
(二)mainactivity.java文件代码的设计
package com.example.android; import android.content.intent; import android.os.bundle; import android.os.persistablebundle; import android.view.view; public class mainactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); } //跳转到mainactivity页面 public void tomainactivity(view v) { startactivity(new intent(this, mainactivity.class)); } //跳转到singletopactivity页面 public void tosingletopactivity(view v) { startactivity(new intent(this, singletopactivity.class)); } //跳转到singletaskactivity页面 public void tosingletaskactivity(view v) { startactivity(new intent(this, singletaskactivity.class)); } //跳转到singleinstanceactivity页面 public void tosingleinstanceactivity(view v) { startactivity(new intent(this, singleinstanceactivity.class)); } //关闭页面页面 public void tofinish(view v) { finish(); } }
四个activity文件的文件名换一下就可以了。
(三)程序运行前要设置androidmanifest.xml,如下:
<activity android:name=".mainactivity"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity android:name=".singletopactivity" android:launchmode="singletop" /> <activity android:name=".singletaskactivity" android:launchmode="singletask"/> <activity android:name=".singleinstanceactivity" android:launchmode="singleinstance" />
前面一个activity是系统默认添加的,后面三个activity是要自己手动添加的
(四)程序运行后的结果:
程序启动后点击各个模式试一下,最后每次点击关闭页面,看看退出的顺序是否是你所想的?要弄清过程就可以。
一些简单的逻辑顺序,比如:
1.比如多次点击主页面按钮,要多次点击关闭页面按钮才能退出程序。
2.点击tosingletask模式的页面后,无论你点击多少次,去主页面的按钮或tosingtop按钮,再点击一次tosingletask按钮后,点击关闭页面按钮后,退回的是standard模式页面,再次点击关闭页面按钮后将退出程序。
3.后面也可以改变程序的最开始启动的页面的启动模式,再看看运行的效果。
(五)对比一下这四种模式
android的四种启动模式是standard、singletop、singletask、singleinstance,这是我们要必须要记住的几个关键字。这几种模式有什么区别? 我简单描述一下:
1.从四种模式的命名都可以看出,后面三种模式都带有single关键字,是单例的意思,所以后面三个模式都是单例的模式。而前面一个模式是加载模式,即点击多少次该页面,该页面就会加载多少个activity对象。
2.后面三种单例模式再对比一下,可以发现它们的单例强度一个比一个强:
(1)singletop单例模式,只能保证它在栈顶的情况下,它才是单例模式;比如,当前页面是singletop模式的页面,如果点击跳转到自身页面,在栈里面是不会创建再它的activity对象的;如果singletop模式的页面还没有创建或给模式的页面不在栈顶,这种情况下跳转到该模式的那个页面,会重新创建它的activity对象。
对比standard模式和singletop模式发现,在同一个栈里面,可以有多个standard模式的同一个页面的对象,也可以有多个singletop模式的同一个页面的对象,但是singletop模式的同一个页面不可以连续两次存在,这里注意是连续的两次。而standard模式的同一个页面可以连续多次的出现,这是它们的区别。
(2)singletask单例模式,能保证它在整个栈里面只有它一个activity对象,如果同一个singletask模式的页面之前打开过,然后点击其他页面之后,再次点击上面的singletask模式的那个页面,那么第一次打开这个页面的后面的所有activity对象都会被清除掉,但是该模式页面打开之前打开的页面的activity对象没有被清除。
对比singletop和singletask这两种单例模式,在整个栈的的数量是其中的一个区别,singletask模式的同一个页面在一个task里面只能有一个activity对象。
(3)singleinstance单例模式,上面的singletask模式已经很强了,难道还有比他更强的吗。答案肯定是有的。singleinstance单例模式能保证在整个task中只能有它自己一个activity对象,这里要注意是整个task中,无论是栈顶栈底都是它自己。实现的方法是,它会新建一个自己的task栈来保存自己的activity示例,当再次点击它时它也是不会创建自己的示例,不管它是不是在栈顶,它在整个程序中只会保存一个实例对象。因为它是自己单独一个task栈保存的,所以它是不会清除它的activity实例对象的;比如;在singleinstance模式的页面上打开其他模式的页面,它的activity对象是保存在一个原来的task栈里面的,即打开singleinstance页面之前的task栈里面;如果singleinstance模式的页面的最开始打开的,那么其他的模式的activity对象也是放在一个新建的task栈里面。
对比singletask和singleinstance,这两种单例模式,singletask模式的activity对象会移除在它的activity对象之上的activity对象,而singleinstance模式,会在另一个task栈里面保存自己的对象。
这四种模式中,只用singleinstance模式的页面会创建新的task栈(同一个页面只创建一次),其他的模式都是在原来的栈里面创建activity对象
三.android启动模式相关的知识
(一)退出单个activity方法:1.调用finish2.杀死该进程:killprocess(process.mid)3.终止正在运行的虚拟机:system.exit()(二)退出整个应用:1.制造抛异常导致整个程序退出2.将所有的activity放入到一个list中,然后在需要退出的时候,将所有的activity,finish掉3.通过广播来完成退出功能
通过广播来完成退出功能,具体实现过程是这样的:在每个activity创建时(oncreate时)给activity注册一个广播接收器,当退出时发送该广播即可。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!