四大组件Activity详解

Activity

1.整体理解

Activity是一个负责与用户进行交互的组件。一个用户交互画面对应一个activity,可以通过其setContentView(View v)方法来显示需要的控件。Activity是Context的子类,同时实现了window.callback借口(里面方法如dispatchtouchevent可以分发事件)和keyevent.callback等,可以处理与窗体用户交互的事件(为什么能交互)。

2.生命周期

 

三种状态:  

显示状态:onCreate,onStart,onResume

看不见状态:onPause,onStop

销毁状态:onDestory

各周期会有的一些操作:

Void onCreate()

Activity已经被创建完毕,完成activity的初始化工作,比如加载布局,绑定事件。

onCreate方法有一个参数,可为空,也可是之前调用onSaveInstanceState()方法保存的状态信息。

Void onStart()

在该方式执行时表示所属活动将要被展示给用户。Activity已经显示与屏幕,但未得到焦点

Void onResume()

Activity得到焦点,可以与用户交互

Void onPause()

Activity失去焦点,无法与用户交互,但依然可见

当一个正在前台运行的activity因为其他activity需要前台运行而转入后台运行的时候,触发该方法。这时候需要活动的状态持久化,比如正在编辑的数据库记录等。

Void onStop

Activity不可见进入后台

当一个activity不再需要展示给用户的时候,触发该方法。如果内存紧张,系统会直接结束该活动,而不会触发onStop方法,所以保存状态信息是应该在onPause时做,而不是在onStop()时做。活动如果没有在前台运行,都将被停止或者Linux管理进程为了给新的活动预留足够的存储空间而随时结束活动。因此对于开发者来说,在设计应用程序的时候,必须时刻牢记这一原则。在一些情况下,onPause 方法或许是活动触发的最后的方法,因此开发者需要在这个时候保存需要保存的信息。

Void onDestroy()

Activity被销毁

Activity销毁的时候,触发该方法。和onStop方法一样,如果内存紧张,系统会直接结束这个活动而不会触发该方法。

Void onRestart()

当处于onStop状态的活动需要再次展现给用户的时候,触发该方法,即从不可见变成可见时会执行此方法

 

 

3.执行顺序

一个Activity 的启动顺序:

onCreate()——>onStart()——>onResume()

当另一个Activity 启动时:

第一个Activity onPause()——>第二个Activity onCreate()——>onStart()——>onResume()——>第一个Activity onStop()

当返回到第一个Activity 时:

第二个Activity onPause() ——> 第一个Activity onRestart()——>onStart()——>onResume()——>第二个Activity onStop()——>onDestroy()

4.异常情况生命周期

情况1.资源相关的系统配置发生改变

资源相关的系统配置发生改变,举个例子。当前Activity处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity就会销毁并且重建,其onPause, onStop, onDestory均会被调用。因为实在异常情况下终止的,所以系统会调用onSaveInstanceState来保存当前Activity状态。这个方法是在onStop之前,与onPause没有固定的时序关系。当Activity重建的时候系统会把onSaveInstanceState所保存的Bundle作为对象传递给onRestoreInstanceState和onCreate方法。

情况2:资源内存不足导致低优先级Activity被杀死

Activity优先级:

前台Activity——正在和用户交互的Activity,优先级最高

可见但非前台Activity——Activity中弹出的对话框导致Activity可见但无法交互

后台Activity——已经被暂停的Activity,优先级最低

系统内存不足是,会按照以上顺序杀死Activity,并通过onSaveInstanceState和onRestoreInstanceState这两个方法来存储和恢复数据。

 

5.Activity周期总结

1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态

2.当前Activity被其他Activity覆盖其上或被锁屏,系统会调用onPause方法,暂停当前Activity的执行

3.当前Activity由被覆盖状态回到前台或解锁屏,系统会调用onResume方法,再次进入运行状态

4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台,系统会先调用onPause方法,然后调用onStop方法,进入停滞状态

5.用户后退到此Activity,系统会先调用onRestart方法,然后调用onStar方法,最后带哦用onResume方法,再次进入运行状态。

