《》Activity 的生命周期与加载模式
在Activity的生命周期中,如下方法会被回调:
public void onCreate(Bundle savedInstanceState) ;
创建Activity时被回调。该方法在Activity的一个生命周期中只可能回调一次
public void onStart();
启动Activity的时候被调用
public void onRestart();
重新启动Activity的时候会被调用
public void onResume();
恢复Activity的时候会被回调,onStart()方法之后一定会毁掉这个方法,从上图中也可以将看到这一点
public void onPause();
暂停Activity的时候被回调,即当Activity依然可见,但是被一个窗口挡上了,不能够获得焦点了
public void onStop();
当Activity完全不可见,失去焦点,就会回调这个方法,如按下“HOME“键
public void onDestroy();
当Activity被销毁时回调,该方法在一个生命周期中只可能被回调一次
下面有一个测试用例,在需要的时候随时可以用下面的代码进行测试:
ActivityLifeCycle.java
布局文件中只有两个按钮,非常的简单
public class ActivityLifeCycle extends Activity {
final String TAG = "--CycleState--" ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_life_cycle);
Button startActivity = (Button) findViewById(R.id.startActivity) ;
Button finishActivity = (Button) findViewById(R.id.finishActivity) ;
startActivity.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
Intent intent = new Intent(ActivityLifeCycle.this , SecondActivity.class) ;
startActivity(intent);
}
}); // 为startActivity注册监听器完毕
finishActivity.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
ActivityLifeCycle.this.finish() ;
}
});//为finishActivity注册监听器完毕
}
@Override
public void onStart()
{
super.onStart();
// 输出日志
Log.d(TAG, "-------onStart------");
}
@Override
public void onRestart()
{
super.onRestart();
// 输出日志
Log.d(TAG, "-------onRestart------");
}
@Override
public void onResume()
{
super.onResume();
// 输出日志
Log.d(TAG, "-------onResume------");
}
@Override
public void onPause()
{
super.onPause();
// 输出日志
Log.d(TAG, "-------onPause------");
}
@Override
public void onStop()
{
super.onStop();
// 输出日志
Log.d(TAG, "-------onStop------");
}
@Override
public void onDestroy()
{
super.onDestroy();
// 输出日志
Log.d(TAG, "-------onDestroy------");
}
}
此外还需要创建SecondActivity,并在Manifest.xml文件中加以配置,就不在写了,可以简单的做一个窗口就行了
《》Activity的加载模式
在Manifest.xml文件中可以对加载的Activity进行加载方式的配置,即,对属性值
android:launchMode的属性赋值,(注意这个属性并不是针对整个应用程序的,而是针对每一个Activity的)该属性支持下面四种模式:
standerd:标准模式,这也是默认的加载模式
singleTop: Task顶单例模式
singleTask:Task内单例模式
singleInstance:全局单例模式
上面的四种模式,指定了一个Activity在Activity Task管理栈中的创建和存在模式:
standerd模式:
每次通过这种模式来启动目标Activity的时候,Android总会为目标Activity创建一个新的实例,并将该Activity实例添加到当前的Task栈的栈顶——这种模式不会启动新的Task,新的Activity实例只会放到原有的Task栈顶,
public class StandardTest extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.setContentView(layout);
// 创建一个TextView来显示该Activity和它所在Task ID。
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString()
+ "\n" + ",Task ID为:" + this.getTaskId());
Button button = new Button(this);
button.setText("启动StandardTest");
// 添加TextView和Button
layout.addView(tv);
layout.addView(button);
// 为button添加事件监听器,当单击该按钮启动StandardTest
button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// 创建启动StandardTest的Intent
Intent intent = new Intent(StandardTest.this
, StandardTest.class);
startActivity(intent);
}
});
}
}
上面的程序中,每次点击按钮的话,都会不断地启动StanderdTest实例(注意不同的Activity会有不同的hashCode值,所以启动的StanserdTest是不同的),但是他们所在Task ID是相同的(通过调用Activity的getTaskId()即可获得这个栈的编号),
singleTop模式:
这种模式和上面的standerd模式基本相同,但有一点不同:当将要被启动的目标Activity已经为Task栈顶时,系统将不会将重新创建目标Activity的实例,而是直接复用已有的Activity实例
singleTask模式:
1、如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,并将它加载到Task的顶部
2、如果将要启动的目标Activity已经位于Task栈顶了,此时与singleTop模式的行为相同
3、如果将要启动的目标Activity已经存在,但是并没有位于Task的栈顶,那么系统会把位于该Activity上面的所有的Activity实例移出Task栈,从而使目标Activity转入栈顶
singleInstance模式
这种模式将保证,无论从哪个Task中启动目标Activity,只会创建一个目标实例,并且使用一个全新的Task栈来装载Activity实例,分为两种情况,
1、如果将要启动的目标Activity不存在的话,系统会先创建一个全新的Task、在创建这个目标实例,并将这个目标实例加入这个Task的栈顶
2、如果将要启动的目标Activity已经存在,无论它位于哪个应用的哪个Task中,系统都将会将这个Task转到前台,从而使Activity 显示出来
需要注意的是如果需要进行上述说的跨应用启动的话,那么还要为Manifest.xml文件中的该Activity,配置如下属性:
android:exported=“true“ 表明这个Activity可以被其他的程序启动