上一篇文章写了关于Activity生命周期和生命周期状态的介绍,这一篇文章给大家聊聊Activity生命周期函数。
应用程序的入口一般都是桌面应用程序图标,用户点击应用图标打开应用,这是因为应用程序有主Activity,如果没有主Activity,应用程序就不会在桌面中显示。主Activity在AndroidManifest.xml中的声明如下:
XHTML
<activity android : name = ".MainActivity" android : label = "@string/app_name" > <intent-filter> <action android : name = "android.intent.action.MAIN" /> <category android : name = "android.intent.category.LAUNCHER" /> </intent-filter> </activity> |
与普通Activity在AndroidManifest.xml声明的区别就是多了<action android:name="android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" />。 Activity有这两个声明才能在桌面应用程序列表中找到。
Activity的生命周期方法都会被系统回调,它们的调用时机都是什么呢?在这些方法中你需要做些什么?先看一张图,对照着图来讲解你可能理解的更明白。
图片来自google的developer官网。
onCreat方法在Activity生命周期中只会被调用一次,onCreat后Activity进入Created状态。在这个方法中主要做的工作是初始化你这个Activity需要的资源和加载UI。初始化资源一般都是你定义的变量什么的。加载UI一般都是先在xml文件中设置好布局,然后通过setContentView(layout_xml)加载到应用窗口上(可以理解为每一个应用程序的界面最外层都有一个窗口,叫做Window,所有的view都显示在这个窗口上)。实例代码如下:
TextView mTextView ; // Member variable for text view in the layout @Override public void onCreate ( Bundle savedInstanceState ) { super . onCreate ( savedInstanceState ) ; // Set the user interface layout for this Activity // The layout file is defined in the project res/layout/main_activity.xml file setContentView ( R . layout . main_activity ) ; // Initialize member TextView so we can manipulate it later mTextView = ( TextView ) findViewById ( R . id . text_message ) ; } |
onCreat方法执行完会紧接着调用到onStart方法,onStart方法后Activity进入Started状态。一般这个方法用不着,因为有其他方法可以替代它完成需要做的工作。这个方法调用完View就会变为可见状态,但是不可交互。从刚开始的图能看到onStart方法在整个生命周期中可能会被调用多次,在Activity进入Stoped状态后也可能再次经过onRestart-》onStart方法再次进入Started状态。
onStart方法执行完会紧接着调用onResume方法,走完这个方法Activity就会进入Resumed状态,此时的Activity获得了焦点,可见可交互,这个方法在生命周期中可能会多次调用,只要进入可交互状态必然会走这个方法。在进入这个方法时你需要准备好与用户交互的资源,也就是说用户要看的、要点击的UI资源都要能够快速响应用户,比如要准备好音乐播放器,用户点击播放立刻就能听到音乐。
在Activity被前台UI部分或者全部遮挡时会走onPause方法,此时Activity失去焦点,不可交互。比如弹出的对话框,或者进入其他Activity界面。在这个方法中你要处理好用户不再需要的资源,比如停止游戏,停止播放器等,并且需要保存用户现在的数据,比如游戏数据(关卡进度),播放数据(播放进度)等,但是不要进行太耗时的操作。google官网给出的建议是:
官网的例子如下:
@Override public void onPause ( ) { super . onPause ( ) ; // Always call the superclass method first // Release the Camera because we don't need it when paused // and other activities might need to use it. if ( mCamera != null ) { mCamera . release ( ) mCamera = null ; } } |
当activity的onStop方法被调用后,Activity进入Stoped状态,完全不可见,此时你需要完全释放用户不再需要的资源,尽管之前你调用了onPause方法释放了一部分资源,但是在onPause方法中你不能执行更大、更耗费CPU的方法,在onStop中使可以的。例如把数据保存到数据库:
@Override protected void onStop ( ) { super . onStop ( ) ; // Always call the superclass method first // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. ContentValues values = new ContentValues ( ) ; values . put ( NotePad . Notes . COLUMN_NAME_NOTE , getCurrentNoteText ( ) ) ; values . put ( NotePad . Notes . COLUMN_NAME_TITLE , getCurrentNoteTitle ( ) ) ; getContentResolver ( ) . update ( mUri , // The URI for the note to update. values , // The map of column names and new values to apply to them. null , // No SELECT criteria are used. null // No WHERE columns are used. ) ; } |
在Stoped状态Activity在系统资源紧张的时候会直接被系统回收掉而不再调用onDestroy方法,当然这是很极端的时候发生的。
Activity生命周期的最后一个方法,一般不会再这个方法里做什么事,应为它有可能不会被调用。大部分的清理工作是在onPause和onStop方法中做的,这个方法是完成清理工作的最后机会,一些可能会引起内存泄露的线程应该在这个方法中停掉,Hander的消息也要清理掉。
我用了两篇文章来给大家聊聊Activity的生命周期和生命周期方法,主要是理解在各个生命周期方法中该做那些事,不该做那些事,这样就能保证UI显示的正确和快速,数据会被保存,该释放的资源会被释放。如果大家有什么问题可以关注下面的公众号给我留言,大家共同讨论。
关注微信公众平台:程序员互动联盟(coder_online), 你可以 第一时间获取原创技术文章, 和(java/C/C++/Android/Windows/Linux)技术大牛做朋友, 在线交流编程经验, 获取编程基础知识, 解决编程问题。程序员互动联盟,开发人员自己的家。