6.当前Activity处于被覆盖状态或后台不可见状态,系统内存不足,则会杀死当前Activity,而后用户退回当前Activity,则会再次调用onCreate方法,onStart方法,onResume方法,进入运行状态。

7.用户退出当前Activity:系统调用onPause,然后调用onStop方法,最后调用onDestory方法,结束当前Activity

 

6.任务栈

 

 

7.四种启动模式

在清单文件里,Acitvity有个LaunchMode属性,进行设置

standard

· 系统默认启动模式

· 不论存在与否,都会重新创建一个新的实例

· 多实例实现,谁启动了这个Activity、那么这个Activity就运行在启动它那个Activity所在栈

singleTop

· 判断需要启动的Activity是否为任务栈栈顶 ,如果是,则不会重新创建,如果不是,则会重新创建

· 不重新创建时候,该Activity的 onNewIntent(Intent intent) 方法会被回调,通过该方法的参数,可以取出当前请求的信息;

· 系统可能会杀死该Activity,杀死之后,启动情况与第一次启动相同,所以有必要在onCreate与onNewIntent方法中调用同一个处理数据的方法
运用场景:常运用于通知栏弹出Notification,点击Notification跳转到指定的Activity,设置singleTop模式还有浏览器的书签

singleTask

· 判断Activity所需任务栈内是否已经存在,如果存在,就把该Activity切换到栈顶(会导致在它之上的都会出栈)

· 如果所需任务栈都不存在,就会先创建任务栈再创建该Activity

· 可以理解为 顶置Activity+singleTop 的模式
运用场景:可用来退出整个应用。主界面activity设为singleTask模式,要退出应用时转到主activity,从而将主activity之上的activity都清除,然后重写主activity的onNewIntent()方法,在里面加上finish(),即可退出所有activity。这种模式还适用于做浏览器、微博之类的应用

singleInstance

· 拥有singleTask的所有特性之外,此模式Activity只能单独地位于一个新的任务栈中

· 也就是,Activity启动之后,就会独自在一个新的任务栈中,下次肯定不会重新创建该Activity,除非被系统杀死
运用场景:这种模式常运用于需要与程序分离的界面,如在SetupWizard(安装向导)中调用紧急呼叫就是适用这种模式还有电话拨打界面

8.横竖屏切换

默认情况下,横竖屏切换,销毁当前的activity,重新创建一个新的activity

在一些特殊情况下,是不希望横竖屏切换的,比如,activity切换时,EditText中的文字没有了

解决方案:

1.AndriudMainfest.xml加入声明,将横竖屏写死

Android:screenOrientation=landscape  portrait

2.让系统的环境不再敏感横竖屏切换

Andorid:configChanges=orientation|screenSize

3.EditText控件加上id,系统会自动保存然后恢复,或者在onSaveInstanceState保存,在重新创建的onCreate方法中恢复

9.Activity数据保存

Activity由于系统配置等发生改变,会导致Activity被杀死而重新创建。即会调用onDestroy销毁Activity,再重新onCreate开启新Activity,系统通过调用onSaveInstanceState和onRestoreInstanceState分别保存和恢复视图(View)状态。

 

· onSaveInstanceState

onSaveInstanceState在onStop之前调用,但不一定在onPause之前或者之后。onRestoreInstanceState在onStart之后调用

需要注意的是,onSaveInstanceState方法只会在Activity被异常终止,在Activity即将被销毁且有机会重新显示的情况下才会调用

 

可以总结有下面几种情况:

1、当用户按下HOME键时。

这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则

2、长按HOME键,选择运行其他的程序时。

3、按下电源按键(关闭屏幕显示)时。

4、从activity A中启动一个新的activity时。

5、屏幕方向切换时,例如从竖屏切换到横屏时。(如果不指定configchange属性) 在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行

总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据(当然你不保存那就随便你了)。

