问题背景:
最近用到了主Activity里有一个Thread在处理数据,当跳转到第二个Activity时,希望Thread暂停。从第二个Activity回来时这个Thread再接着运行。今天得空顺着这个应用场景再过一下Activity的生命周期。
下面是一个小demo,主Activity里有个按钮,跳转到第二个Activity。在主Activity里有个UpdateThread在一直运行。第二个Activity里有个按钮,点击显示一个Dialog。下面是源码:
activity_main.xml
package com.example.activitylife;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView mTextView = null;
Button mBtutton = null;
boolean allowRun = true;
boolean allowUpdate = true;
private static final String tag = "yan";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
Log.i(tag, "onCreate...");
mTextView.setText("..................." + "\n");
mTextView.append("onCreate..." + "\n");
new Thread(new UpdateThread()).start();
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(tag, "onStart...");
mTextView.append("onStart..." + "\n");
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i(tag, "onRestart...");
mTextView.append("onRestart..." + "\n");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(tag, "onResume...");
mTextView.append("onResume..." + "\n");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(tag, "onPause...");
mTextView.append("onPause..." + "\n");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(tag, "onStop...");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
Log.i(tag, "onDestroy...");
super.onDestroy();
}
@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;
}
public void initUI(){
mTextView = (TextView)findViewById(R.id.textview_show);
mBtutton = (Button)findViewById(R.id.button_jump);
mBtutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
// allowRun = false;
// allowUpdate = false;
startActivity(intent);
}
});
}
class UpdateThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
while(allowRun){
if(allowUpdate){
try {
Thread.sleep(1000);
Log.i(tag, "UpdateThread....");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
package com.example.activitylife;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class SecondActivity extends Activity {
private final static String tag = "yan";
Button mShowDialogBtn = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.i(tag, "SecondActivity:OnCreate...");
mShowDialogBtn = (Button)findViewById(R.id.button_show_dialog);
mShowDialogBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showAlertDialog(SecondActivity.this);
}
});
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(tag, "SecondActivity:onStart...");
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i(tag, "SecondActivity:onRestart...");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(tag, "SecondActivity:onResume...");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(tag, "SecondActivity:onPause...");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(tag, "SecondActivity:onStop...");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(tag, "SecondActivity onDestroy...");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.second, menu);
return true;
}
public void showAlertDialog(Context c){
Dialog dialog = new AlertDialog.Builder(c)
.setTitle("通知")
.setMessage("专注才能深入 ")
.setIcon(android.R.drawable.ic_dialog_email)
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
})
.create();
dialog.show();
}
}
运行界面:
下面是得到的结论:
1、一个正常的Activity的流程:onCreate------onStart-----------onResume, onResume的时候就可以看到这个Activity,并跟这个Activity进行交互。之后如果正常退出的话,流程是:onPause--------onStop---------onDestroy.什么时候进行onPause的状态呢?在Activity不在是最前端,但依然可见时这个状态是onPause。所以切换到SecondActivity时,主Activity先进行onPause,当SecondActivity onResume可见时,主Activity进行onStop,表示彻底不可见。 (正常的流程可简化记忆为:CS R, PS D. 有CS和PS打头 不会记混淆吧。)
2、如果不做特别处理,主Activity切换到SecondActivity后,只进行到onStop,如果自己写了finish(),那么从SecondActivity按返回键时就直接退出了,否则的话主Activity进行onRestart--------onStart-----onResume.恢复正常。
3、当主Activity里有个UpdateThread一直在运行时,即使切换到SecondActivity,它依旧没有被释放,并正常运行。
如果需要切换到第二个Activity时,UpdateThread停止运行,让allowUpdate = false。当切换回来时,让allowUpdate = true就ok了。
4、从SecondActivity按返回键时,SecondActivity自动进行了onDestroy.
5、如果不对主Activity做额外操作,当按返回键后,虽然他执行了onDestroy,但是UpdateThread一直在运行。这点比较奇葩,呵呵。所以要退出主程序时,一定让allowRun = false,确保Thread停止.
6、当在主Activity复写了OnBackPressed()时:
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
MainActivity.this.finish();
}
虽然finish()了,但是UpdateThread依旧在运行。
7、如果对主Activity进行锁屏,它从onResume-----切换到onPause---onStop的状态,不用说,UpdateThread依旧在运行。
8、当在SecondActivity按显示Dialog时,如上面第三幅图时,对SecondActivity的状态没有任何影响。这一点跟咱家之前的观念还不大一样,往后要更正了。其实可以这样理解,因为Dialog显示的时候,SecondActivity首先是可见的所以肯定不是onStop状态。再者,虽然SecondActivity貌似不在最前端了,但事实上他依旧可以合用户进行交互,在屏幕周围可以响应点击等事件。在本例中,如果不按Dialog的确定按键,而是点击屏幕其他区域一样可以让Dialog消失,所以SecondActivity没有进入onPause状态,而依旧是OnResume.
链接http://blog.csdn.net/lamp_zy/article/details/7703893说当按锁屏键时,原Activity只执行onPause而不执行onStop这是胡扯。此链接中还说,当有Dialog显示时,当前Activity会进入onPause状态而不进入OnStop状态,这亦是胡扯,真实情况是当有Dialog显示时,原Activity依旧是onResume状态。
这下Activity的生命周期终于真相大白了!!!
--------------------本文系原创,转载请注明作者:yanzi1225627
参考链接:
1、Dialog详解:http://blog.csdn.net/flyfight88/article/details/8602162
2、http://blog.csdn.net/hpoi/article/details/4629065
3、http://blog.csdn.net/hpoi/article/details/4629065