当前位置:首页 » 安卓系统 » android单activity

android单activity

发布时间: 2023-03-17 11:31:45

Ⅰ Android中的Activity详解--启动模式与任务栈

目录

activity的简单介绍就不写了,作为最常用的四大组件之一,肯定都很熟悉其基本用法了。

首先,是都很熟悉的一张图,即官方介绍的Activity生命周期图.

情景:打开某个应用的的FirstActivity调用方法如下:
由于之前已经很熟悉了,这里就简单贴一些图。

按下返回键:

重新打开并按下home键:

再重新打开:

在其中打开一个DialogActivity(SecondActivity)

按下返回:

修改SecondAcitvity为普通Activity,依旧是上述操作:

这里强调一下 onSaveInstanceState(Bundle outState) 方法的调用时机:
当Activity有可能被系统杀掉时调用,注意,一定是被系统杀掉,自己调用finish是不行的。
测试如下:FirstActivity启动SecondActivity:

一个App会包含很多个Activity,多个Activity之间通过intent进行跳转,那么原始的Activity就是使用栈这个数据结构来保存的。
Task
A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened.
即若干个Activity的集合的栈表示一个Task。
当App启动时如果不存在当前App的任务栈就会自动创建一个,默认情况下一个App中的所有Activity都是放在一个Task中的,但是如果指定了特殊的启动模式,那么就会出现同一个App的Activity出现在不同的任务栈中的情况,即会有任务栈中包含来自于不同App的Activity。

标准模式,在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例,覆盖在原有的Activity上,原有的Activity入栈。
测试如下:在FirstActivity中启动FirstActivity:

当只有一个FirstActivity时堆栈情况:

此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。
测试,设置FirstActivity为此启动模式,多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况:
(其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity)

大意就是:
对于使用singleTop启动或Intent.FLAG_ACTIVITY_SINGLE_TOP启动的Activity,当该Activity被重复启动(注意一定是re-launched,第一次启动时不会调用)时就会调用此方法。
且调用此方法之前会先暂停Activity也就是先调用onPause方法。
而且,即使是在新的调用产生后此方法被调用,但是通过getIntent方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。
方法参数就是新传递的Intent.

1.如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。
测试:SecondActivity启动模式设为singleTask,启动三个Activity:

这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。
测试:SecondActivity启动模式设为singleInstance

结果:

显然,启动了两次ThirdActivity任务栈中就有两个实例,而SecondActivity在另外一个任务栈中,且只有一个。

在使用Intent启动一个Activity时可以设置启动该Activity的启动模式:
这个属性有很多,大致列出几个:

每个启动的Activity都在一个新的任务栈中

singleTop

singleTask

用此种方式启动的Activity,在它启动了其他Activity后,会自动finish.

官方文档介绍如下:

这样看来的话,通俗易懂的讲,就是给每一个任务栈起个名,给每个Activity也起个名,在Activity以singleTask模式启动时,就检查有没有跟此Activity的名相同的任务栈,有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。
测试:在App1中设置SecondActivity的taskAffinity为“gsq.test”,App2中的ActivityX的taskAffinity也设为“gsq.test”

任务栈信息如下:

结果很显然了。
测试:在上述基础上,在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下:

这样就没问题了,ActivityY在一个新的任务栈中,名称为包名。
这时从ActivityY跳转到SecondActivity,那应该是gsq.test任务栈只有SecondActivity,ActivityX已经没有了。因为其启动模式是singleTask,在启动它时发现已经有一个实例存在,就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。

还有一点需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器,故在FirstActivity跳转到SecondActivity时,按下home键,再点开App1,回到的是FirstActivity。

大致就先写这么多吧,好像有点长,废话有点多,估计也有错别字,不要太在意~~~

