列举android四大组件名称,Android四大组件(一):Activity

Activity是Android应用中负责与用户交互的组件,给Android应用提供可视化用户界面。Activity是Window的容器,Activity包含一个getWindow()方法,返回该Activity所包含的窗口。

创建Activity

需要在清单文件中为其配置一个activity标签

标签中如果带有这个子节点,则会在系统中多创建一个快捷图标

一个应用程序可以在桌面创建多个快捷图标。

activity的名称、图标可以和应用程序的名称、图标不相同

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

Activity的生命周期

Activity的四个状态

a0ee9fb34c38

Activity的四个状态

活动状态:当前Activity位于前台,用户可见,可以获得焦点进行交互。

暂停状态:其他Activity位于前台,该Activity依然可见,只是不能获得焦点进行交互,常见如弹出PopupWindow。

停止状态:该Activity不可见,失去焦点。

销毁状态:该Activity结束,或Activity所在的Dalvik进程结束。

Activity生命周期及回调方法

a0ee9fb34c38

Activity生命周期及相关的回调方法

onCreate(Bundle savedStatus):创建Activity时被回调;

onStart():启动Activity时被回调,Activity已经显示在屏幕,但没有得到焦;

onRestart():重新启动Activity时被回调,Activity从不可见变成可见时会执行此方法;

onResume():恢复Activity时被回调, Activity得到焦点,可以与用户交互;

onPause():暂停Activity时被回调,Activity失去焦点,无法再与用户交互,但依然可见;(可用于保护界面当前状态)

onStop():停止Activity时被回调,Activity不可见,进入后台;

onDestroy():销毁Activity时被回调。

Activity实践中的生命周期方法回调过程

启动Activity:onCreate->onStart->onResume;

点击Home键返回系统桌面:onPause->onStop;

点击应用列表的图标重新进入应用:onRestart->onStart->onResume;

点击返回键(或程序调用finish()方法):onPause->onStop->onDestory;

Activity跳转时的生命周期方法回调过程

a0ee9fb34c38

Activity跳转时生命周期

横竖屏切换的生命周期

默认情况下 ,横竖屏切换, 销毁当前的activity,重新创建一个新的activity。在一些特殊的应用程序常见下,比如游戏,不希望横竖屏切换activity被销毁重新创建。

默认情况(manifest清单文件中不对Activity的configChanges属性做任何设置):

1、android3.2之前的版本:onSaveInstanceState->onPause->onStop->onDestroy->onCreate->onStart->onResume;

2、android3.2以后的版本:onPause->onSaveInstanceState->onStop->onDestroy->onCreate->onStart->onResume;

设置让Activity对横竖屏切换不敏感(清单文件中设置android:configChanges="orientation"):

1、android3.2之前的版本:调用onConfigurationChanged(不会重建Activity,也不会调用任何生命周期方法)

2、android3.2之后的版本,又分为两种情况:

①targetSdkVersion<=12:调用onConfigurationChanged(不会重建Activity,也不会调用任何生命周期方法);

②targetSdkVersion>12:onPause->onSaveInstanceState->onStop->onDestroy->onCreate->onStart->onResume(配置的android:configChanges="orientation"没起作用);

③如果targetSdkVersion>12时,想让横竖屏切换时不重建Activity,还得配置screenSize,也就是android:configChanges="orientation|screenSize"(因为google在android3.2中添加了screensize改变的通知,在转屏的时候,不仅是orientation发生了改变,screensize同样也发生了改变),这是最保险的做法。

开发实践中禁用掉横竖屏重建Activity:

1、直接将Activity的横竖屏写死(简单、但是用户体验不友好,具体根据产品需求):

//①通过清单文件配置Activity

android:screenOrientation="landscape"//始终横屏

android:screenOrientation="portrait"//始终竖屏

//②在代码中实现:

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//始终横屏

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //始终竖屏

2、通过清单文件配置Activity不再敏感横竖屏切换(相对更友好安全的做法,参见上文这也是兼容性更好的做法,如果需要在横竖屏切换时做业务逻辑处理,可以在onConfigurationChanged方法中实现):

在manifest.xml中配置activity:

android:configChanges="orientation|screenSize"

Activity的启动模式

所有的Activity都将存放在任务栈中,通过设置Activity的启动模式,可以修改任务栈的排列模式。我们可以在可以通过adb指令来查看系统的任务栈情况:adb shell dumpsys activity。 adb shell dumpsys activity activities | findstr "ResumedActivity"(这是用来查看当前活跃的栈顶Activity)。

