Activity和Servlet一样,都用了回调机制。我们通过类比servlet来学习Activity。当一个servlet开发出来之后,该servlet运行于Web服务器中。服务器何时创建servlet的实例,何时调用servlet的方法向用户生成响应,程序员无法控制,这种回调由服务器自行决定。Activity也一样,被开发出来,开发者只要在AndroidManifest.xml文件配置该Activity即可。至于该Activity何时被实例化,它的方法何时被调用,对开发者来说完全是透明的。
当开发者开发一个Servlet时,根据不同的需求场景,可能需要选择性的的实现如下方法:
- init(servletConfig config)
- destroy()
- doGet(HttpServletRequest req,HttpServletResponse resp)
- doPost(HttpServletRequest req,HttpServletResponse resp)
- sevice(HttpServletRequest req,HttpServletResponse resp
- 当把Servlet部署到Web应用中之后,Web服务器将会在特定的时刻,调用该Servlet上面的各种方法---这种调用就被称为回调。
Activity的回到机制与此类似,当Activity被部署到Android应用之后,随着应用程序的运行,Activity会不断的在不同的状态进行切换,该activity中特定的方法就会被回调-----开发者就可以选择性的重写这些方法来加入业务相关的处理。Android运行过程的不同状态被称为生命周期。
Android的生命周期:当activity处于Android的应用中的运行时,它的活动状态由Android运行时以Activity栈的形式管理。当前活动的Activity位于栈顶。
Android的生命周期演示:android大致经过如下四个状态:
- 活动状态:当前Activity位于前台,用户可见,可以获得焦点。
- 暂停状态:其他Activity位于前台,该Activity依然可见,只是不能获得焦点。
- 停止状态:该Activity不可见,失去焦点
- 销毁装填:该activity结束,或者activity所在的Dalvik进程被结束。
下面是官方API所提供的生命周期图:
下面使用代码亲自测下Android的生命周期,测完就明白了:
package com.lp.ecjtu.activitydemo1; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.widget.EditText; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText editText; //创建Activity被回调 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.editText); Log.e(TAG, "Start onCreate ========="); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } //启动Activity被回调 @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.e(TAG, "Start onStart ========="); } //重新启动Activity被回调 @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); Log.e(TAG, "Start onRestart ========="); } //恢复Activty被回调 @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.e(TAG, "Start onResume ========="); } //暂停Activity被回调 @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); Log.e(TAG, "start onPause============="); } //停止Activity被回调 @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.e(TAG, "start onStop============="); } //销毁Activity被回调 @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.e(TAG, "start onDestroy============="); } }
运行上面的代码:我们打开应用程序时回调了OnCreate()-->onStart()-->onResume()方法。在LogCat窗口可以看到:
Back键:当我们按返回键的时候这个应用程序或者Activity将结束,依次回调了OnPause()-->onStop()-->Ondestroy()方法:在LogCat窗口可以看到:
HOME键:当我们正在打游戏的时候,突然来了条短信,我们想看短息,按HOME键,然后打开短信的应用,当我们按HOME键的时候Activity先后执行了OnPause()-->OnStop方法,在LogCat窗口可以看到:
而我们看完短息在启动应用的时候:会执行OnRestart()-->onStart-->OnResume方法。在LogCat窗口可以看到:
通过上面的操作,想必我们都对Android Activity生命周期有了深刻的了解,我们就可以在开发Activity的时候,选择性的重写生命周期的方法来解决业务上的一些需求。
例如:下面的这个例子,当我们在看视屏的时候,或者在注册的时候,刚好填完用户的注册信息,不小心按到了Home键,当我们在进入应用程序的时候,发现之前填的注册信息全没了,这时候我们就要哭了,说明这个应用程序做的比较垃圾。正常情况下,我们之前填写的注册信息还在,也就是说和我们按Home键之前的状态是一致的。
为了理解,我们用一个小例子说明问题:
在XML代码代码中增加EditText:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_Activity" /> <EditText android:id="@+id/editText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" /> </LinearLayout>
java代码不变,运行程序,在EditText中输入peter,
然后按HOME键,在次启动MainActivity,发现之前输入的内容没了。
这显然不是正常的应用程序,我们都会哭的。那么就需要我们队生命周期非常了解了,当我们按Home键的时候,Activity回调了onPause-->OnStop()方法,再次进入应用程序的时候回调了OnRestart-->OnStart-->onResume()方法,说明我们只要在onPause()和OnRestart方法里面做处理既可以保存之前的状态:下面看代码
package com.lp.ecjtu.activitydemo1; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.widget.EditText; public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText editText; //定义一个String字符串用于存放用户输入的字符串 private String userString; //创建Activity被回调 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (EditText) findViewById(R.id.editText); Log.e(TAG, "Start onCreate ========="); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } //启动Activity被回调 @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Log.e(TAG, "Start onStart ========="); } //重新启动Activity被回调 @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); //再次启动应用时,把先前用户输入的值重新设置EditText editText.setText(userString); Log.e(TAG, "Start onRestart ========="); } //恢复Activty被回调 @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.e(TAG, "Start onResume ========="); } //暂停Activity被回调 @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); //按home键的时候,保存用户输入的字符串信息。 userString = editText.getText().toString(); Log.e(TAG, "start onPause============="); } //停止Activity被回调 @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Log.e(TAG, "start onStop============="); } //销毁Activity被回调 @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.e(TAG, "start onDestroy============="); } }
重新启动app,按home键,在进入应用程序OK了,看下面的图:
总结:理解生命周期的关键是,我们可以在开发过程选择性的重写生命周期中的方法,解决一些实际问题,这才是关键,学以致用!