`
haric
  • 浏览: 117696 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android教程(2.1) Activity的详细讲解

阅读更多

  作者微博  http://www.weibo.com/haric

Activity 是我们开发Android应用程序最重要的一个类。这个类的内容比较多,我理解多少
就写多少,希望你喜欢:)

这篇文章会涉及到以下几个内容

一 Activity的生命周期
二 让Activity变成一个窗口:Activity属性设定
三 你后台的Activity被系统回收怎么办:onSaveInstanceState
四 调用与被调用:我们的通信使者 - Intent


一 Activity的生命周期

   和其他手机平台的应用程序一样,Android的应用程序的生命周期是被统一掌控 的,也
   就是说我们写的应用程序命运掌握在别人(系统)的手里,我们不能改变它,只能学习并
   适应它。
  
   简单地说一下为什么是这样:我们手机在运行一个应用程序的时候,有可能打进来电话
   发进来短信,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能,另
   外系统也不允许你占用太多资源,至少要保证电话功能吧,所以资源不足的时候也就有可 

   能被干掉。

   言归正传,Activity的基本生命周期如下代码所示:

 public class MyActivity extends Activity {
     protected void onCreate(Bundle savedInstanceState);

     protected void onStart();

     protected void onResume();

     protected void onPause();

     protected void onStop();

     protected void onDestroy();
   } 

 

   你自己写的Activity会按需要 重载这些方法,onCreate是免不了的,在一个Activity正常启动的过程中,他们被调用的顺序是 onCreate -> onStart -> onResume, 在Activity被干掉的时候顺序是onPause -> onStop -> onDestroy ,这样就是一个完整的生命周期,但是有人问了 ,程序正运行着呢来电话了,这个程序咋办?中止了呗,如果中止的时候新出的一个Activity是全屏的那么:onPause->onStop ,恢复的时候onStart->onResume ,如果打断  这个应用程序的是一个Theme为Translucent 或者Dialog 的Activity那么只是onPause ,恢复 的时候onResume

   详细介绍一下这几个方法中系统在做什么以及我们应该做什么:

   onCreate:    在这里创建界面,做一些数据的初始化工作

   onStart:   到这一步变成用户可见不可交互

   onResume:   变成和用户可交互 的,(在activity栈系统通过栈的方式管理这些个      
                      Activity的最上面,运行完弹出栈,则回到上一个Activity)

   onPause:     到这一步是可见但不可交互 的,系统会停止动画等消耗CPU 的事情
                    从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候
                    你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在

                    onResume里读出来,注意:这个方法里做的事情时间要短,因为下一
                    个activity不会等到这个方法完成才启动

   onstop:      变得不可见 ,被下一个activity覆盖了

   onDestroy:  这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方
                     法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判
                     断它,如果你有一个Progress Dialog在线程中转动,请在onDestroy里
                     把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛
                    
的。                    
             
onPause,onstop, onDestroy,三种状态下 activity都有可能被系统干掉
为了保证程序的正确性,你要在onPause()里写上持久层操作的代码,将用户编辑的内容都保存到存储介质上(一般都是数据库)。实际工作中因为生命周期的变化而带来的问题也很多,比如你的应用程序起了新的线程在跑,这时候中断了,你还要去维护那个线程,是暂停还是杀掉还是数据回滚,是吧?因为Activity可能被杀掉,所以线程中使用的变量和一些界面元素就千万要注意了,一般我都是采用Android的消息机制[Handler, Message]来处理多线程和界面交互的问题。这个我后面会讲一些,最近因为这些东西头已经很大了,等我理清思绪再跟大家分享。

二 让Activity变成一个窗口:Activity属性设定
   
   讲点轻松的吧,可能有人希望做出来的应用程序是一个漂浮在手机主界面的东西,那么很
简单你只需要设置一下Activity的主题就可以了在AndroidManifest.xml 中定义Activity的
地方一句话:

android:theme="@android:style/Theme.Dialog"
 

  这就使你的应用程序变成对话框的形式弹出来了,或者

android:theme="@android:style/Theme.Translucent"
 

就变成半透明的,[友情提示-.-]类似的这种activity的属性可以在android.R.styleable 类的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的属性的介绍都可以参考这个类android.R.styleable

上面说的是属性名称,具体有什么值是在android.R.style中 可以看到,比如这个"@android:style/Theme.Dialog" 就对应于android.R.style.Theme_Dialog ,('_'换成'.' <--注意:这个是文章内容不是笑脸)就可以用在描述文件中了,找找类定义和描述文件中的对应关系就都明白了。


三 你后台的Activity被系统回收怎么办:onSaveInstanceState
  
   当你的程序中某一个Activity A 在运行时中,主动或被动地运行另一个新的Activity B
这个时候A会执行

public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putLong("id", 1234567890);
}

 
B 完成以后又会来找A, 这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回
收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数
savedInstanceState,没被收回的就还是onResume就好了。

savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。

if(savedInstanceState != null){
     long id = savedInstanceState.getLong("id");
}

 
就像官方的Notepad教程里的情况,你正在编辑某一个note,突然被中断,那么就把这个note的id记住,再起来的时候就可以根据这个id去把那个note取出来,程序就完整一些。这也是看你的应用需不需要保存什么,比如你的界面就是读取一个列表,那就不需要特殊记住什么,哦, 没准你需要记住滚动条的位置...

四 调用与被调用:我们的通信使者Intent

要说Intent了,Intent就是这个这个意图 ,应用程序间Intent进行交流,打个电话啦,来个
电话啦都会发Intent, 这个是Android架构的松耦合的精髓部分,大大提高了组件的复用性,比如你要在你的应用程序中点击按钮,给某人打电话,很简单啊,看下代码先:

 Intent intent = new Intent();
 intent.setAction(Intent.ACTION_CALL);
 intent.setData(Uri.parse("tel:" + number));
 startActivity(intent);

 

扔出这样一个意图,系统看到了你的意图就唤醒了电话拨号程序,打出来电话。什么读联系人,发短信啊,邮件啊,统统只需要扔出intent就好了,这个部分设计地确实很好啊。

那Intent通过什么来告诉系统需要谁来接受他呢?
通常使用Intent有两种方法,第一种是直接说明需要哪一个类来接收代码如下:

Intent intent = new Intent(this, MyActivity.class);
intent.getExtras().putString("id", "1");
tartActivity(intent);


第一种方式很明显,直接指定了MyActivity为接受者,并且传了一些数据给MyActivity,在MyActivity里可以用getIntent()来的到这个intent和数据。

第二种就需要先看一下AndroidMenifest中的intentfilter的配置了

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:value="android.intent.action.EDIT" />
    <action android:value="android.intent.action.PICK" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
 

这里面配置用到了action, data, category这些东西,那么聪明的你一定想到intent里也会有这些东西,然后一匹配不就找到接收者了吗?

action其实就是一个意图的字符串名称。
上面这段intent-filter的配置文件说明了这个Activity可以接受不同的Action,当然相应的程序逻辑也不一样咯,提一下那个mimeType,他是在ContentProvider里定义的,你要是自己实现一个ContentProvider就知道了,必须指定mimeType才能让数据被别人使用。

不知道原理说明白没,总结一句,就是你调用别的界面不是直接new那个界面,而是通过扔出一个intent,让系统帮你去调用那个界面,这样就多么松藕合啊,而且符合了生命周期被系统管理的原则。

想知道category都有啥,Android为你预先定制好的action都有啥等等,请亲自访问官方链接Intent

ps:想知道怎么调用系统应用程序的同学,可以仔细看一下你的logcat,每次运行一个程序的时候是不是有一些信息比如:
Starting activity: Intent { action=android.intent.action.MAIN categories={android.intent.category.LAUNCHER} flags=0x10200000 comp={com.android.camera/com.android.camera.GalleryPicker} }
再对照一下Intent的一些set方法,就知道怎么调用咯,希望你喜欢:)

52
2
分享到:
评论
6 楼 lordhong 2009-09-08  
  写得不错
5 楼 gogole_09 2009-08-19  
谢谢分享,写得很通俗易懂,适合我们这样的入门级人员。
4 楼 wuhua 2009-02-20  
写的不错,收藏了,作为一个参考的文档
3 楼 java-admin 2009-02-06  
写的很好! 可以加我的qq吗,大侠!~~ 我的qq 498305889
2 楼 haric 2008-12-12  
skycode 写道

问个问题哈,如果A被系统回收了,请问A有没有被Destroy掉。
如果被Destroy掉了,那么B是如何再次转到A的?还是通过Intent吗?这个时候B的setResult是不是就对A没有作用了啊?
以上,谢谢

如果A被系统收回了,肯定是执行onDestroy方法了,但是这个时候,因为生命周期还是被
系统所管理的,系统帮你新建了一个A的实例调用了onCrearte方法,并且附上Bundle参数,至于setResult我没有实验过,我觉得他应该是不生效了,因为事实上再回到A的时候A已经是一个新的实例了,不知道我理解地对不对:)
1 楼 skycode 2008-12-12  
问个问题哈,如果A被系统回收了,请问A有没有被Destroy掉。
如果被Destroy掉了,那么B是如何再次转到A的?还是通过Intent吗?这个时候B的setResult是不是就对A没有作用了啊?
以上,谢谢

相关推荐

    Android Fragment超详细教程

    二、Android Fragment 示例讲解一 2.1 创建 Fragment 2.2 Fragment 管理 2.3 Fragment 与 Activity 通讯 2.4 Fragment 示例 三、Android Fragment 示例讲解二 3.1 项目的效果图 3.2 项目结构图与内容分析...

    Android开发案例驱动教程 配套代码

    《Android开发案例驱动教程》 配套代码。 注: 由于第12,13,14章代码太大,无法上传到一个包中。 这三节代码会放到其他压缩包中。 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式...

    Android应用开发详解pdf.pdf

    目录回到顶部↑ 第一篇 基础篇 第1章 android概述 2 1.1 android的前世今生 3... 第7章 Android Service组件Android Service组件,讲述了Android中的后台服务Service的概念、创建和使用,并详细讲解了远程服务的调用

    Android编程入门很简单.(清华出版.王勇).part1

    本书避免出现云山雾罩、晦涩难懂的讲解,代之以轻松活泼、由浅入深的剖析。这必将使得阅读本书的读者少走弯路,快速上手,从而建立学习Android开发的信心。本书配带1张光盘,收录了重点内容的教学视频(8.7小时多媒体...

    深入理解Android:卷I--详细书签版

    第2章通过对android系统中的mediascanner进行分析,详细讲解了 android中十分重要的jni技术;第3章分析了init进程,揭示了通过解析init.rc来启动zygote以及属性服务的工作原理;第4章分析了zygote、systemserver等...

    android开发入门与实战(下)

    9.1.3 Intent详细讲解 9.1.4 Android解析Intent实现 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 9.2.1 实现Android中的广播事件 9.2.2 BroadCastReceiver介绍 9.3 应用实例详解 9.3.1 程序操作演示 9.3.2...

    Android Fragment从零开始

    二、Android Fragment示例讲解一 2.1 创建Fragment 2.2 Fragment 管理 2.3 Fragment 与Activity 通讯 2.4 Fragment 示例 三、Android Fragment示例讲解二 3.1 项目的效果图 3.2 项目结构图与内容分析 3.4 ...

    《Google Android开发入门与实战》.pdf

    2.1 开发android应用前的准备 7 2.1.1 android开发系统要求 7 2.1.2 android软件开发包 7 .2.1.3 其他注意事项 8 2.2 windows开发环境搭建 8 2.2.1 jdk、eclipse、android sdk软件安装 8 2.2.2 ...

    android开发入门与实战(上)

    9.1.3 Intent详细讲解 9.1.4 Android解析Intent实现 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 9.2.1 实现Android中的广播事件 9.2.2 BroadCastReceiver介绍 9.3 应用实例详解 9.3.1 程序操作演示 9.3.2...

    Android应用开发揭秘pdf高清版

    《Android应用开发揭秘》内容全面,不仅详细讲解了Android框架、Android组件、用户界面开发、游戏开发、数据存储、多媒体开发和网络开发等基础知识,而且还深入阐述了传感器、语音识别、桌面组件开发、Android游戏...

    Google.Android开发入门与实战

    2.1 开发Android应用前的准备 2.1.1 Android开发系统要求 2.1.2 Android软件开发包 2.1.3 其他注意事项 2.2 Windows开发环境搭建 2.2.1 JDK、Eclipse、AndroidSDK软件安装 2.2.2 SDK的家在哪里——设定...

    Android高级编程--源代码

    在每章的讲解中,它会让你通过一系列示例项目逐步掌握Android中的各种新功能和技术,助你取得最圆满的学习效果。本书所介绍的各个应用实例简明扼要且极具实用价值,它们覆盖了Android 1.0的所有基本功能和高级功能...

    Android launcher应用讲解

    Launcher即启动器,也就是home,一般叫桌面,即 home screen。 Launcher的代码位于packages/apps/Launcher目录及Launcher2目录。...只要在manifest中Activity具备这样的intent-filter都可以在开机的时候作为Home启动

    Android编程入门很简单.(清华出版.王勇).part2

    本书避免出现云山雾罩、晦涩难懂的讲解,代之以轻松活泼、由浅入深的剖析。这必将使得阅读本书的读者少走弯路,快速上手,从而建立学习Android开发的信心。本书配带1张光盘,收录了重点内容的教学视频(8.7小时多媒体...

    Android实训报告.doc

    二、设计思路 2.1设计题目 以Android系统的UI界面开发为基础,设计一个可以简单计算标准体重的应用程序, 要求以2个Acitivity实现,第一个Activity作为输入界面,第二个Activity作为结果输 出界面,具体实现细节...

    Google Android开发入门与实战的代码

    9.1.3 Intent 详细讲解 177 9.1.4 Android解析Intent实现 179 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 180 9.2.1 实现Android中的广播事件 180 9.2.2 BroadCast Receiver介绍 181 9.3...

    Android实训报告(2).doc

    二、设计思路 2.1设计题目 以Android系统的UI界面开发为基础,设计一个可以简单计算标准体重的应用程序, 要求以2个Acitivity实现,第一个Activity作为输入界面,第二个Activity作为结果输 出界面,具体实现细节...

    Android之listfragment的使用例子

    简单的例子,新建一个最基本的Android空白界面,我们得到的是一个可以显示一个空白界面的app。一个activity对应着一个layout。 但是fragment则是基于activity,突破了已经固定好的layout的限制,在原有的layout中...

Global site tag (gtag.js) - Google Analytics