Activity的四种启动模式

Standard 标准启动模式:Android创建Activity时的默认模式,假设没有为Activity设置启动模式的话,默觉得标准模式。每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。

a0ee9fb34c38

Standard启动模式

SingleTop 栈顶复用模式:假设你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存。

①如果需要创建的Activity已经不处于栈顶,将会创建一个新的Activity入栈,同Standard模式一样。

a0ee9fb34c38

SingleTop模式Activity位于栈顶

②如果须要创建的Activity已经处于栈顶时,此时不会再创建新的Activity,而是直接复用栈顶的Activity,保证栈顶如果存在,不会重复创建。此时Activity的onCreate、onStart不会被系统调用,由于它并没有发生改变。但是它的的 onNewIntent会被回调。

a0ee9fb34c38

SingleTop模式Activity不在栈顶

SingleTask 栈内复用模式: 当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,如果有实例存在就复用这个已经存在的activity,并且把这个activity上面的所有的别的activity都清空让此Activity位于栈顶,并且回调Activity的onNewIntent方法。保证整个任务栈里面只有一个实例存在。如果不存在同Standard模式一样。(如果一个activity的创建需要占用大量的系统资源一般配置这个activity为singletask的启动模式,一般应用的主界面也会配置为SingleTask模式) 。

a0ee9fb34c38

SingleTask模式复用

SingleInstance启动模式非常特殊,是全局单例模式,是一种加强的SingleTask模式。它除了具有SingleTask的所有特性外,还有一个特点,SingleInstance启动的activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在。一般应用开发很少用到,如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance。比如Launch、锁屏键、电话拨打界面等。

①我们可以试着做一个SingleInstance启动模式的小猜想:假设我们从MainActivity ->(跳转到)SingleInstanceActivity ->(跳转到) ->SecondActivity。 然后我们点击返回按钮,页面的返回顺序会是怎样?如果你试了之后不理解其原理,下文有关于任务栈的详细介绍。

任务栈的相关理解

在上文的启动模式中我们多次提到任务栈这个概念,任务是一个activity的集合,它用栈(后进先出)的方式来管理activity;这个栈被称为返回栈(back stack),栈里的activity顺序是按打开顺序放置。

①当用户在home界面点击应用图标时候,这个应用的任务就会被转移到前台,如果这个应用的任务是空的,说明最近这个应用没有被启动过,系统就会去创建一个新的任务,将该应用的主activity放入到返回栈中。

②当一个activity启动了一个新activity的时候,新的activity会被放置到返回栈的栈顶并获取焦点(如果是SingleInstance启动模式,新的Activity会新建一个栈并独享);前一个activity仍然保留在任务栈,但处于停止状态。

③当用户按下返回键的时候,处于栈顶的activity会被移除掉,前一个activity就会重新回到栈顶的位置。我们只能向栈顶添加activity或者将栈顶的activity移除掉。

④如果一直按返回键,返回栈中的activity会一个一个的被移除,最终返回到主屏幕,这时候返回栈中activity全被清空,对应的任务也就不存在了。

当打开一个应用,对应的任务处于前台;这时候点击home键回到主屏幕,任务就被转移到后台;当任务处于后台状态的时候,返回栈中的activity都进入停止状态,但在返回栈中的顺序不会变,每个activity的信息和数据都在;当处于内存不足的情况下有可能会被销毁回收(涉及到进程优先级问题)。

a0ee9fb34c38

通过SingleInstance启动模式理解任务栈

启动模式的使用方式

1、在Manifest.xml清单文件中静态指定启动模式:

android:name=".MainActivity"

android:launchMode="singleTask"/>

2、在Intent中动态指定启动模式去创建Activity:

Intent intent = new Intent();