此外,由于默认的onSaveInstanceState()方法的实现帮助UI存储它的状态,所以如果你需要覆盖这个方法去存储额外的状态信息时,你应该在执行任何代码之前都调用父类的onSaveInstanceState()方法(super.onSaveInstanceState())。 既然有现成的可用,那么我们到底还要不要自己实现onSaveInstanceState()?这得看情况了,如果你自己的派生类中有变量影响到UI,或你程序的行为,当然就要把这个变量也保存了,那么就需要自己实现,否则就不需要。

· onRestoreInstanceState

onRestoreInstanceState方法在activity确定被销毁以后,重建activity时调用,注意是确定activity被销毁,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行。

另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原。 还有onRestoreInstanceState在onstart之后执行。 至于这两个函数的使用,给出示范代码(留意自定义代码在调用super的前或后):

· 由于内存不足导致的Activity被杀死

activity由于内存不足,被系统杀死后会调用onSaveInstanceState和onRestoreInstanceState保存和恢复视图。按照优先级从高到低,将activity分为以下三种:前台Activity、可见但非后台Activity、后台Activity,当系统内存不足,系统会按照上述优先级杀死目标Activity所在进程。

注,如果是少量数据,可以通过onSaveInstanceState()和onRestoreInstanceState()进行保存与恢复,如果是大量数据就要使用Fragment保持保存的对象。

10.Activity过渡动画的五种实现

------》Activity之间的数据传递,常见的有4中,Intent传递简单数据,Bundle传递数据包,传递值对象,获取Activity的返回参数

这之间都用到了Intent,intent支持: 实现Serializable接口,实现parcelable接口,charSequence,Bundle四种类型。

1. Intent传递简单数据

· Activity通过Intent启动时,可以通过Intent对象携带数据到目标Activity

        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("maleName", maleName);
        intent.putExtra("femaleName", femaleName);
        startActivity(intent);

· 在目标Activity中取出数据

        Intent intent = getIntent();
        String maleName = intent.getStringExtra("maleName");
        String femaleName = intent.getStringExtra("femaleName");

2. Bundle传递数据包

通过使用Bundle可以传递稍微复杂的数据,进行数据交互。

· MainActivity

Intent intent = new Intent(MainActivity.this,OtherActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name","MirGao");
bundle.putString("age","24");
intent.putExtras(bundle);

startActivity(intent);

· OtherActivity

Intent intent = getIntent();
Bundle b = intent.getExtras();
tv.setText(b.getString("name") + "  " + b.getString("age"));

3.传递值对象(序列化对象)

Java中实现Seriallizable接口,使用序列化很简单,可以方便的进行复杂,大量数据的传递,但是,Serializable与Parcelable相比而言 效率比较低 ,所以Android平台又给我们提供了Parcelable,他是一个专门针对移动工具上数据序列化的接口。

Serializable和Parcelable都是序列化接口,因为Serializable简单,方便,Android系统对他有自动完成序列化的操作,所以速度是比较慢的。而Parcelable中都是手动去添加数据类型,读取数据,Android系统并没有给我们提供序列化机制,所以Parcelable的数据是相对复杂的,但是速度是比较快的。所以在使用时,注意优缺点选择。

 

利用Android 提供的Parcelable 传递数据

实现Parcelable步骤

1. implements Parcelable

2. 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据

3. 重写describeContents方法,内容接口描述,默认返回0就可以

4. 实例化静态内部对象CREATOR实现接口Parcelable.Creator

Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据。而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

 

选择序列化方法的原则

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。

2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。

 

 

 

 

4.获取Activity的返回参数

· startActivityForResult(Intent intent,int requestCode)方法

· 回调方法:onActivityResult(int requestCode, int resultCode, Intent data)

· setResult(int Request,Intent data);

· 两个data是一个Intent对象,里面放的是要回调的数据

· 请求码:用来区分数据来自于哪一个Activity

· 结果码:用来区分,返回的数据时属于什么类型

 

 

11.Activity过渡动画的五种实现

1.使用overridePendingTransition方法实现Activity跳转动画

overridePendingTransition方法是Activity中提供的Activity跳转动画方法,通过该方法可以实现Activity跳转时的动画效果,简单例子如下:

 

注意:overridePendingTransition在startActivity或者是finish方法立刻执行才有效

 

2、使用style的方式定义Activity的切换动画

1)定义Application的style

 