Ⅱ Android Activity启动模式与状态保存及恢复详解

       Activity是 Android组件 中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器)之一 。
       Activity是一个应用程序 组件 ,提供一个 屏幕 ,用户可以用来交互为了完成某项任务。
       Activity中所有操作都与用户密切相关,是一个负责与 用户交互 的组件,可以通过setContentView(View)来 显示指定控件
       在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。
       关于Activity启动流程请参考之前的文章 Android activity启动流程分析

       activity有四种启动模式,分别为standard,singleTop,singleTask,singleInstance。如果要使用这四种启动模式,必须在manifest文件中<activity>标签中的launchMode属性中配置。

       标准的默认启动模式,这种模式下activity可以被多次实例化,即在一个task中可以存在多个activity,每一个activity会处理一个intent对象,(在A中再次启动A,会存在后面的A在前面的A上面,当前task会存在两个activity的实例对象)

       如果一个singleTop模式启动的activity实例已经存在于栈顶,那么再次启动这个activity的时候,不会重新创建实例,而是重用位于栈顶的那个实例,并且会调用实例的onNewIntent()方法将Intent对象传递到这个实例中,如果实例不位于栈顶,会创建新的实例。

       启动模式设置为singleTask,framework在启动该activity时只会把它标示为可在一个新任务中启动,至于是否在一个新任务中启动,还要受其他条件的限制,即taskAffinity属性。
        taskAffinity :默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名。我们可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的应用中的activity的taskAffinity设置成相同的值,当两个不同应用中的activity设置成相同的taskAffinity时,则两个activity会属于同一个TaskRecord。
       在启动一个singleTask的Activity实例时,如果系统中已经存在这样一个实例,就会将这个实例调度到任务栈的栈顶,并清除它当前所在任务中位于它上面的所有的activity;如果这个已存在的任务中不存在一个要启动的Activity的实例,则在这个任务的顶端启动一个实例;若这个任务不存在,则会启动一个新的任务,在这个新的任务中启动这个singleTask模式的Activity的一个实例。

       以singleInstance模式启动的Activity具有全局唯一性,即整个系统中只会存在一个这样的实例,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
       以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中(官方文档上的描述为,singleInstance模式的Activity不允许其他Activity和它共存在一个任务中)。
       被singleInstance模式的Activity开启的其他activity,能够开启一个新任务,但不一定开启新的任务,也可能在已有的一个任务中开启,受条件的限制,这个条件是:当前系统中是不是已经有了一个activity B的taskAffinity属性指定的任务。

       涉及到Activity启动,就不得不说一下Activity的管理,Activity是以什么方式及被什么类来进行管理的,涉及的类主要如下:

       历史栈中的一个条目,代表一个activity。ActivityRecord中的成员变量task表示其所在的TaskRecord,ActivityRecord与TaskRecord建立了联系。

       内部维护一个 ArrayList<ActivityRecord> 用来保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord与ActivityStack建立了联系。

       内部维护了一个 ArrayList<TaskRecord> ,用来管理TaskRecord,ActivityStack中持有ActivityStackSupervisor对象,由ActivityStackSupervisor创建。

       负责所有ActivityStack的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。

       ActivityThread 运行在UI线程(主线程),App的真正入口。

       用来实现AMS和ActivityThread之间的交互。

       负责调用Activity和Application生命周期。

       当一个Activity未被主动关闭,即“被动关闭”时,可能需要系统给用户提供保持一些状态的入口。

       前面说的入口就是:Activity提供了onSaveInstanceState()方法,该方法是Activity在关闭前保存状态的核心方法。

       前面提到“被动关闭”,如果是主动关闭那么就不会调用,比如:按back键、调用finish()等,那么"被动关闭"的场景有哪些呢?下面给列举一下:

       肯定在调用onStop()前被调用,但不保证在onPause()前 / 后,一般是在onPause()后调用。

       当需要保持状态时,在onSaveInstanceState()内执行以下逻辑:

       当需要恢复时,在onCreate()内部执行以下逻辑:

       布局每个View默认实现:onSaveInstanceState(),即UI的任何改变都会自动的存储和在activity重新创建的时候自动的恢复(只有在为该UI提供了唯一ID后才起作用);
       若需复写该方法从而存储额外的状态信息时,应先调用父类的onSaveInstanceState()(因为默认的onSaveInstanceState()帮助UI存储它的状态);
       只使用该方法记录Activity的瞬间状态(UI的状态),而不是去存储持久化数据,因为onSaveInstanceState()调用时机不确定性;可使用 onPause()[一定会执行]存储持久化数据;

       Activity提供了onRestoreInstanceState()方法,该方法是Activity在重新创建后恢复之前保存状态的核心方法。

       若被动关闭了Activity,即调用了onSaveInstanceState(),那么下次启动时会调用onRestoreInstanceState()。

       onCreate()--->onStart()--->onRestoreInstanceState()--->onResume()

        注意: onSaveInstanceState()、onRestoreInstanceState()不一定 成对被调用
       如:当正在显示Activity A时,用户按下HOME键回到主界面,然后用户紧接着又返回到Activity A,此时Activity A一般不会因为内存的原因被系统销毁,故Activity A的onRestoreInstanceState()不会被执行;
       针对以上情况,onSaveInstanceState保持的参数可以选择在onCreate()内部进行解析使用,因为onSaveInstanceState的bundle参数会传递到onCreate方法中,可选择在onCreate()中做数据还原。
        至此:Activity的启动模式及Activity的状态保持及恢复介绍完毕。

