androidactivity(androidactivity imageview充满屏幕)
本篇文章给大家谈谈androidactivity,以及androidactivity imageview充满屏幕对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、Android基础之Activity生命周期
- 2、Android Activity启动模式与状态保存及恢复详解
- 3、Android中的Activity详解--启动模式与任务栈
- 4、android activity的关闭处理的几种方式
- 5、Android 10.0 Activity的启动流程
- 6、Android之Activity全面解析,有些知识点容易忘记
Android基础之Activity生命周期
Activity是Android最常用的四大组件之一,Activity是Android应用中与用户交互的界面,通常一个activity就是一个屏幕,Activity一共有四种状态,Active/Running(当Activity可见且可以与用户交互);Paused(当Activity可见但是不可交互);Stoped(当Activity被完全覆盖不可见);Killed(当Activity被系统从内存中删除).其生命周期如下图:
相关方法及作用:
1 onCreate:当Activity创建时仅且调用一次,该方法主要适用于初始化页面。
2 onStart:当Activity调用onCreate方法之后,然后调用此方法开启Activity,Activty此时可见但不可交互。
3 onResume:此时Activity在前台可见且可与用户交互。适合做UI更新操作。
4 onPouse:当Activity被另外一个Activity覆盖时调用该方法。
5 onStop:当Activity在前台不可见或者Activity在销毁前调用此方法,此方法适合做一些资源的回收操作。
6 onDestroy:当activity被销毁时调用此方法。
问题:
1)onCreate 和 onStart 方法的区别
a.执行次数磨闹雀不同,onCreate只执行一次,而onStart可以执行多次。
b.在弯坦activity的状态不同,onCreate被调用时Activity的状态还是未可见,而调用onStart时已可见。
2) onStart 和 onStop的区别
在执行onStart或者onStop时,Activity都是不可交互的,执行onStart时Activity在前台不可见,在后台可见。而执行onStop时Activity前后台都不可见。
3)onResume 和 onPouse的区别
在执行onResume时,Activity在前台是可见的且可以与用户交互的。而执行onPouse时Activity在前台有可能可见,Activity没有获取到焦点,此时不可与用瞎早户交互。
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建立了联系。
内部维护一个 ArrayListActivityRecord 用来保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord与ActivityStack建立了联系。
内部维护了一个 ArrayListTaskRecord ,用来管理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的状态保持及恢复介绍完毕。
[img]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,而且这也是面试经常遇到的问题,退出程序的方式也有好几种,一下是一些处理关闭程序的方法:
1.最简单的方式就是使用系统的方法exit(0),这丛启是最简单粗暴的方式,强制程序退出,但是这种方法针对尘郑租部分机型有可能不太好使,退出时有可能出现程序崩溃的弹出框,或者程序会重新启动,这对用户体验来说不是很好。
2.抛出异常强制退出,这种方法的使用对用户体验来说简直就是灾难,所以就不要用这种方式了。
3.使用广播的方式通知activity进行关闭,这种方式也有人在用,大家可以自行百度下,我主要介绍下面这种方式。
4.使用application,在application中创建activity集合,创建添加以及删除activity的方法,并且在BaseActivity中的生命周期中调用这些方法,在使用的时候调用BaseApplication的方法,这也是目前最常用的方法,但是这种在BaseActivity中添加activity的方法也有一个问题,那就是当你要使用第三方的BaseActivity的时候,一个还好你可以继承,那如果要使用两个第三方的BaseActivity呢, Java 本身是单继承的,所以就会导致activity关闭不全了。那么这个问题的解决就要依靠一接口: ActivityLifecycleCallbacks ;这是Application中声明的一个接口,其内容如下:
@Override
public voidonActivityCreated(Activity activity,Bundle bundle) {
Log.e("onActivityCreated---","is running"+"--"+activity.getLocalClassName());
}
@Override
public voidonActivityStarted(Activity activity) {
Log.e("onActivityStarted---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityResumed(Activity activity) { Log.e("onActivityResumed---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityPaused(Activity activity) { Log.e("onActivityPaused---","is running"+"--"+activity.getClass().getCanonicalName());}
@Override
public voidonActivityStopped(Activity activity) { Log.e("onActivityStopped---","is running"+"--"+activity.getClass().getCanonicalName() );}
@Override
public voidonActivitySaveInstanceState(Activity activity,Bundle bundle) { Log.e("onActivitySaveInstanceState---","is running"+"--"+activity.getPackageName());}
@Override
public voidonActivityDestroyed(Activity activity) { Log.e("onActivityDestroyed---","is running"+"--"+activity.getPackageName());}
大派兆家可以看到这些方法名采用的都是英语中的过去式命名,其意大家看方法名也应该懂了,就是activity执行过得生命周期都会在这里调用,想要这些方法执行要调用
registerActivityLifecycleCallbacks(this);
这个方法,记得一定要调用啊,还有请记住这些回调是针对所有的Activity哦,所以我们就可以使用这样的方式去对activity进行关闭或者其他操作了。下面有一种存放activity的方式,喜欢的可以使用:
private staticWeakReferencecurAct;
private staticWeakHashMapacList=newWeakHashMap();
/***设置当前activity**
@paramact*/
public static voidsetCurActivity(Activity act) {curAct=newWeakReference(act);acList.put(act, null);}
/***获取想要的activity*@return*/
public staticActivitygetCurActivity() {if(acList==null||acList.isEmpty())return null;WeakReference wr =curAct;if(wr !=null) {returnwr.get();}return null;}
/***清理activity*@paramact*/
public static voidclearCurActivity(Activity act) { Object remove =acList.remove(act);if(remove !=null TextUtils .equals(remove.getClass().getSimpleName(),curAct.get().getClass().getSimpleName())) {//TODO You want to do something.}}/***销毁所有的activity*/public static voiddestroyAllActivity() {if(null!=acList !acList.isEmpty()) { Object[] keys =acList.keySet().toArray();for(Object obj : keys) { Activity act = (Activity)obj;if(act !=null) { act.finish();} } }}
/***关闭某个activity*@paramactivity*/
public static voidcloseActivity(String activity) {if(null!=acList !acList.isEmpty()) { Object[] keys =acList.keySet().toArray();for(Object obj : keys) {if(obj !=null activity !=null TextUtils.equals(obj.getClass().getSimpleName(),activity)) { Activity act = (Activity)obj;act.finish();} } }}
下面是CSDN地址: 原文链接
Android 10.0 Activity的启动流程
本文主要学习记录,基于Android 10的源码,有错误欢迎指正,主要目的是梳理流程图。
以进程为单位的调用栈图如下:
1.activity中的startActivity方法最终都会通过拿到ATSM的代理IActivityTaskManager调用的startActivity;
2.之后进入system server进程中的ATMS startActivity,ATMS 经过收集Intent信息,然后使用ActivityStackSupervisor.startSpecificActivityLocked,如果进程已经存在,则直接使用realStartActivityLocked,通过App的binder客猛颤腊户端的代理ApplicationThread调用回到bindApplication,走入Activity的启动流程;如果进程不存在则通过socket链接Zygote,请求fork新的进程;
3.App进程创建完成后,进程启动会调用ActivityThread.main方法,初始化主线程Handler,接着走入attach方法,然后通过AMS的代理调用AMS的attachApplication方法,并将App进程的通信代理ApplicationThread传入AMS;
4.AMS获取到ATMS调用ApplicationThread的bindApplication回到App进程的ActivityThread.ApplicationThread.bindApplication方法中,然后使用Handler切换到主线程执行handleBindApplication,这里初始化了App的进程名字、时间,用户的硬件配置,包括App的文件系统,创建了App的Context实例,洞启Instrumentation实例,调用App的onCreate回调方法,同时告诉AMS APP初始化工作完毕;
5.AMS接着会调用ATMS的attachApplication,最后调用ClientLifecycleManager的scheduleTransaction方法,通过App的Binder代理ApplicationThread回到ActivityThread;
6.进入ActivityThread.ApplicationThread.scheduleTransaction方法之后就进入了Activity的onStart、onResume回调
创建进程之前的过程主要是AMS的内部信息收集的判断的过程,下面主要看一下App进程启动的源码流程
从应用进程被创建开始,ActivityThread.main被执行
调用ActivityThread的attach方法,然后将activity和AMS通信的Binder代理IApplicationThread实例传入AMS
接着进入AMS进程,ActivityManagerService.attachApplicationLocked
1.thread.bindApplication :该方法主要讲App进程的配置信息通过IApplicationThread Binder通信回传到ActivityThread中
2.mAtmInternal.attachApplication :mAtmInternal实际就是ActivityTaskManager的实例,通过LocalServices加载
那么这里相当于走到了ActivityTaskManagerServer的attachApplication中
先看第一条:
注意:ActivityThread中存在于Binder通信的代理--》ApplicationThread extends IApplicationThread.Stub
ActivityThread--》ApplicationThread--》bindApplication
这里的bindApplication主要枝滑初始化了AppBindData,然后发送BIND_APPLICATION给APP的主线程BIND_APPLICATION,最后执行了handleBindApplication
handleBindApplication如下:
ActivityThread--》class H extends Handler
该方法主要在App进程中对App的一些硬件资源配置申请的属性、App的文件夹等完成App基本信息的初始化
接着看第二条:mAtmInternal.attachApplication
mAtmInternal.attachApplication最终会调用mRootActivityContainer.attachApplication(wpc)
RootActivityContainer.attachApplication
接着调用ActivityStackSupervisor.realStartActivityLocked开始创建Activity
ActivityStackSupervisor.realStartActivityLocked
创建ClientLifecycleManager和ClientTransactionHandler来辅助管理Activity的生命周期
注意
clientTransaction.addCallback是LaunchActivityItem
lifecycleItem是ResumeActivityItem
ClientLifecycleManager.scheduleTransaction最终会调用ClientTransaction的schedule方法
那么这个mClient是IApplicationThread的实例,那么此时也就回到了ActivityThread的ApplicationThread中
ActivityThread的ApplicationThread中
因为ActivityThread继承ClientTransactionHandler,所以到了ClientTransactionHandler中
通过Handler发送消息EXECUTE_TRANSACTION到H中
接着TransactionExecutor的execute方法
LaunchActivityItem.execute方法
client其实是在ActivityThread的实例,那么就回到了ActivityThread的handleLaunchActivity
接着调用performLaunchActivity
在performLaunchActivity中,主要是加载App的资源包,然后创建了Activity的context实例,并创建了Activity的实例,接着调用activity.attach方法,attach执行完之后调用了onCreate方法。
activity.attach
activity.attach中主要
1.创建了PhoneWindow实例
2.设置了Window接口的监听
3.初始化了成员变量,包括线程和WindowManager
到此Oncreate已经完成,那么OnStart和OnResume去哪了?
TransactionExecutor的execute方法
之前们只分析了executeCallbacks,接着executeLifecycleState方法
TransactionExecutor的executeLifecycleState方法
cycleToPath:lifecycleItem即为ResumeActivityItem
第一点:
int finish = lifecycleItem.getTargetState()
lifecycleItem对应ResumeActivityItem,如下:
ResumeActivityItem的getTargetState方法
对应ActivityLifecycleItem中的枚举类型:
第二点:ActivityClientRecord中的mLifecycleState,由于在前面已经执行了handleLaunchActivity所以mLifecycleState=1
对应ActivityLifecycleItem中的枚举类型:
PRE_ON_CREATE = 0
所以final int star = 1
接着看getLifecyclePath,此时start=1,finish=3
那么返回的IntArray就是2
接着看performLifecycleSequence
最终执行的是handleStartActivity所以最终走到了ActivityThread的handleResumeActivity
两点:
调用activity.performStart
调用Instrumetation.callActivityOnPostCreate
performStart方法:
调用了Instrumentation.callActivityOnStart方法:
最终到了activity的onStart方法
第二点:Instrumentation.callActivityOnPostCreate
上面主要走了cycleToPath,接着ResumeActivityItem.execute
调用了handleResumeActivity方法
handleResumeActivity最终调用performResumeActivity
调用了Instrumentation.callActivityOnResume,
到了activity.onResume()方法
参考文章:
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的默认值content\file
注意该方法需要在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的sheduleLaunchActivity方法,在方法中会发送LAUNCH_ACTIVITY到消息队列,最终通过handleLaunchActivity处理消息,完成Acitivty的启动。
Activity
Activity 的 36 大难点,你会几个?「建议收藏」
[译]Android Application启动流程分析
关于androidactivity和androidactivity imageview充满屏幕的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。