2)定义具体的AppTheme样式

其中这里的windowAnimationStyle就是我们定义Activity切换动画的style。而@anim/slide_in_top就是我们定义的动画文件,也就是说通过为Appliation设置style,然后为windowAnimationStyle设置动画文件就可以全局的为Activity的跳转配置动画效果。

 

而在windowAnimationStyle中存在四种动画:

---》activityOpenEnterAnimation
用于设置打开新的Activity并进入新的Activity展示的动画

---》activityOpenExitAnimation
用于设置打开新的Activity并销毁之前的Activity展示的动画

---》activityCloseEnterAnimation
用于设置关闭当前Activity进入上一个Activity展示的动画

---》activityCloseExitAnimation
用于设置关闭当前Activity时展示的动画

3.使用ActivityOptions切换动画实现Activity跳转动画

通过overridePendingTransition方法基本上可以满足我们日常中对Activity跳转动画的需求了,但MD风格出来之后,overridePendingTransition这种老旧、生硬的方式怎么能适合我们的MD风格的App呢?google在新的sdk中给我们提供了另外一种Activity的过度动画——ActivityOptions。并且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat是一个静态类,提供了相应的Activity跳转动画效果,通过其可以实现不少炫酷的动画效果。

1)在跳转的Activity中设置contentFeature

 

2)在startActivity执行跳转逻辑的时候调用startActivity的重写方法,执行ActivityOptions.makeSceneTransitionAnimation方法

效果图见gif图-activity跳转

(四)使用ActivityOptions之后内置的动画效果通过style的方式

这种方式其实就是通过style的方式展示和使用ActivityOptions过度动画,下面是实现通过定义style方式定义过度动画的步骤:

1)编写过度动画文件

 

首先我们需要在Application项目res目录下新建一个transition目录,然后创建资源文件,然后使用这些系统自带的过渡动画效果,这里设置了过度时长为300ms。

 

 

2)定义style文件

 

Application的style文件中添加:

 

并指定过渡动画效果为我们刚刚定义的过渡动画文件。

3)执行跳转逻辑

点击按钮,实现Activity的跳转操作 * 通过Android5.0及以上style的方式实现activity的跳转动画

 

这样执行之后也可以展示出Activity跳转过度动画了,其和通过代码方式实现的效果是类似的,而且这种动画效果是全局的。

(五)使用ActivityOptions动画共享组件的方式实现跳转Activity动画

这里的共享组件动画效果是指将前面一个Activity的某个子View与后面一个Activity的某个子View之间有过渡效果,即在这种过度效果下实现Activity的跳转操作。那么如何实现两个组件View之间实现过渡效果呢?

1)定义共享组件

Activity a中的button按钮点击transitionName属性:

 

Activity b的布局文件中为组件定义transitionName属性,这样这两个组件相当于有了过度对应关系,这里需要注意的是这两个组件的transitionName属性的值必须是相同的。

 

2)调用startActivity执行跳转动画

点击按钮,实现Activity的跳转操作 * 通过Android5.0及以上共享组件的方式实现activity的跳转动画

 

需要说明的是这里调用的ActivityOptions.makeSceneTransitionAnimation方法,传递了三个参数,其中第一个参数为context对象,第二个参数为启动Activity的共享组件,第三个参数为启动Activity的共享组件transitionName属性值。

这样经过调用之后我们就实现了从Activity a跳转到Activity b的时候a中的组件到b中组件的过度效果,效果见gif图-activity跳转02

 

过渡动画总结

overridePendingTransition方法从Android2.0开始,基本上能够覆盖我们activity跳转动画的需求;

ActivityOptions API是在Android5.0开始的,可以实现一些炫酷的动画效果,更加符合MD风格;ActivityOptions还可以实现两个Activity组件之间的过渡动画;

