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

    Activity 是我们在学习android 的时候最先接触到的东西,也是android 开发过程中不可少的组件。而 在我们android 学习中,对activity 有个全面的认识是很重要的。本人在学习android 以来,对activity 也是又爱又恨,所以特意做了个总结,希望能对 那些 activity 认识还不够的“同鞋”一些帮助。

七星网站制作公司哪家好,找创新互联公司!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。创新互联公司自2013年起到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联公司


内容提要

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 类继承关系

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

    通过这张类图,我们可以看到,activity 是继承于 ContenttextThemeWrapper 类的,是它的直接也是唯一子类。

而activity 的直接子类 则有ActivityGroup、AliasActiviyt、ExpandableListActivity和 ListActivity,其中常用的有 ListActivity (后面再讲List 相关用法时,会讲下ListActivity的相关用法)。

3、Activity 的生命周期

    相信这张图你已经见过很多次了吧,经典永远是值得学习的。下面我们就来好好学习下经典。

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

所有的 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->onResume

activity 启动后被打断,进入一个不是全屏的窗口,如Dialog之类的:

(启动)-> onPause

恢复时:onResume

4、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->B

A中 绑定数据:

Intent intent = new Intent( this, MyReceiver.class);

intent.putExtra( "data", "data from A");

StartActivity(intent);

B中 接收数据:

String data = intent.getStringExtra( "data");

2、数据包采用Bunde 来传递

A->B

A中 绑定数据:

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 Serializable

A中: 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 CREATOR = new Creator(){

          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->A

B中:返回时监听:

     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 的翻译,同样其中不免有些知识点是有和其他文章有相通的,所以如果有失礼或者是有不是很恰当的地方,还请前辈们见谅。

 



新闻标题:Android四大组件之Activity基础总结(1)
分享URL:http://pwwzsj.com/article/iiidph.html