Ⅲ Android基础之Activity 运行模式与回退栈

LaunchMode 定义的是activity实例与task之间的关系,可以通过下面的两种方式来定义:

在Activity A中启动B,可以利用Activity B在清单中的launchmode定义,也可以在A中调用startActivity()的时候通过intent的flag传入,当两种方式都有定义,intent的flag参数会覆盖掉B原有的定义。

利用Activity 元素的launchMode属性
launchMode属性指定Activity如何被运行到一个task中。launchMode的值有四种:

默认, 每次启动Activity系统都会产生一个新的实例,并且把intent发送给新产生的实例,这个Activity可以被实例化多次,每个实例可以属于不同的task,每个task也可以保有多个此Activity的实例。

如果当前task 的回退栈栈顶已经存在一个此Activity的实例,系统通过调用这个实例的onNewIntent()方法把intent发送给这个Activity实例,而不是创建一个新的此Activity的实例。这个Activity也可以被实例化多次,每个实例可以属于不同的task,每个task可一个保有多个实例(仅限于此Activity已存在的实例不在栈顶)
注意:
应用场合如下:不想出现2个同样的activity在顶部。比如用户正在一个activity阅读信息,这时来了notification,用户点击后应该更新这些信息,而不是新建一个activity,这样在点击back时,就不会出现回到旧信息activity的情况了。这种情况正是下面这段英语提到的。
Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent()
.
例如,当前回退栈中有A,B,C,D四个Activity,全部是Standard,在D中调用startActivity()去启动B,intent的flag设置成FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK,系统发现栈中有B,会先销毁这个B,再原位置重建B,清空CD,而不是把这个新建的B的实例压入栈顶,这里之所以会销毁B再新建B,因为B的launchmode是Standard,无论什么情况下启动,都需要new一个B的实例,但如果此时B是SingleTop的,系统会把这个intent通过onNewIntent传给已经在栈中的B的实例,不需要销毁再创建,仍需要清空CD。

系统会创建一个新的task并且把这个实例放在栈底( 此处有疑问,测试发现并不一定是栈底 ),但是,如果在一个单独的task中已经存在一个此Activity的实例,系统会把intent通过onNewIntent()发送给这个实例( 测试发现如果在回退栈中,该Activity的上面还有其他Activity,启动此Activity会清空栈中此Activity上面的其他Activity ),而不是创建一个新的实例。同一时间在只有一个此Activity的实例存在于系统中。

与SingleTask一样,不同的是SingleTask的Activity所在的task中可以有其他的Activity,而SingleInstance的Activity独占一个task,并且在整个系统中只有唯一的一个实例。由这个Activity启动的其他Activity都会在新的task中打开。

另一个例子,系统自带浏览器APP把浏览器Activity声明为SingleTask,通过在Activity标签里的launchMode进行指定,这意味着如果你发送一个intent启动浏览器,不管是为浏览器新开启一个task还是从浏览器已经在后台保有的task中启动浏览器,浏览器Activity与你的APP不在同一个task。

不管一个Activity是不是在一个新的task中启动,点击返回都会返回前一个Activity。不过,如果启动一个LaunchMode为singleTask的Activity,如果该Activity此时在一个处于后台的task中,整个task会变成前台task,此时,回退栈会包含由这个后台task携带过来所有Activity,放在回退栈的栈顶,下图说明这种情况。

在一个新的task里启动Activity. 如果已经有Activity实例运行在某一task中,启动这个Activity会把该实例所在的task带到前台,由该实例的onNewIntent()来接收新的intent。

如果被启动的Activity就是当前的Activity,这个已经存在的实例通过onNewIntent()接收intent,不会产生新的实例。