11.常见问题

        1.Activity间跳转时,为什么是先AActivity的onPause()被调用,然后是BActivity的初始化流程(onCreate() --> onStart() --> onResume()),再然后是AActivity的onStop()被调用?

·  onResume() 的注释中,建议是在onResume()中打开独占设备(比如相机),与onResume()对应的是onPause(),关闭相机的操作也应该在此方法中被调用;否则,考虑一下如下场景:
如果AActivity打开了相机,我们点击某按钮要跳转到BActivity中,BActivity也想打开相机;假设AActivity的onPause() 在 BActivity启动后再被调用,那BActivity根本就无法再正常启动相机。

· onPause() 的注释中,也明确地说了,在这个方法中执行停止动画等比较耗CPU的操作,如果不先执行这些操作,就先启动新应用,然后再来执行此操作,确实是不合逻辑;

从逻辑的完整性和用户体验的角度来分析,这样实现确实是比较合理的,当用户触发某事件切换到新的Activity,用户肯定是想尽快进入新的视图进行操作,上面已经说了,在onResume()一般会打开独占设备,开启动画等,当需要从AActivity切换到BActivity时,先执行AActivity中的与onResume()相对应的onPause()操作,比如关闭独占设备,关闭动画,或其它耗费cpu的操作;以防止BActivity也需要使用这些资源,关闭耗CPU的操作,也有利于BActivity运行的流畅。

底层执行AActivity的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。

AActivity中比较消耗资源的部分关闭后,再切换到BActivity中执行BActivity的初始化,显示BActivity中的View。

BActivity已经执行显示出来了,用户可以交互,后台再去执行AActivity的onStop()操作,即使这里面有些比较耗时的操作,也没有关系,这是在后台执行所以也不影响用户的体验。

2如何保存 Activity 的状态?

Activity 的状态通常情况下系统会自动保存的,只有当我们需要保存额外的数据时才需要使用到这样的功能。一般来说, 调用 onPause()和 onStop()方法后的 activity 实例仍然存在于内存中, activity 的所有信息和状态数据不会消失, 当 activity 重新回到前台之后, 所有的改变都会得到保留。但是当系统内存不足时, 调用 onPause()和 onStop()方法后的 activity 可能会被系统摧毁, 此时内存中就不会存有该 activity 的实例对象了。如果之后这个 activity 重新回到前台, 之前所作的改变就会消失。为了避免此种情况发生 , 我 们 可 以 覆 写 onSaveInstanceState() 方 法 。onSaveInstanceState()方法接受一个 Bundle 类型的参数, 开发者可以将状态数据存储到这个Bundle 对象中, 这样即使 activity 被系统摧毁, 当用户重新启动这个 activity 而调用它的 onCreate()方法时, 上述的 Bundle 对象会作为实参传递给 onCreate()方法, 开发者可以从 Bundle 对象中取出保存的数据, 然后利用这些数据将 activity 恢复到被摧毁之前的状态。需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下 BACK 键退出 activity 时, 用户显然想要关闭这个 activity, 此时是没有必要 保 存 数 据 以 供 下 次 恢 复 的 , 也 就 是 onSaveInstanceState() 方 法 不 会 被 调 用 . 如 果 调 用onSaveInstanceState()方法, 调用将发生在 onPause()或 onStop()方法之前。

 

@Overrideprotected void onSaveInstanceState(Bundle outState) {// TODO Auto-generated method stubsuper.onSaveInstanceState(outState);

}

 

3两个 Activity 之间跳转时必然会执行的是哪几个方法?

一般情况下比如说有两个activity,分别叫A,B,当在A里面激活B组件的时候, A会调用 onPause()方法,然后 B 调用 onCreate() ,onStart(), onResume()。
这个时候 B 覆盖了窗体, A 会调用 onStop()方法. 如果 B 是个透明的,或者是对话框的样式, 就不会调用 A 的 onStop()方法。

