关于activity的生命周期:要知道的知识点
1.每个生命活动执行的顺序、
2.每个生命周期我们应该做怎么样的处理:每个方法保留的时间有多久;那个方法是活动阻塞的,他没有做完,别的人做不了;那个方法让我们暂时回收内存,避免内存泄露等等
3.我们怎么强制性关闭activity
4.生命周期的设计模式,(模板方法模式),我们可以重写他的每个活动的方法
1.执行顺序
这种顺序已经很熟悉了,网上有人也对这个生命周期进行了另外的解说:分为可见和不可见,运行状态来区分生命周期,
1、entire lifetime (整个生命周期)
一个Activity整个生命周期,存在于onCreate()方法和onDestroy()调用之间。你的Activity应该在onCreate()方法里执行设置“全局”状态(如定义布局)。并在onDestroy()方法里释放所有剩余资源。例如,如果你的活动有一个线程在后台运行下载网络数据,它可以在onCreate()中创建该线程【一般在onStart里面创建更好子线程,主要是onCreate()只有5秒的响应时间】,然后在onDestroy()中停止线程。
2、visible lifetime(可见生命周期)
一个Activity可见生命周期,存在于onStart()和onStop()调用之间。在此期间,用户可以看到屏幕上的activity并与之交互。当一个其他的Activity启动,并且这个Activity完全不可见的时候,onStop()方法就会被调用。在这两个方法,你可以保持该Activity需要展示给用户的资源。例如,您可以在onStart()方法里注册一个BroadcastReceiver来监控你的UI的变化,并在onStop()方法里注销它。在整个生命周期的活动中,系统可能会调用onStart()和onStop()多次,因为活动之间交替进行隐藏或显示给用户。
3、 foreground lifetime(前台生命周期)
一个Activity前台生命周期,存在于onResume()和onPause()调用之间。在这段时间里,这个Activity在其他所有Activity的前面,拥有用户输入焦点。一个Activity可以经常在前台状态发生转换—比如,当设备休眠或者弹出了个对话框。因为经常会发生转换,所以在这两个方法之间的代码应该是轻量级的,防止导致其他转换变慢使得用户需要等待。
一个Activity本质上只有三种状态:
Resumed(运行)、Paused(暂停)、Stopped(停止),因为从Activity被创建之后,它只可能在这三种状态保持长久的停留,其他的回调方法结束后的状态都只能称之为过渡状态。比如进入到onStart方法后,执行完该方法,会立即进入到OnResume方法。(这里所说的状态都是指对应的某个方法返回之后)
即使一个Activity进入到Paused或者Stopped方法,它仍然是存在的,被保存在任务返回堆栈中。它仍然保持着自身的所有实例和状态,所以根本不用担心它在返回到onResume方法时,实例会变为null,或者控件的事件监听不了(我以前就担心过这个问题)。唯一需要考虑的就是,系统在内存不足的情况下,杀死在Paused或者Stopped状态下的Activity。
当一个Activity在Resumed状态下,它是不会因内存不够而被系统直接杀死(在极端的情况下也有可能被杀死,但是一般不会考虑这种情况)。只有进入Paused或者Stopped状态才会,而且可能根本就不会去调用onStop()和onDestory()方法,所以onPause()方法是我们最大程度上保证Activity在销毁之前能够执行到的方法。【这也就导致了我们可以在onPause()方法里面用isFinshing()方法来判断activity还在不在,onPause方法是Activity创建后最有可能保证执行的方法】因此,如果你的某个Activity需要保存某些数据到数据库,您应该在onPause()里编写持久化数据的代码。但要注意,你应该选择哪些信息必须保留在onPause(),因为这个方法任何阻塞程序都会阻止过渡到下一个Activity,这样给用户体验就感觉十分缓慢。【这个里面一定不能太耗时,否则会阻塞,影响用户体验,onPause里面保存的数据是可能保存到硬盘去的,因为他是用bundle进行管理的,bundle是由系统来管理的】
关于视图可见的问题:
onPause() 执行之后,如果是跳转到另外一个activity,比如是A跳到B,A执行onPause(),然后就执行B的onCreate(),onStart(),onResume(),最后才执行A的onStop(),从这个流程看来,onPause其实是可见不可触发的一种状态,就是界面还是有的,但是用户无法点击了,然后去执行B的创建过程,显示视图了,A就转到后台生命周期里面去了,
onResume是视图可见可操作的,
onCreate()方法是不可见也不可以操作,还要注意一点,View的绘制过程是在onCreate执行完之后,
onStart()方法是可见但是不可以操作
finish方法的问题:
当你在onClick事件里面写 startacitivity的时候,在前面执行finish方法和在后面执行finish方法,他们影响不大,因为他们都是异步的过程
他会把所有的异步代码全部执行了,然后再去执行startActivity():onpause,另一个activity的创建过程,然后是onstop,ondestroy(),
并且startActivity先于finish解除阻塞
2.在各个生命周期中,我们能做些什么事
回调方法的作用,就是通知我们Activity生命周期的改变,然后我们可以处理这种改变,以便程序不会崩溃或者数据丢失等等,也就是拥有更好的用户体检,那么这么多回调方法里到底应该怎么做呢?
这个问题不好总结,因为不同的应用、不同的Activity所干的事都不一样,有时候我们甚至只需要实现一个onCreate就行了。所以下面所说的,看看即可,不一定符合所有的情况。
1、onCreate
最重要是在里面调用setContentView,还可以在里面初始化各控件、设置监听、并初始化一些全局的变量。
因为在Activity的一次生命周期中,onCreate方法只会执行一次。在Paused和Stopped状态下恢复或重启的下,这些控件、监听和全局变量也不会丢失。即便是内存不足,被回收了,再次Recreate的话,又是一次新的生命周期的开始,又会执行onCreate方法。
还可以在onCreate执行数据操作,比如从Cursor中检索数据等等,但是如果你每次进入这个Activity都可能需要更新数据,那么最好放在onStart里面。(这个需要根据实际情况来确定)
2、onDestory
确定某些资源是否没有被释放,做一些最终的清理工作,比如在这个Activity的onCreate中开启的某个线程,那么就要在onDestory中确定它是否结束了,如果没有,就结束它。
3、onStart和onRestart、onStop
Activity进入到Stopped状态之后,它极有可能被系统所回收,在某些极端情况下,系统可能是直接杀死应用程序的进程,而不是调用onDestory方法,所以我们需要在onStop方法中尽可能的释放那些用户暂时不需要使用的资源,防止内存泄露。
尽管onPause在onStop之前执行,但是onPause只适合做一些轻量级的操作,更多的耗时耗资源的操作还是要放在onStop里面,比如说对数据保存,需要用到的数据库操作。
因为从Stopped状态重启之后, onStart和onRestart方法都会被执行,所以我们要判断哪些操作分别要放在哪个方法里面 。因为可能在onStop方法里面释放了一些资源,那么我们必须要重启他们,这个时候这些重启的操作放在onStart方法里面就比较好(因为onCreate之后也需要开启这些资源)。那些因为Stopped之后引发的需要单独操作的代码,就可以放在onRestart里面。
4、onResume和onPause
onPause和onResume中做的操作,其实意义上和onStart和inStop差不多,只不过是要更轻量级的,因为onPause不能阻塞转变到下一个Activity。
比如:停止动画、取消broadcast receivers。当然相应的需要在onResume中重启或初始化等等。
有时候也需要在onPause判断用户是调用finish结束这个Activity,还是暂时离开,以便区分处理。这时候可以调用isFinishing()方法来判断。如果是用户finish这个Activity,那么返回为true,如果只是暂时离开或者被系统回收的话,就返回false。
3.如何强制性关闭一个activity
Android下结束进程的方法 一、结束一个活动Activity 要主动的结束一个活动Activity,使用finish方法,而且这个方法最后会调用Activity的生命周期函数onDestroy方法,结束当前的Activity,从任务栈中弹出当前的Activity,激活下一个Activity。 二、强制结束当前的进程 强行结束当前进程有两个方法。 1、killProcess(int pid) 例子:android.os.Process.killProcess(android.os.Process.myPid()); 这个方法使用是有条件的: a、将被杀掉的进程 和 当前进程 处于同一个包或者应用程序中;android:process b、将被杀掉的进程 是由当前应用程序所创建的附加进程; c、将被杀掉的进程 和 当前进程 共享了普通用户的UID。(这里的普通用户,是相对于Root权限的用户来说的)android:shareuserid 2、System.exit(int code) 例子:System.exit(0); 该方法只能用于结束当前进程自身,在程序遇到异常,无法正常执行时,可以通过这个方法强制退出。需要把异常捕获到 需要注意的是,这两个方法,会导致进程非正常退出,就是说,进程退出时不会去执行onPause、onStop和onDestroy方法,那么进程很有可能错过了保存数据的机会。因此,这两个方法最好使用在出现异常的时候! 三、结束另一个进程 要通过一个进程去结束另一个进程。在之前的SDK版本中,一直使用方法restartPackage(packageName)方法,但是在Android的开发文档中介绍说,这个函数会导致一些问题( the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc.),所以建议大家使用一个新的方法: void killBackgroundProcesses(String packageName) 由于这个方法没有返回值,所以我们也不知道我们的目标进程是否真的退出了。但是,我目前只发现了这个可以结束另一个进程的方法。 四、退出到主屏幕 这个方法,也是退出当前进程的一个方法。如果我们在进程中创建了很多的Activity,但是又不想关闭时去退出不在任务栈顶的Activity,那么就可以直接使用这个方法了。
mHomeIntent = new Intent(Intent.ACTION_MAIN, null); mHomeIntent.addCategory(Intent.CATEGORY_HOME); mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
4.activity的模板方法模式,请看前面的文章