被启动的Activity如果已经存运行于当前task,回退栈中所有在此Activity上面的Activity都将被销毁,此Activity通过onNewIntent()接收新的intent。
例如,一个task中有A,B,C,D,四个Activity,如果D 调用startActivtiy()启动Activity B,C和D会被销毁,B接收这个intent,回退栈中有A,B。
上例中的Activity B的实例,或者通过onNewIntent()接收新的intent,或者销毁新建来处理新的intent。如果B的launchmode是standard,并且没有设置FLAG_ACTIVITY_SINGLE_TOP,那么B会被销毁重启,如果是其他launchmode或者设置了FLAG_ACTIVITY_SINGLE_TOP,则会通过onNewIntent()接收。
FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK结合使用会有个不错的效果。
如果启动的Activity位于task的底部,它会把所在task带到前台,并且清理状态至root状态,当从通知栏里打开一个Activity的会非常有用。

Affinity指的是一个Activity偏向于从属于哪个task,默认情况下,一个APP内的所有Activity互相之间共享一个affinity的值,所以,所有同一APP下的所有Activity都偏向于从属于同一个task。但是,这个值是可以更改的,不同APP内的Activity可以共享一个affinity,同一个APP内的Activity也可以被分配不同的affinity的值。
affinity的值可以通过修改Activity标签的taskAffinity属性来修改。
这个属性接收一个String的值,必须在manifest标签范围内是唯一的值,因为系统是通过名称来标识APP的affinity的值的。
Affinity作用于以下两种情况:

通过startActivity()启动一个新的Activity时,默认情况下,新的Activity会被压入与启动者相同的回退栈中。但是,如果在启动Activity的时候,使用了FLAG_ACTIVITY_NEW_TASK 这个标志,系统会为新的Activity寻找一个新的task。通常情况下,是一个新的task。但是也并不是必须的。如果系统中有一个task的affinity值与新的Activity的值相同,新的Activity会被分配到这个task中。如果没有这样的task,就启动一个新的task。如果这个标志产生了一个新的task,当用户点击home键离开的时候,必须要有某种方式能够使用户返回到这个task来。有些实体(例如通知管理器)总是从一个外部task中启动Activity,所以在通过startActivity()启动新的Activity时总是需要传递FLAG_ACTIVITY_NEW_TASK 这个标志。如果你有一个Activity可以被外部实体可能这个标志启动,注意用户可以有一种独立的方式回到启动它的task,例如点击启动图标。

这种情况下,一个Activity可以动启动它的那个task移动到它的affinity值对应的task中,当那个task回到前台。例如,假设,一个报告指定城市天气情况的Activity作为一个旅行APP的一部分,它跟其他处在同一APP的Activity一样有一个相同的affinity值,并且允许通过这个属性来调整目标task。当你的一个Activity启动了这个天气预报Activity,它默认跟你的Activity在一个task里,但是,当旅行APP进入到前台,这个天气预报Activity又会被重新分配给旅行APP并且在旅行APP内展示。
提示:
如果一个APK文件从用户的角度看是多款APP,可能需要这个属性来设置不同的affinity来关联不同的APP。

如果用户离开一个task太长时间,系统会清除task中的所有Activity仅仅保留这下根Activity。当用户返回到这个task的时候,只有这个根Activity会被恢复。系统通过这种方式来处理,是因为经过相当长的一段时间之后,用户已经抛弃他们曾经正在做的事情,计划再回来的时候做点新的事情。

你可以通过如下属性来更改这种行为:

参考文献:
Tasks and Back Stack
<activity>
Android 阅读Tasks and Back Stack文章后的重点摘抄

Ⅳ Android之Activity全面解析,有些知识点容易忘记

Activity作为安卓四大组件之一,是最重要也是用得最多的组件,涉及的知识点非常多,有些知识点平时开发很少用到,但在某些场景下需要特别注意,本文详细整理了Activity涉及的知识点,供开发参考。

针对Activity可以提出很多问题,如:
Activity 的生命周期?
Activity 之间的通信方式?
Activity 各种情况下的生命周期?
横竖屏切换时 Activity 的生命周期?
前台切换到后台,然后再回到前台时 Activity 的生命周期?
弹出 Dialog 的时候按 Home 键时 Activity 的生命周期?
两个Activity之间跳转时的生命周期?
下拉状态栏时 Activity 的生命周期?
Activity 与 Fragment 之间生命周期比较?
Activity 的四种 LaunchMode(启动模式)的区别?
Activity 状态保存与恢复?
Activity的转场动画有哪些实现方式?
Activity的生命周期中怎么获取控件宽高?
onNewIntent的执行时机?
如何连续退出多个Activity?