4横竖屏切换时 Activity 的生命周期
此时的生命周期跟清单文件里的配置有关系。
1.不设置 Activity 的 android:configChanges 时,切屏会重新调用各个生命周期默认首先销毁当前 activity,然后重新加载。
2.设置 Activity android:configChanges="orientation|keyboardHidden|screenSize"时,切屏不会重新调用各个生命周期,只会执行 onConfigurationChanged 方法。通常在游戏开发, 屏幕的朝向都是写死的。

5如何将一个 Activity 设置成窗口的样式
只需要给我们的 Activity 配置如下属性即可。android:theme="@android:style/Theme.Dialog"

6如何退出Activity?如何安全退出已调用多个Activity 的Application?

(1)通常情况用户退出一个 Activity 只需按返回键,我们写代码想退出 activity 直接调用 finish()方法就行。

(2)记录打开的 Activity:每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。

//伪代码

List<Activity> lists ;// application 全局的变量里面

lists = new ArrayList<Activity>();

lists.add(this);for(Activity activity: lists)

{

activity.finish();

}

lists.remove(this);

(3)发送特定广播:

在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭即可。

//给某个 activity 注册接受接受广播的意图registerReceiver(receiver, filter)//如果过接受到的是 关闭 activity 的广播 就调用 finish()方法 把当前的 activity finish()

(4)递归退出

在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在 onActivityResult 中处理,递归关闭。

(5)其实也可以通过 intent 的 flag 来实现 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一个新的 activity。此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有 Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。

7Activity 的四种启动模式,singletop 和 singletask 区别是什么?一般书签的使用模式是 singletop,那为什么不使用 singletask?

singleTop 跟 standard 模式比较类似。唯一的区别就是,当跳转的对象是位于栈顶的 activity(应该可以理解为用户眼前所 看到的 activity)时,程序将不会生成一个新的 activity 实例,而是直接跳到现存于栈顶的那个 activity 实例。拿上面的例子来说,当 Act1 为 singleTop 模式时,执行跳转

后栈里面依旧只有一个实例,如果现在按返回键程序将直接退出。singleTask 模式和 singleInstance 模式都是只创建一个实例的。在这种模式下,无论跳转的对
象是不是位于栈顶的 activity,程序都不会生成一个新的实例(当然前提是栈里面已经有这个实例)。这种模式相当有用,在以后的多 activity 开发中,常会因为跳转的关系导致同个页面生成多个实例,这个在用户体验上始终有点不好,而如果你将对应的 activity 声明为 singleTask 模式,这种问题将不复存在。在主页的 Activity 很常用

8Android 中的 Context, Activity,Appliction 有什么区别?
相同:Activity 和 Application 都是 Context 的子类。Context 从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理上下文环境中各个参
数和变量的总用,方便我们可以简单的访问到各种资源。不同:维护的生命周期不同。 Context 维护的是当前的 Activity 的生命周期,Application 维护
的是整个项目的生命周期。使用 context 的时候,小心内存泄露,防止内存泄露,注意一下几个方面:
1. 不要让生命周期长的对象引用 activity context,即保证引用 activity 的对象要与 activity 本身生命周期是一样的。
2. 对于生命周期长的对象,可以使用 application,context。
3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化。

9两个 Activity 之间传递数据,除了 intent,广播接收者,contentprovider 还有啥?
1)利用 static 静态数据,public static 成员变量
2)利用外部存储的传输,

3EventBusRxBus
例如 File 文件存储
SharedPreferences 首选项
Sqlite 数据库

10Context 是什么?
1、它描述的是一个应用程序环境的信息,即上下文。
2、该类是一个抽象(abstract class)类,Android 提供了该抽象类的具体实现类(ContextIml)。
3、 通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如: 启动一个 Activity,发送广播,接受 Intent,信息,等。

10、如何完全退出一个App

// 移除栈空间中所有的Acitivity
ActivityManager.getInstance().removeAll();
// 结束当前进程
android.os.Process.killProcess(android.os.Process.myPid());
// 结束当前虚拟机执行
System.exit(0);

 

猜你喜欢

转载自blog.csdn.net/mr___xu/article/details/80580146