intent.setClass(context, MainActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

两种方式的区别:在Intent中动态指定的方式,优先级更高,若两者同时存在,以动态指定方式为准;

Activity异常结束时保存状态

Activity异常结束

Activity的异常结束是指,非人为主动结束和退出Activity的行为,一般有以下两种情况:

1、资源系统设置变更:如横竖屏切换,可能会导致Activity销毁重建,或者设备语言发生变化,或者键盘发生变化时。我们可以在清单文件中配置Activity的configChanges属性来避免(具体参照上文)。

2、系统资源不足时:由于虚拟机的垃圾回收机制,在系统内存不足时,会自动回收掉低优先级的进程,释放内存保证优先级高的进程能正常运行(Android进程优先级相关知识)。

在Activity异常结束时保存和恢复数据

保存数据:onSaveInstanceState(),只会在异常退出时才会回调。如果用户显式关闭Activity时(点击返回,或者触发Activity的finish方法),则系统不会回调此方法。调用的时机android3.2之前的版本:onSaveInstanceState在onPause之前回调,Android3.2之后在onPause之后回调。

@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putString("name", "rave");

}

恢复数据:onRestoreInstanceState(),会在页面异常关闭之后,重新进入时回调。调用时机是在onStart之后,onResume之前(没有做过低版本测试)。

@Override

protected void onRestoreInstanceState(Bundle savedInstanceState) {

super.onRestoreInstanceState(savedInstanceState);

if(savedInstanceState != null){

String name = savedInstanceState.getString("name");

System.out.println(name);

}

}

对于控件来说,在Activity异常结束时,部分系统控件会自动保存和恢复它的状态(如EditView)。因为View类里面也有onSaveInstanceState()和onRestoreInstanceState(Parcelable state),如果要自定义控件实现该功能可以参考系统控件的做法。

Activity的之间的数据传递

当一个Activity启动另一个Activity时,或者当一个Activity关闭并返回时,常常会有一些数据需要传递。Android的做法是将数据以键值对的方式存放在Bundle中,让Intent携带Bundle在Activity之间完成数据传递。我们通过intent的putExtras()来添加数据,里面可以存放所以可序列化的类型(基本数据类型及其数组:byte、boolean、char、short、int、long、float、double、byte[]...;实现Parcelable接口的类;实现Serializable接口的类;还有这些类型的ArrayList集合类:ArrayList extends Parcelable>、ArrayList、ArrayList、ArrayList)。???疑问这里Parcelable和Serializable有什么区别

Activity启动另一个Activity传递数据:

Bundle bundle = new Bundle();

bundle.putBoolean("booleanValue", true);

Intent intent = new Intent();

intent.putExtras(bundle);

startActivity(intent);

//startActivityForResult(intent, 0);

从Intent里面提取数据:

Bundle bundle = getIntent().getExtras();

boolean value = bundle.getBoolean("booleanValue");

Activity关闭并返回数据:

Bundle bundle = new Bundle();

bundle.putSerializable("booleanValue", true);

Intent intent = new Intent();

intent.putExtras(bundle);

setResult(1, intent);

finish();

从返回的Activity里提取数据:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

Bundle bundle = data.getExtras();

}

Activity转场动画

使用Scheme方式唤起Activity

Android中启动Activity主要有两种方式,一种是通过显示意图启动,一种是通过隐式意图启动。这里介绍的使用Scheme方式唤起,其实是隐式意图启动的一种,因为这种方式在hybird开发中很常用所以提出来单独介绍。

android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面。客户端应用可以通过清单文件向操作系统注册一个 URL scheme,该 scheme 用于从浏览器或其他应用中启动本应用。通过指定的 URL 字段,可以让应用在被调起后直接打开某些特定页面,比如商品详情页、活动详情页等等。也可以执行某些指定动作,如完成支付等。也可以在应用内通过 html 页来直接调用显示 app 内的某个页面。

URL Scheme使用场景大致分以下几种

服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面

H5页面点击锚点,根据锚点具体跳转路径APP端跳转具体的页面

APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页面

APP根据URL跳转到另外一个APP指定页面

xl代表该Scheme 协议名称

goods代表Scheme作用于哪个地址域

goodsDetail代表Scheme指定的页面

goodsId代表传递的参数

8888代表该路径的端口号

使用方式

唤起外部应用的Activity:

1、必须在目标Activity的Manifest.xml中配置如下过滤器(关于Intent和Intent-filter会单独说明):

android:host="first"

android:path="/enter"/>

2、启动方式:

Intent intent = new Intent();

intent.setData(Uri.parse("artist://first/enter"));

startActivity(intent);

唤起应用内部Activity(也可以用上面的方式唤起内部Activity),可以用下面的方式:

1、在目标Activity的Manifest.xml中配置如下过滤器

android:host="first"

android:path="/enter"/>

2、启动方式:

WebView.loadUrl("artist://first/enter");

相关源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值