如何把Acitivty设置成Dialog样式 ,android:theme="@android:style/Theme.Dialog"

关于横竖屏切换的生命周期,对应不同的手机,由于厂商定制的原因,会有不同的效果,如设置了configChanges="orientation”在有些手机会执行各个生命周期,但有些手机却不会执行。
网上常见的结论如下:

但实际的测试如下:

可以看出,不同厂商的手机切屏生命周期会有差异。
从API 13以上,当设备在横竖切屏时,“屏幕尺寸”也会发生变化,因此为了杜绝切屏导致页面销毁重建,需要加上screenSize,使用设置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .

Activity的四种状态如下:

在activity处于paused或者stoped状态下,如果系统内存紧张,可能会被销毁,当重回该activity时会重建,正常返回和被回收后返回的生命周期如下:

如果是回收后返回,onCreate的参数savedInstanceState不为空。

有哪些场景会触发onNewIntent回调呢?跟启动模式有关,首先该Activity实例已经存在,再次启动才可能触发。一种情况是启动模式是singleTask或者singleInstance,无论该activity在栈中哪个位置,都会触发onNewIntent回调,并且把上面其他acitivity移除,另一种情况是启动模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP启动,并且该activity实例在栈顶,会触发onNewIntent,如果不在栈顶是重新创建的,不会触发。

在实际业务开发中,往往碰到需要连续退出多个activity实例,下面整理了几种常见方法:

● 发送特定广播
1、在需要处理连续退出的activity注册该特定广播;
2、发起退出的activity发送该特定广播;
3、接收到该广播的activity 调用finish结束页面。
● 递归退出
1、用startActivityForResult启动新的activity;
2、前一个页面finish时,触发onActvityResult回调,再根据requestCode和resultCode处理是否finish,达到递归退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通过intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)启动新activity,如果栈中已经有该实例,则会把该activity之上的所有activity关闭,达到singleTop启动模式的效果。
● 自定义activity栈
1、自定义activity列表,新打开activity则加入栈中,关闭则移除栈;
2、需要退出多个activity时,则循环从栈中移除activity实例,并调用finish。

在讨论Activity启动模式经常提到任务栈,那到底什么是任务栈?
任务是一个Activity的集合,它使用栈的方式来管理其中的Activity,这个栈又被称为返回栈(back stack),栈中Activity的顺序就是按照它们被打开的顺序依次存放的。返回栈是一个典型的后进先出(last in, first out)的数据结构。下图通过时间线的方式非常清晰地向我们展示了多个Activity在返回栈当中的状态变化:

taskAffinity 任务相关性,可以用于指定一个Activity更加愿意依附于哪一个任务,在默认情况下,同一个应用程序中的所有Activity都具有相同的affinity, 名字为应用的包名。当然了,我们可以为每个 Activity 都单独指定 taskAffinity 属性(不与包名相同)。taskAffinity 属性主要和 singleTask 启动模式和 allowTaskReparenting 属性配对使用,在其他情况下没有意义。
taskAffinity 有下面两种应用场景:

分为显示启动和隐式启动。
(1)显示启动
直接指定待调整的Activity类名。

(2)隐式启动
Intent 能够匹配目标组件的 IntentFilter 中所设置的过滤信息,如果不匹配将无法启动目标 Activity。IntentFilter 的过滤信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一个 Activity 中可以有多个 intent-filter
● 一个 intent-filter 同时可以有多个 action、category、data
● 一个 Intent 只要能匹配任何一组 intent-filter 即可启动对应 Activity
● 新建的 Activity 必须加上以下这句,代表能够接收隐式调用
<category android:name="android.intent.category.DEFAULT" />

只要匹配一个action即可跳转,注意的是action要区分大小写。

规则:如果intent中有category,则所有的都能匹配到intent-filter中的category,intent中的category数量可用少于intent-filter中的。另外,单独设置category是无法匹配activity的,因为category属性是一个执行Action的附加信息。

