一. 再探Activity生命周期
为了研究activity的生命周期,简单测试代码如下。
package com.example.testactivity;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
private static final String LOG_TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(LOG_TAG, "MainActivity------onDestroy");
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i(LOG_TAG, "MainActivity------onRestart");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(LOG_TAG, "MainActivity------onResume");
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(LOG_TAG, "MainActivity------onStart");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(LOG_TAG, "MainActivity------onStop");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(LOG_TAG, "MainActivity------onPause");
}
@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;
}
}
查看logcat,输出如下:
1.点击进入 app 后,点击back button退出:
2.点击进入app后,直接锁屏:
解锁屏幕后,activity被唤醒:
3.点击app进入 app后,点 home键退出,又进入:
4.点击 home键进入后直接锁屏
然后唤醒
5.点击app进入后,点home键退出,然后锁屏:
然后唤醒进入
说明:
1)onpause()方法在用户离开activity时被调用(这一般并不表示activity要被销毁了)。这个函数一般用来提交哪些需要保存状态的数据。
2)对标签的说明
除label,name,icon外还需指定一个或多个来确定该activity可以响应的intent。
是过滤器,action说明次activity时application的main入口,指定这个activity需要在系统的application 列表中列出!
注:android application要求所有应用程序组件(Activity,Service,ContentProvider,BroadcastReceiver)都必须显示进行配置.
二.Activity之间的值传递
1)bundle(适用于数据比较少的情况)
Intent intent = new Intent();
intent.setClass(A.class,B.class);
intent.putExtra(“name”,”value”);
startActivity(intent);
之后再B.class中用
Intent intent = new Intent();
intent.getExtras()来获取
2)Bundle(数据较多时使用)
Intent intent = new Intent(A.class,B.class));
Bundle bundle = new Bundle();
bundle.putString(“Stringkey1”,”value1”);
bundle.putString(“booleankey2”,”value2”);
intent.putExtra(“key”,bundle);
startActivity(intent);
之后再B.class中用
Intent intent = new Intent();
Bundle bundle = intent.getBundleExtra(“key”);
bundle.getBoolean(“booleankey2”);
bundle.getString(“Stringkey1”);来获取。
3)解析startActivityForResult
适用于A跳转到B,再返回到A,同时还要保留之前的用户输入。由于由页面 A跳转到页面 B之后,A所在页面的Activity已经被Destroy。所以,如果要重新返回A并显示数据,就必须将A所在页面的Activity再次唤醒,与此同时调用某个方法来获取并显示相应的数据。
所以一般用以下几个步骤来实现
a.从A跳转到B时使用startActivityForResult(Intent intent, int requestcode)方法;
b.再A页面的Activity重写onActivityResult方法,
onActivityResult(int requestcode, int resultcode, intent data);
其中参数1是提供给onActivityResult,用来确认数据是从哪个activity返回的,并且该参数和从A跳转到B时使用startActivityForResult方法的requestcode相对应。
参数2由新的activity在关闭前向前面的activity返回数据时使用。
参数3是一个 intent,带有从B所在Activity返回的数据。
A 所在页面activity实现
onActivityResult(int requestcode, int resultcode, intent data){
String result = data.getExtras().getString("result");
}
B所在activity实现:
Intent intent = new Intent();
intent.putExtra("result","value");
B.this.SetResult(RESULT_OK,intent);
B.this.finish();
未完待续。。。
---------------------------------------
好,今天接着来进一步解析Activity的生命周期。
自己画了一下activity的生命周期图,感觉很糟糕的样子。。
如图所示,activity的整个生命周期有四种状态,而对这四种状态的描述通常使用一下7种方法来完成。
Activity的四种状态分别是:
a.running
当activity运行于屏幕前台(处于activity栈的栈顶),此时它获取了 焦点可以相应用户操作,属于running状态,同一时刻只能有一个 activity处于running(active)状态。
b.paused
此时Activity已经失去焦点,但是仍然对用户可见,例如:在该activity之上有另外一个透明的 Activity或Toast,AlertDialog等弹出窗口时,该Activity则处于暂停状态。暂停的Activity仍然 是处于存活状态,(它保留着所有的状态和成员信息并保持着和窗口管理器的连接),但当此时出现system memory不够用时,就会被系统杀掉。
c.Stopped
指定Activity完全被另一个Activity遮挡时,它将处于停机状态,但它仍保留着所有的状态和成员信 息。只是此时指定的Activity对用户不可见,但当此时出现system memory不够用时,就会被系统杀掉。
d.Dead
Activity尚未启动,或者已经被手动中止,或者已经被system回收。导致Activity处于非活动状态。
手动中止可以在程序中调用finish方法;而被system回收,则是可能是因为内存不足。当system内存不足时,Dalvak虚拟机的内存回收规则如下:
first:先回收与其它Activity,Service,Intent,Receiver无关的进程(优先回收独立的 Activity)。所以,一些耗时的操作最好写成Service。
second:不可见(stopped)的Activity。
Third:Service进程(经过前两步后,内存不足时采取)。
Fourth: 当前正在运行的(Running)Activity。
伴随Activity生命周期的7个方法:
当Activity从一种状态进入另一种状态时system会自动调用下面相应的方法来通知用户这种变化。
a.Activity第一次被实例化的时候system会调用onCreate()方法(整个生命周期只调用一次)来进行初始化设置:
为Activity提供所需布局文件;为按钮绑定监听器等静态的设置操作。
b.Activity可见,但尚未获得焦点,即不能与用户进行交互时调用:onStart(),
c.Activity已经stopped之后重新被system启动时调用onRestart();
d.当Activity获得用户焦点能进行交互时system调用onResume().
e.当system启动另外一个Activity时,在新的Activity启动之前被system调用来保存当前获得用户焦点的Activity中的持久数据,停止动画等。当系统而非用户自己出于回收内存而关闭了Activity。此时,用户会期望当他再次回到这个Activity时,它仍保持着上次离开时的样子,此时便调用onSaveInstanceState(),该方法用来保存Activity被杀之前的状态,它在onPause之前被触发,当system为了节省内存开销销毁了该Activity(或许用户并不想销毁)时就需要重写这个方法了,当该Activity再次被实例化时会通过onCreate(Bundle saveInstanceState)将已经保存的临时状态数据传入。需要注意的是
onSaveInstanceState() 方法并不会经常被调用,它的默认触发条件为按下home键,按下电源键,横竖屏切换三种情况。所以我们可以通过重写onSaveInstanceState() 来记录Activity的临时数据。
而记录持久数据时,应该使用onPause()来存储。
f.当Activity完全被另一个Activity覆盖不可见时system调用onStop();
g.当Activity被kill时system调用onDestroy(),用来释放onCreate()方法中创建的资源,如结束线程等。需要注意的是和onCreate相对应,onDestroy()方法,在Activity的整个生命周期中也只被调用一次。
至此,关于Activity的梳理已经差不多了,最后需要注意一下的是设置Activity的android:configChanges=“”的设置。