活动Activity的启动模式有四种:standard、singleTop、singleTask和singleInstance。
通过在androidmanifest.xml中通过给activity标签指定要选择的启动模式,默认的启动模式是standard。
1、standard
这种启动模式,只要不进行启动模式的指定,默认都是改启动模式,每启动一次,将新启动的Activity置于该栈顶。
看一个例子:在Mainactivity中通过点击按钮,进行本页面的跳转。通过log打印来显示信息。
在Mainactivity的oncreate方法中设置跳转,按钮监听。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("FirstActivity", this.toString());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
bt=(Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setClass(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
看着有些别扭,但是可以达到效果,咱们看看log打印:
每点击一次按钮,都会进行log的打印,创建新的activity置于栈顶,通过Back键也要点两次才回退出。这就是standard模式。
该模式的示意图:
2、singleTop
singleTop是对standard的一个改进,当一个活动处于栈顶,其实没有必要再创建出一个新的activity再置于栈顶,single模式就是
一个进步。
同样对oncreate进行操作:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("single", this.toString());
setContentView(R.layout.activity_main);
bt=(Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
在androidmanifest中设置启动模式,
<activity
android:launchMode="singleTop"
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
通过对按钮的点击看看log 的信息打印。
只会出现一次log打印,因为该Activity始终置于栈顶。
但是如果刚开始此activity不住栈顶,它会制造出新的activity作为栈顶。
先通过跳转第二个activity,再返回到第一个activity。
Mainactivity:
package com.example.single;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button bt, bt1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("single", this.toString());
setContentView(R.layout.activity_main);
bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
bt1 = (Button) findViewById(R.id.bt1);
bt1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);
startActivity(intent);
}
});
}
@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;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
点击跳转到第二个Activity后:
这个log打印可以看出,通过点击跳转按钮到第二个Activity,打印出other的信息,再通过点击返回按钮返回到第一个activity会重
新打印出新的log信息置于栈顶。
singleTop的示意图:
3、singleTask
singleTop很好地解决重复创建栈顶的问题,但是如果不位于栈顶,还是会多次创建该活动实例。有没有使得整个Activity在整个
应用程序的上下文中只存在一个实例呢?看另一种模式,singleTask。
在Mainactivity中创建一个onrestart方法,进行log打印。
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i("single", "onrestart");
}
在另一个Activity中创建onDestroy方法。
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("other", "ondestroy");
}
因为在第二个Activity返回到第一个Activity时,会调用restart方法,返回栈中已经存在Mainactivity的实例,进行log打印就可以验证是否仍然是该Activity。重新成为栈顶。
接着onDestroy方法也会执行。按一下Back键便可退出程序。
第二个Activity代码:
package com.example.single;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class OtherActivity extends Activity {
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("other", this.toString());
setContentView(R.layout.other);
bt=(Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent() ;
intent.setClass(OtherActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("other", "ondestroy");
}
}
4、singleInstance
假如说,一个程序的活动activity可以被其他程序所共享,前面3种是达不到的,因为每个应用程序都有自己的栈,将一个活动入栈
必定要创建新的活动的实例,而singleinstance就好比static,是静态所共享的,只要引用另一个栈的活动就好ok了,不必要创建
新的实例。
通过一个实例,1跳转到2,2跳转到3。
在androidmanifest设置模式,这里将第二个Activity设置成singleInstance。
<activity
android:name=".OtherActivity"
android:launchMode="singleInstance"
>
activity>
Mainactivity的oncreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("single", "Task is"+getTaskId());
setContentView(R.layout.activity_main);
bt1 = (Button) findViewById(R.id.bt1);
bt1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);
startActivity(intent);
}
});
}
第二个Activity的oncreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("other", "Task is"+getTaskId());
setContentView(R.layout.other);
bt=(Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent() ;
intent.setClass(OtherActivity.this, ThirdActivity.class);
startActivity(intent);
}
});
}
第三个活动的oncreate方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("third", "Task is"+getTaskId());
}
log效果图可以看一下:
很明显,第一个和第三个Activity位于一个栈,而且当你Back键返回时,第三个Activity会直接先到第一个Activity,然后才是第二
个Activity,因为当第三个栈顶移走后是第一个Activity位于栈顶,栈顶为空时,才会跳转到另一个栈显示第二个Activity。