intent不添加category会匹配默认的,即 “android:intent.category.DEFAULT”
如果上面例子,如果去掉intent.setAction("action_name"),则会抛出异常:

规则:类似action,但data有复杂的结构,只要匹配一个data并且与data中所有属性都一致就能匹配到Activity,只要有1个属性不匹配,都无法找到activity。
data的结构:

data 主要是由 URI 和 mimeType 组成的。
URI 可配置很多信息,的结构如下:

与url类似,例如:

mineType:指资源类型包括文本、图片、音视频等等,例如:text/plain、 image/jpeg、video/* 等

下面看下data匹配的例子:
只匹配scheme

只匹配scheme也是能匹配到activity的。

匹配scheme、host、port
将上面的data改为

匹配mineType

如果有mineType,则不能仅设置setData或setMineType了,因为setData会把mineType置为null,而setMineType会把data置为null,导致永远无法匹配到activity,要使用setDataAndType。

使用scheme的默认值contentfile

注意该方法需要在startAtivity方法或者是finish方法调用之后立即执行,不能延迟,但可以在子线程执行。

而在windowAnimationStyle中存在四种动画:
activityOpenEnterAnimation // 打开新的Activity并进入新的Activity展示的动画
activityOpenExitAnimation // 打开新的Activity并销毁之前的Activity展示的动画
activityCloseEnterAnimation //关闭当前Activity进入上一个Activity展示的动画
activityCloseExitAnimation // 关闭当前Activity时展示的动画

overridePendingTransition的方式比较生硬,方法也比较老旧了,不适用于MD风格,google提供了新的转场动画ActivityOptions,并提供了兼容包ActivityOptionsCompat。

我们知道在onCreate和onResume里面直接获取到控件宽高为0,那有什么办法获取到控件的实际宽高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三种方式获取。

当用户点击桌面图标启动APP时,背后的流程如下:

我们看到的手机桌面是Launch程序的界面,点击应用图标会触发点击事件,调用startActivity(intent),然后通过Binder IPC机制,与ActivityManagerService(AMS)通讯,AMS执行一系列操作,最终启动目前应用,大概流程如下:

通过PackageManager的resolveIntent()收集跳转intent对象的指向信息,然后通过grantUriPermissionLocked()方法来验证用户是否有足够的权限去调用该intent对象指向的Activity。如果有权限,则在新的task中启动目标activity,如果发现没有进程,则先创建进程。

如果进程不存在,AMS会调用startProcessLocked创建新的进程,在该方法中,会通过socket的通讯方式通知zygote进程孵化新的进程并返回pid,在新的进程中会初始化ActivityThread,并依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。

创建好进程后下一步要将Application和进程绑定起来,AMS会调用上一节创建的ActivityThread对象的bindAppliction方法完成绑定工作,该方法会发送一条BIND_APPLICATION的消息,最终会调用handleBindApplication方法处理消息,并调用makeApplication方法处理消息,加载APP的classes到内存中。

通过前面的步骤,系统已经拥有了该Application的进程,后续的启动则是从已存在其他进程中启动Acitivity,即调用realStartAcitvityLocked,该方法会调用Application的主线程对象ActivityThread的sheleLaunchActivity方法,在方法中会发送LAUNCH_ACTIVITY到消息队列,最终通过handleLaunchActivity处理消息,完成Acitivty的启动。

Activity
Activity 的 36 大难点,你会几个?“建议收藏”
[译]Android Application启动流程分析

热点内容
小鸟酱265g资源密码多少啊 发布:2024-05-03 21:32:08 浏览:652
三国战纪游戏华为帐号密码是多少 发布:2024-05-03 21:22:54 浏览:949
变频压缩机启动 发布:2024-05-03 21:17:06 浏览:436
建立云存储 发布:2024-05-03 21:04:03 浏览:76
socket编程php 发布:2024-05-03 20:12:50 浏览:208
坦洲邮政局可以解压吗 发布:2024-05-03 20:09:55 浏览:732
二级程序编译答案 发布:2024-05-03 18:41:35 浏览:654
领动自动精英版是哪个配置 发布:2024-05-03 18:37:30 浏览:151
java编译器中cd什么意思 发布:2024-05-03 18:36:00 浏览:390
传奇服务器如何刷钱 发布:2024-05-03 18:36:00 浏览:978