- Activity创建和启动
Activity概述
四大组件之一的Activity组件,在应用中一个Activity可以用来表示一个界面,中文意思也可以理解为“活动”,即一个活动开始,代表Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个android应用必须通过Activity来运行和启动,Activity的生命周期交给系统统一管理。
-
- 通过Activity创建向导创建
通过向导创建Activity时,会自动在清单文件中注册,无需再手动注册,但是一般情况下仍然需要对注册部分进行修改。
1.File > new > other>android>Android Activity
2、点击next,然后选择一个Activity模板
3、下一步,填写相应信息
4、点击Finish后,稍等片刻Activity创建成功,并且清单文件中已经自动配置完毕。
-
- 直接创建类,然后手动配置
- 创建一个类,使该类继承系统的android.app.Activity
- 在清单文件AndroidManifest.xml中注册刚刚创建的Activity。
注册方式:在application标签下直接添加一个新的activity标签,并给该配置属性android:name=”” 值得是Activity的全名(包名+类名)
android:label=" " 值是Activity显示的标题
备注:android的四大组件Activity、Service、BroadcasetReceiver、ContentProvider都必须 在清单文件中注册。(BroadcasetReceiver比较特殊,有一种动态注册即使用java代码注册)
-
- Activity的启动
- 点击快捷方式启动。如果在配置Activity的时候,配置了如下的intent-filter(意图过滤器),则会在手机中从产生快捷方式,点击该快捷方式则启动该Activity。
- 使用java代码启动一个新的Activity,实现页面的跳转。
在代码中调用如下方法Context.startActivity(意图对象)
Intent i = new Intent(this, SecondActivity.class);
this.startActivity(i);
注:意图分隐式意图和显示意图。
做为Activity,系统自动生成了一个onCreate方法 ,这个方法是Activity被开启的时候所调用的方法,大多数做一些初始化的操作,一般情况下我们要重写这个方法,它推荐我们调用setContentView()方法来显示一个界面,这个方法接收一个而局文件的ID,就是想显示哪个布局文件,这里就传哪个布局文件的ID。
- Activity页面跳转
前面我们在写安卓应用时只写了一个界面,当程序运行时,启动一个Activity,这个界面就显示出来了,但是实际中一个应用程序会有好多个界面,也就是说会有很多个Activity,那我们怎么实现各个Activity之间的跳转呢?
我们回顾一下在JAVAWEB中,页面的跳转有两方式有两种,一种叫重定向,一种叫转发。那么在安卓应用中,我们也可以模拟WEB中的跳转方式,让一个Activity跳转到另外一个Activity。
在安卓系统里,谷歌设计了这样一个组件,叫Intent,它表示一个意图,目的,意向,作用是实现了应用之间的交互与通讯,它不仅可以在程序内部的各个Activity之间进行跳转,还可以用于应用程序之间进行跳转,实现个各组件之间的交互。
那么在使用这个Intent(意图)进行跳转时,也分为两种方式,一种叫显示意图,一种叫隐式意图。
- 使用显示意图进行页面跳转
这种方式比较麻烦,可以用下面这种方式
- 创建显示意图对象的时候就指定激活的组件,不用传包名类名全路径,只需要传一个组件的字节码文件就可以了
Intent it = new Intent(this, Main1Activity.class);
直接调用this.startActivity(it)方法完成页面跳转。(由于Activity继承自Context,所以此处使用this方法相当爽)
- 使用隐式意图进行页面跳转
- 配置意图过滤器:给要跳转到的Activity配置intent-filter子标签。并至少配置如下标签:目的就是让某一个Activity与某一个动作关联
其中action的name属性值根据需要自己定,就是定义一个动作,其实系统已经定义了一系列的动作,比如打电话,查看等。
一定要加category标签,表示默认的附加选项,用来表现动作的类别,用来约束动作的,如果什么都不配的话一般用default即可
- 在Activity中使用如下代码进行跳转:
- Activity页面跳转时传递参数
-
- 使用Intent传递参数
- 存入数据方法一:在Intent对象中,可以放入各种数据类型。如: it.putExtra(name, value); //name必须是字符串,value可以使任意数据类型。在另外的Activity中可以通过name来取得value的值。
注意:当value的值是普通的对象时,则该对象所属类必须实现Serializable接口或Parcelable(了解)接口。
- 存入数据方法二:创建一个Bundle对象,然后调用Bundle对象的put方法来来存入数据,最后把Bundle对象存入Intent中。
- this.startActivity(it)启动新的页面。
- 在新的页面中获取数据方式一:
其中的it.getXXX类型Extra()根据前面传入的不同类型来定。
- 在新的页面中获取数据的方式二:
Bundle bundle = it.getExtras(); //获得所有的extra组成的Bundle对象
调用bundle对象的各种get方法来获得数据。
Tips:bundle对象可以理解成一个Map集合。
不建议使用静态成员传值,由于 Android 具有相应的生命周期的特征,使用static 变量很可能会导致bug。另外static本身依赖进程模型,而Android力图屏蔽进程的细节。
注意:上面的任何一种存入数据的方法,都可以通过任何一种取出数据的方法来取。
- 使用startActivityForResult(意图,请求码) 跳转页面
- 当从A跳转到B,B关闭的时候需要返回数据给A的时候可以使用该方法来进行跳转。在A中覆写onActivityResult方法来接受从B传来的参数,然后在对返回的参数进行处理。
在B中通过调用如下方法就可以在Activity关闭的时候把参数传回给A。
其中finish()方法即是关闭当前Activity。注意:传递数据仍然需要通过Intent来传递。
- Activity的三种状态
在安卓中,Activity拥有三个基本状态:
- Resumed,一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
- Paused,当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态,此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。
- Stoped,当Activity被另外一个Activity完全覆盖,失去焦点并不可见时处于Stoped状态。
- Activity的生命周期
①当用户接一个电话或切换到另一个程序不会崩溃
②当用户后台运行程序时不会销毁有价值的系统资源
③当用户离开再返回你的应用时不会丢失用户的进程
④当手机屏幕进行横竖屏切换的时候不会崩溃或者丢掉用户的进程
生命周期的七个方法:
另外一些有用的方法:
- onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前 Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前 Activity。以上几种情况都会调用onWindowFocusChanged,并且当Activity被创建时是在onResume之后被调用,当 Activity被覆盖或者退居后台或者当前Activity退出时,它是在onPause之后被调用
- onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足然后将其杀死,此方法会被调用;(2)在用户改变 屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。第一 种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此 方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。onSaveInstanceState的调用 顺序是在onStop之前,无法保证是在onPause之前还是之后
- onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此 Activity,此方法会被调用;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。 onRestoreInstanceState的调用顺序是在onStart之后和onResume之前。
一、为什么要做现场保护:
1、Activity在生命周期中的Paused状态或Stoped状态下,内存空间紧张的时,系统很可能会干掉Activity,如果用户通过导航再返回刚被干掉的Activity,系统只能创建新的Activity,如果之前的Activity界面已有用户录入信息,如用户名和密码等,而在新的Activity中则没有了,这种时间就需要做现场保护
2、横屏与竖屏切换时,生命周期变化如下:
onPause()->onStop()->onDestroy()->onCreate()->onStart()->onResume()
如果当前窗口中已录入部分信息,而用户不小心切换横竖屏,此时需要做现场保护。
二、调用时机,如下图所示:
/*
* (1)在Activity被覆盖或退居后台之后,系统资源不足然后将其杀死,此方法会被调用;
* (2)在用户改变 屏幕方向时,此方法会被调用;
* (3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。
* 第一 种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;
* 第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此 方法时,我们可以保存一些临时数据;
* 第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。
* onSaveInstanceState的调用 顺序是在onStop之前,无法保证是在onPause之前还是之后
*
*/
protected void onSaveInstanceState(Bundle outState)
/*
/*
* (1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此 Activity,此方法会被调用;
* (2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。
* onRestoreInstanceState的调用顺序是在onStart之后和onResume之前。
*/
protected void onRestoreInstanceState(Bundle savedInstanceState)