您的位置:首页 > 移动开发 > Android开发

Android 四大组件之Activity 基础总结(1)

2016-03-30 17:16 645 查看
Activity 是我们在学习android 的时候最先接触到的东西,也是android 开发过程中不可少的组件。而 在我们android 学习中,对activity 有个全面的认识是很重要的。本人在学习android 以来,对activity 也是又爱又恨,所以特意做了个总结,希望能对 那些 activity 认识还不够的“同鞋”一些帮助。内容提要1、Activity 的概念2、Activity 类继承关系3、Activity 的生命周期4、Activity 横竖屏切换时生命周期变化5、Activity 启动模式6、Activity 之间通信数据传递7、Activity 的回收与数据保存内容详情1、Activity 的概念 在谷歌给的官方Android Api文档中,是这么描述 Activity中的:一个 activity 是一个单一的,聚焦了用户可以做的事情。几乎所有的 activity 都与用户进行交互,因此 activity 需要关注创建一个窗口,可以通过 setContentView(int) 来更新替换 UI 视图界面。activity 往往是以全屏方式呈现给用户的,你也可以通过设置主题或将activity嵌入其他activity 的方式来改变。2、Activity 类继承关系 通过这张类图,我们可以看到,activity 是继承于 ContenttextThemeWrapper 类的,是它的直接也是唯一子类。而activity 的直接子类 则有ActivityGroup、AliasActiviyt、ExpandableListActivity和 ListActivity,其中常用的有 ListActivity (后面再讲List 相关用法时,会讲下ListActivity的相关用法)。3、Activity 的生命周期 相信这张图你已经见过很多次了吧,经典永远是值得学习的。下面我们就来好好学习下经典。所有的 activity 都会实现两个方法:onCreate() 和 onPause()方法。下面就来具体讲讲图中的各个方法详情和都在什么情况下调用:onCreate: 在这里创建界面,做一些数据的初始化工作onStart: 到这一步变成用户可见不可交互的onResume: 变成和用户可交互的,(在activity 栈系统通过栈的方式管理这些个Activity的最上面,运行完弹出栈,则回到上一个Activity)onPause: 到这一步是可见但不可交互的,系统会停止动画等消耗CPU 的事情从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在onResume里读出来,注意:这个方法里做的事情时间要短,因为下一个activity不会等到这个方法完成才启动onstop: 变得不可见,被下一个activity覆盖了onDestroy: 这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方 法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有一个ProgressDialog在线程中转动,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛异常的。注:onPause,onstop, onDestroy,三种状态下 activity都有可能被系统干掉。正常启动activity:onCreate-> onStart -> onResume(启动)正常退出activity: (启动)-> onPause-> onStop -> onDestroy(退出)activity 启动后被打断,进入一个新全屏activity:(启动)-> onPause->onStop恢复时:onStart->onResumeactivity 启动后被打断,进入一个不是全屏的窗口,如Dialog之类的:(启动)-> onPause恢复时:onResume4、Activity 横竖屏切换时生命周期变化在android 程序清单中声明activity 时我们可以设置 activity在横竖屏切换时的生命周期变化,具体情况如下:不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。设置Activity的android:configChanges="orientation"时,切横,竖屏时生命周期只会执行一次。设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用声明周期,只会执行onConfigurationChanged方法。5、Activity 启动模式我们知道在继承一个activity类时,当我们要将自己写的 activity启动的时候,我们需要在 androidManifest.xml 程序清单里面,声明所要启动的 activity,而在声明 activity 的同时 我们可以设置activity 的启动模式,launchModel = "...",在android 系统中 ,activity 有四种启动模式,而系统默认是 standard,启动模式在某些需求的情况下可以方便系统 对activity 的管理。下面说解讲下四种启动模式的各自的特点和区别:standard:默认模式,可以不用写配置。activity在同一个任务栈,每启动一个activity,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。singleTop:activity在同一个任务栈,当要启动的activity处于栈顶时,重复启动之前已创建的实例;当要启动的activity 不处于栈顶时,会创建新的实例singleTask:activity在同一个任务栈,只在一个实例,若创建了将不重复创建;在启动已在栈里面有的activity时(由栈顶的activity(B) 跳转到下面的 activity (A)时),会将在A上面的activity 一直弹出,一直到A。singleInstance:每个activity是独立任务栈,且只放一个activity实例, activity的之间的切换会在几个不同任务栈之间跳转。6、Activity 之间通信数据传递在平常的android 开发过程中, 很多活动界面之前是需要传递数据的,也就是说在activity之间是需要传递数据,而数据怎么传递,传递什么样的数据,这些都要有一定的了解。下面详细介绍:1、简单数据采用 Intent 来传递A->BA中 绑定数据:Intent intent = new Intent( this, MyReceiver.class);intent.putExtra( "data", "data from A");StartActivity(intent);B中 接收数据:String data = intent.getStringExtra( "data");2、数据包采用Bunde 来传递A->BA中 绑定数据:Bundle b = new Bundle();b.putString("string","String data from A");b.putInt("int","Int data from A");b.putBoolean("boolean","Boolean data from A");Intent intent = new Intent( this, MyReceiver.class);intent.putExtra("datas",b);//intent.putExtra(b);B中接收数据:Bundle b = getIntent.getExtras("datas")//b = getIntent().getExtras();String datastr = b.getString("string","default");//default为缺省值3、对象的传递A->B ,class User (name,age)1》Serializable java语言提供 ,效率较低User中:继承Serializable , class User implements SerializableA中: intent.putExtra("user",new User());B中: User user = (User)getIntent().getSerializableExtra("user");2》Parcelable 专门面向移动端,效率较高User中:继承Parcelabe , class User implements Parcelable实现两方法:public int describeContents(){return 0}public void writeToParcel(Parcel dest, int flags){dest.writeBundle()//这样可以传递很多相同类型数据了dest.writeString(getName());dest.writeInt(getAge());}public static final Creator<User> CREATOR = new Creator<User>(){public User createFromParcel(Parcel source){source.readBundle();//return new User(source.readString(),source.readInt());}public User[] newArray(int size){return new User[size ];}}A中: intent.putExtra("user",new User());B中: User user = (User)getIntent().getParcelableExtra("user");3、从被启动的activity 传递数据到 主activity(返回传递数据)A->B,B->AB中:返回时监听:String bData;Intent intent = new Intent();intent.putExtra("dataB",bData );setResult(1,intent);//返回状态码可以自行设定finish();A中:在启动时:startActivityForResult(intent, 0);//返回的请求码实现方法:onActivityResult(int requestCode,int resultCode,Intent data)onActivityResult(int requestCode,int resultCode,Intent data){if(requestCode == 0){if(resultCode == 1)String s = data.getStrignExtra("dataB");}}4、还有一种懒汉方法来传递数据,进行通信如设置一个公共类,在公共类中,将要传递的数据声明为 公有静态的(public static ),这样就可以在直接在activity之间进行通信了。当然这种数据也可以放在 application 这个全局的 类里面。这种方法通常是用来判断 是否登陆超时,或是一些全局的配置等等。7、Activity 的回收与数据保存之前在讲解 activity 生命周期的时候,我们就已经知道了,activity 在某些情况下会被系统干掉的,如果这个activity 又在做一些重要的数据,举一个简单的例子, 我们在登录一个时,只填写了一部分,临时离开了这个界面,当我们返回时,如果又需要重新在填写全部的数据,这是不是有点坑,,,严重影响用户体验。当然这只是举的一个小例子,或许有点不恰当,但我们确实是需要在系统回收 activity ,activity被异常干掉的时候保存当前的用户数据 ,而在再次打开或恢复时,应当能还原当初的数据。因为 activity 的切换,所以当用户在再次切换回原来的 activity的时候,原先的 activity 有两种情况:一种是被回收,一种是没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数savedInstanceState,没被收回的就还是onResume就好了。savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。前面在生命周期也讲过,我们可以在onPause 方法中 保存数据,而在 onResume 方法中恢复数据。其实谷歌早就考虑到了关于 activity 异常退出,被系统回收的 的 数据 保存与恢复相关的问题。那就是这两个方法: onSaveInstanceState(Bundle outState) 和 onRestoreInstanceState(Bundle savedInstanceState) 方法,这两个 前者是负责在activity被异常干掉之前保存数据,而后者是负责恢复数据。注:onSaveInstanceState()方法,在正常情况下就不会被调用的,只有当 activity 发生异常时才会被调用。onRestoreInstanceState()方法,系统会调用,其实也是不需要我们人为去干涉的。我们接着看,注意 onSaveInstanceState(Bundle outState )方法的参数,是的,是 Bundle 类型的,还记得前面提到过的 数据传递部分吗,Bundld 就可以保存大多数的数据。 现在或许有人说 onRestoreInstanceState() 方法我们可以不去多管,总感觉心里不踏实,是吧,那我们在哪个地方 将 outState 里面保存的数据拿出来呢?我们再看看 onCreate(Bundle savedInstanceState) ,是不是发现什么了,这个参数,也是Bundle 类型的,其实这里的 savedInstanceState 就是之前保存的 outState,而我们可以在onCreate 方法中取消之前 保存的数据。最后问的归纳如下:保存数据:
void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id",1234567890);
}
判断 和 恢复 数据:
void onCreate(Bundle savedInstanceState){
..........

if(savedInstanceState != null){
.....
}
}
好了,到这里我们对 activity 已经有了个大概的理解了,而博客也到这里结束了。这是 本人 第一次写的 关于 android 的文章 ,从自己学习android 以来,中间有苦有甜,有笑有泪,不容易啊,今天在我即将走出校园,即将用 android 来谋生的同时,写下这篇博客,希望能在android这条路上走得越来越宽,越来越远。注:这博客是总结型的,中间有我自己对 android api 的翻译,同样其中不免有些知识点是有和其他文章有相通的,所以如果有失礼或者是有不是很恰当的地方,还请前辈们见谅。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息