我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

1.Activity,Window与View的关系

流程解析: Activity调用startActivity后最后会调用attach方法,然后在PolicyManager实现一个Ipolicy接口,接着实现一个Policy对象,接着调用makenewwindow(Context)方法,该方法会返回一个PhoneWindow对象,而PhoneWindow 是Window的子类,在这个PhoneWindow中有一个DecorView的内部类,是所有应用窗口的根View,即View的老大, 直接控制Activity是否显示(引用老司机原话..),好吧,接着里面有一个LinearLayout,里面又有两个FrameLayout他们分别拿来装ActionBar和CustomView,而我们setContentView()加载的布局就放到这个CustomView中!

总结下这三者的关系: 打个牵强的比喻: 我们可以把这三个类分别堪称:画家,画布,画笔画出的东西; 画家通过画笔( LayoutInflater.infalte)画出图案,再绘制在画布(addView)上! 最后显示出来(setContentView)


2.Activity,Task和Back Stack的一些概念

接着我们来了解Android中Activity的管理机制,这就涉及到了两个名词:Task和Back Stack了!

概念解析:

我们的APP一般都是由多个Activity构成的,而在Android中给我们提供了一个Task(任务)的概念, 就是将多个相关的Activity收集起来,然后进行Activity的跳转与返回!当然,这个Task只是一个 frameworker层的概念,而在Android中实现了Task的数据结构就是Back Stack(回退堆栈)! 相信大家对于栈这种数据结构并不陌生,Java中也有个Stack的集合类!栈具有如下特点:

而Android中的Stack Stack也具有上述特点,他是这样来管理Activity的:

我们来看下官方文档给出的一个流程图:

流程解析:

应用程序中存在A1,A2,A3三个activity,当用户在Launcher或Home Screen点击应用程序图标时, 启动主A1,接着A1开启A2,A2开启A3,这时栈中有三个Activity,并且这三个Activity默认在 同一个任务(Task)中,当用户按返回时,弹出A3,栈中只剩A1和A2,再按返回键, 弹出A2,栈中只剩A1,再继续按返回键,弹出A1,任务被移除,即程序退出!

接着在官方文档中又看到了另外两个图,处于好奇,我又看了下解释,然后跟群里的人讨论了下:

然后还有这段解释:

然后总结下了结论:


3.Task的管理

1)文档翻译:

好的,继续走文档,从文档中的ManagingTasks开始,大概的翻译如下:


1)文档翻译

继续走文档,从文档中的ManagingTasks开始,翻译如下:

< activity >中我们可以使用的属性如下:

你能用的主要的Intent标志有:

好的,接下来逐个介绍这些怎么用:


2)taskAffinity和allowTaskReparenting

默认情况下,一个应用程序中的所有activity都有一个Affinity,这让它们属于同一个Task。 你可以理解为是否处于同一个Task的标志,然而,每个Activity可以通过 < activity>中的taskAffinity属性设置单独的Affinity。 不同应用程序中的Activity可以共享同一个Affinity,同一个应用程序中的不同Activity 也可以设置成不同的Affinity。 Affinity属性在2种情况下起作用:


3)launchMode:

四个可选值,启动模式我们研究的核心,下面再详细讲! 他们分别是:standard(默认),singleTopsingleTasksingleInstance


4)清空栈


4.Activity的四种加载模式详解:

接下来我们来详细地讲解下四种加载模式: 他们分别是:standard(默认),singleTopsingleTasksingleInstance 在泡在网上的日子看到一篇图文并茂的讲解启动模式的,很赞,可能更容易理解吧,这里借鉴下:

原文链接:Activity启动模式图文详解:standard, singleTop, singleTask 以及 singleInstance

英文原文:Understand Android Activity's launchMode: standard, singleTop, singleTask and singleInstance 另外还有一篇详细讲解加载模式的:Android中Activity四种启动模式和taskAffinity属性详解

先来看看总结图:

模式详解:


standard模式:

标准启动模式,也是activity的默认启动模式。在这种模式下启动的activity可以被多次实例化,即在同一个任务中可以存在多个activity的实例,每个实例都会处理一个Intent对象。如果Activity A的启动模式为standard,并且A已经启动,在A中再次启动Activity A,即调用startActivity(new Intent(this,A.class)),会在A的上面再次启动一个A的实例,即当前的桟中的状态为A-->A。


