在这里借助简书平台作为学习的笔记,接下来的内容,可能对即将步入职场,Android 面试有些帮助
standard
standard 是activity 默认的启动方式,我们知道,Android 是使用返回栈来管理活动的,每当启动一个新的活动,它都会创建一个该活动的实例,返回栈中,并处于栈顶。而且在创建该活动的实例时,它不会在乎栈中是否存在了这个activity的实例
接下来给大家一段实例
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("MainActivity",this.toString());
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,MainActivity.class);
startActivity(intent);
}
});
}
}
嗯?为什么是跳转到MainActivity ?莫慌,我们这段代码其实没什么意义,但是它是我们用于查看栈中的活动实例用的
1.png这个时候我们会发现,当我们点击button的时候,后台打印了activity的实例,我们需要连续按两次back键才能完全退出程序,给大家画个模型图(出入栈的规则为:先入后出)
2.pngsingleTop
其实,如果我们考虑优化的问题,栈内存在多个相同的实例(区别是地址不同),是不怎么合理的,所以singleTop模式就是来解决这样的问题的(其实并没有完全解决,下面会聊到),当该活动处于栈顶的时候,且启动模式为singleTop就不会再创建该活动的实例,而是直接使用它。
<activity android:name=".MainActivity"
android:launchMode="singleTop"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
在对应的activity 中添加这行代码android:launchMode="singleTop"
然后,你在打印台后面,无论你点击BUTTON多少次,后台都只有一个MainActivity 的实例,当然它的前提条件是该activity在栈中的实例必须是处于栈顶,然后你只要按一次back键,就会退出程序了
为了方便理解,再创建一个activity,并且命名为TestActivity,然后修改MainActivity 中的Intent 的内容,让其指定跳转到TestActivity ,然后我们再给出TestActivity 的代码内容
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestActivity",this.toString());
setContentView(R.layout.activity_test);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(TestActivity.this,MainActivity.class);
startActivity(intent);
}
});
}
}
4.png
你会发现,再第一次跳转之后,MainActivity 已经不处于栈顶了,所以再TestActivity 的页面中,我们在点击BUTTON2 的时候,它跳转到MainActivity 时,它是重新创建了MainActivity 的实例的。要退出程序时就要连续按三次back键了
singleTask
行了,其实这时候也发现了问题,如果activity 的实例没有栈顶,而栈中有存在了该activity 的实例那么是否会很浪费内存,(如果你对按返回键时的顺序没要求的话)那么这个时候singleTask 就派上用场了,当我们指定activity 的启动模式为singleTask 的时候,每次我们启动该activity时,系统都会先检测栈中是否存在该activity 的实例,如果有则直接使用该实例,并把该活动以上的所有活动都出栈,没有的话就重新创建该活动实例
用代码来验证一下,在 mainfests 的配置文件中将MainActivity 的android:launchMode="singleTop"
改为android:launchMode="singleTask"
这个时候我们在MainActivity 添加生命周期中的某个片段 onRestart() ,在TestActivity 中添加onDestory(),(希望提到这你能马上想到activity 的生命周期,因为这很多公司在面试的时候基本都会提问的,算了,自己在写这篇笔记的时候也没能马上想起,所以activity的生命周期为:onCreate(),onStart(),onResume(),onPause(),onStop(),onDestory(),onRestart())。
行了,这个时候再给出MainActivity 和TestActivity的代码
MainActivity 代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("MainActivity",this.toString());
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TestActivity.class);
startActivity(intent);
}
});
}
protected void onRestart(){
super.onRestart();
Log.e("MainActivity","onRestart");
}
}
TestActivity代码
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestActivity",this.toString());
setContentView(R.layout.activity_test);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(TestActivity.this,MainActivity.class);
startActivity(intent);
}
});
}
protected void onDestroy(){
super.onDestroy();
Log.e("TestActivity","onDestroy");
}
}
在启动MainActivity之后,便创建了一个MainActivity实例,点击BUTTON 之后,创建了TestActivity 的实例,这个时候MainActivity 在栈中的位置已经不是在栈顶了,我们在TestActivity 中点击BUTTON2 跳回MainActivity ,这个时候MainActivity 调用了onRestart()方法,而之前在MainActivity 的TestActivity 的实例已经出栈了,所以TestActivity 执行了onDestory() 方法
6.png 5.pngsingleInstance
singleInstance 是稍微比较复杂的,其应用场景是该程序要和其他程序要共享某个Activity 实例时,我们知道每个程序都有自己的返回栈,同一个活动若要在不同的返回栈中,那么就得创建新的实例,而singleInstance模式正是解决这种问题的,在该模式下,会为activity 单独创建一个返回栈,其他程序想用到该activity的都会在同一个返回栈中使用它,我们先把TestActivity 的启动模式修改为singleInstance,修改MainActivity和TestActivity 中log 里的内容,
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("MainActivity","栈的ID"+getTaskId());
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TestActivity.class);
startActivity(intent);
}
});
}
TestActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestActivity","栈的ID"+getTaskId());
setContentView(R.layout.activity_test);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(TestActivity.this,DemoActivity.class);
startActivity(intent);
}
});
}
DemoActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("DemoActivity","栈ID"+getTaskId());
setContentView(R.layout.activity_demo);
}
然后你可以看看MainActivity ,TestActivity和DemoActivity 的栈ID,你会发现,MainActivity 和 DemoActivity 的栈ID 是一样的 !如果我们要退出程序,我们在按一次back键时,我们会发现我们是由DemoActivity 跳转到了MainActivity,如果我们再按back 键,会由MainActivity 跳转到TestActivity ,再按一次back 键,才能彻底的退出程序,也就是当我们所有栈中的实例都清空时才能退出程序
7.png
也可以关注一下我的公众号,不定期的发推送一些文章
网友评论