singleTop模式:

如果一个以singleTop模式启动的Activity的实例已经存在于任务栈的栈顶, 那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例, 并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。 举例来说,如果A的启动模式为singleTop,并且A的一个实例已经存在于栈顶中, 那么再调用startActivity(new Intent(this,A.class))启动A时, 不会再次创建A的实例,而是重用原来的实例,并且调用原来实例的onNewIntent()方法。 这时任务栈中还是这有一个A的实例。如果以singleTop模式启动的activity的一个实例 已经存在与任务栈中,但是不在栈顶,那么它的行为和standard模式相同,也会创建多个实例。


singleTask模式:

只允许在系统中有一个Activity实例。如果系统中已经有了一个实例, 持有这个实例的任务将移动到顶部,同时intent将被通过onNewIntent()发送。 如果没有,则会创建一个新的Activity并置放在合适的任务中。

官方文档中提到的一个问题:



singleInstance模式

保证系统无论从哪个Task启动Activity都只会创建一个Activity实例,并将它加入新的Task栈顶 也就是说被该实例启动的其他activity会自动运行于另一个Task中。 当再次启动该activity的实例时,会重用已存在的任务和实例。并且会调用这个实例 的onNewIntent()方法,将Intent实例传递到该实例中。和singleTask相同, 同一时刻在系统中只会存在一个这样的Activity实例。


5.Activity拾遗

对于Activity可能有些东西还没讲到,这里预留一个位置,漏掉的都会在这里补上! 首先是群友珠海-坤的建议,把开源中国的Activity管理类也贴上,嗯,这就贴上,大家可以直接用到 项目中~

1)开源中国客户端Activity管理类:

package net.oschina.app;

import java.util.Stack;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;


public class AppManager {
    
    private static Stack<Activity> activityStack;
    private static AppManager instance;
    
    private AppManager(){}
    /**
     * 单一实例
     */
    public static AppManager getAppManager(){
        if(instance==null){
            instance=new AppManager();
        }
        return instance;
    }
    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity){
        if(activityStack==null){
            activityStack=new Stack<Activity>();
        }
        activityStack.add(activity);
    }
    /**
     * 获取当前Activity(堆栈中最后一个压入的)
     */
    public Activity currentActivity(){
        Activity activity=activityStack.lastElement();
        return activity;
    }
    /**
     * 结束当前Activity(堆栈中最后一个压入的)
     */
    public void finishActivity(){
        Activity activity=activityStack.lastElement();
        finishActivity(activity);
    }
    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity){
        if(activity!=null){
            activityStack.remove(activity);
            activity.finish();
            activity=null;
        }
    }
    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls){
        for (Activity activity : activityStack) {
            if(activity.getClass().equals(cls) ){
                finishActivity(activity);
            }
        }
    }
    /**
     * 结束所有Activity
     */
    public void finishAllActivity(){
        for (int i = 0, size = activityStack.size(); i < size; i++){
            if (null != activityStack.get(i)){
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }
    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {
        try {
            finishAllActivity();
            ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.restartPackage(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {    }
    }
}

本节小结:

好的,本节就到这里,东西都比较苦涩难懂,暂时知道下即可,总结下Task进行整体调度的 相关操作吧:

好的本节就到这里,关于Task与Activity加载模式的东西还是比较复杂的,下面给大家贴下编写该文的 时候的一些参考文献,可以自己看看~


参考文献:

  • 1.Tasks and Back Stack
  • 2.理解android中Activity和Task的关系
  • 3.Activity启动模式图文详解:standard, singleTop, singleTask 以及 singleInstance
  • 4.Understand Android Activity's launchMode: standard, singleTop, singleTask and singleInstance
  • 5.Android中Activity四种启动模式和taskAffinity属性详解
  • 6.Android的Activity和Tasks详解
  • 7.Activity的四种启动模式和onNewIntent()
  • 8.译:Android任务和返回栈完全解析,细数那些你所不知道的细节
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为1000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版百度优化、名注册、主机空间、手机网站建设公众号开发小程序制作、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线: 13820372851,我们会详细为你一一解答你心中的疑难。项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13820372851

上班时间

周一到周五

公司电话

022-26262675

二维码
线
在线留言