android log.dd("FirstActivity",this.toString()) 求问大神这个语句是什么意思呀?this.toString() 是什么意思?

Android—Activity的四种启动模式及区别
活动的启动模式
启动模式一共有四种,分别是 standard、singleTop、singleTask 和singleInstance,可以在Manifest.xml中通过给activity标签指定android:launchMode 属性来选择启动模式。
1、standard模式
standard 是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式。 Android 是使用返回栈来管理活动的,在 standard 模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard 模式的活动,不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。下面写代码来验证一下:
首先在Androidmanifest文件中的activity标签设置FirstActivity的启动模式为standard:
在OnCreate方法中打印当前栈顶活动的ID,另外加入一个Button,并设置其的监控事件为启动FirstActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Log.d(&FirstActivity&,this.toString());
first_btn = (Button) findViewById(R.id.first_btn);
first_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(FirstActivity.this,FirstActivity.class));
运行项目,连续点击两次Button,打印信息是这样的:
可见三次Activity的ID都不同,所以要退出程序也要按三次back键。vcD4NCjxwPs/Cw+a4+LP2c3RhbmRhcmQgxKPKvbXE1K3A7cq+0uLNvKO6PGJyIC8+DQo8aW1nIGFsdD0="这里写图片描述" src="/uploadfile/Collfiles/544.png" title="\" />
2、singleTop模式
当活动的启动模式指定为 singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
同样,先设置活动的启动模式为singleTop:
其它先不改变,运行项目,打印信息:
这时无论你点击多少次按钮,依然不会出现新的打印信息,因为目前 FirstActivity已经处于返回栈的栈顶,每当想要再启动一个 FirstActivity时都会直接使用栈顶的活动,因此 FirstActivity 也只会有一个实例,仅按一次 Back 键就可以退出程序。
不过当 FirstActivity 并未处于栈顶位置时,这时再启动 FirstActivity,还是会创建新的实例的。下面我们来实验一下,修改 FirstActivity 中 onCreate()方法的代码,如下所示:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Log.d(&FirstActivity&,this.toString());
first_btn = (Button) findViewById(R.id.first_btn);
first_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(FirstActivity.this,SecondActivity.class));
创建SecondActivity,加入Button并设置其点击事件为启动FirstActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d(&SecondActivity&,this.toString());
second_btn = (Button) findViewById(R.id.second_btn);
second_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
startActivity(intent);
现在重新运行程序,在 FirstActivity 界面点击按钮进入到 SecondActivity,然后在 SecondActivity 界面点击按钮,又会重新进入到 FirstActivity。
打印信息:
可以看到系统创建了两个不同的 FirstActivity 实例,这是由于在 SecondActivity 中再次启动 FirstActivity 时,栈顶活动已经变成了 SecondActivity,因此会创建一个新的 FirstActivity实例。现在按下 Back 键会返回到 SecondActivity,再次按下 Back 键又会回到 FirstActivity,再按一次 Back 键才会退出程序。
下面给出singleTop的原理示意图:
3、singleTask模式
当活动的启动模式指定为 singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
同样是设置FirstActivity的启动模式为singleTask:
然后在 FirstActivity 中添加 onRestart()方法,并打印日志:
protected void onRestart() {
super.onRestart();
Log.d(&FirstActivity&, &onRestart&);
最后在 SecondActivity 中添加 onDestroy()方法,并打印日志:
protected void onDestroy() {
super.onDestroy();
Log.d(&SecondActivity&, &onDestroy&);
现在重新运行程序,在 FirstActivity 界面点击按钮进入到SecondActivity,然后在SecondActivity 界面点击按钮,又会重新进入到 FirstActivity。
查看 LogCat 中的打印信息:
从打印信息可以看出,在 SecondActivity 中启动 FirstActivity 时,会发
现返回栈中已经存在一个 FirstActivity 的实例,并且是在SecondActivity 的下面,于是SecondActivity 会从返回栈中出栈,而 FirstActivity 重新成为了栈顶活动,因此 FirstActivity的 onRestart()方法和 SecondActivity 的 onDestroy()方法会得到执行。现在返回栈中应该只剩下一个 FirstActivity 的实例了,按一下 Back 键就可以退出程序。
singleTask 模式的原理示意图:
4、singleInstance模式
指定为 singleInstance 模式的活动会启用一个新的返回栈来管理这个活动(其实如果 singleTask 模式指定了不同的 taskAffinity,也会启动一个新的返回栈)。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
同样设置Activity启动模式为singleInstance:
修改 FirstActivity 中onCreate()方法的代码:在 onCreate()方法中打印了当前返回栈的 id
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Log.d(&FirstActivity&,&Task id is & + getTaskId());
first_btn = (Button) findViewById(R.id.first_btn);
first_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(FirstActivity.this,SecondActivity.class));
修改 SecondActivity 中 onCreate()方法的代码:同样在 onCreate()方法中打印了当前返回栈的 id,然后又修改了按钮点击事件的代码,用于启动 ThirdActivity。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d(&SecondActivity&,&Task id is & + getTaskId());
second_btn = (Button) findViewById(R.id.second_btn);
second_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(SecondActivity.this, ThridActivity.class);
startActivity(intent);
最后修改 ThirdActivity 中 onCreate()方法的代码:仍然是在 onCreate()方法中打印了当前返回栈的 id。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thrid);
Log.d(&ThirdActivity&, &Task id is & + getTaskId());
现在重新运行程序,在 FirstActivity界面点击 按钮进入 到 SecondActivity, 然 后 在 SecondActivity 界 面 点击按钮进入 到ThirdActivity。
查看 LogCat 中的打印信息:
可以看到, SecondActivity 的 Task id 不同于 FirstActivity 和 ThirdActivity,这说明SecondActivity 确实是存放在一个单独的返回栈里的,而且这个栈中只有 SecondActivity 这一个活动。然后我们按下 Back 键进行返回,你会发现 ThirdActivity 竟然直接返回到了FirstActivity,再按下 Back 键又会返回到 SecondActivity,再按下 Back 键才会退出程序,这是为什么呢?其实原理很简单,由于FirstActivity 和 ThirdActivity 是存放在同一个返回栈里的, 当在ThirdActivity 的界面按下 Back 键, ThirdActivity 会从返回栈中出栈,那么 FirstActivity 就成为了栈顶活动显示在界面上,因此也就出现了从 ThirdActivity 直接返回到 FirstActivity 的情况。然后在 FirstActivity 界面再次按下 Back 键,这时当前的返回栈已经空了,于是就显示了另一个返回栈的栈顶活动,即 SecondActivity。最后再次按下 Back 键,这时所有返回栈都已经空了,也就自然退出了程序。
singleInstance 模式的原理示意图:android(32)
安卓的活动会覆盖,实现的机制用的是栈
运行状态;
暂停状态;
停止状态;
销毁状态;
活动的生存期
onCreate();
onStart();
onResume();
onPause();
onDestroy();
onRestart();
体验活动的生命周期
三个Activity,一个NormalActivity, 一个DialogAcitvity, 一个MainActivity
NormalActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.normal_layout);
DialogAcitvity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_layout);
android:name=".MainActivity"
android:label="@string/app_name" &
android:name="android.intent.action.MAIN" /&
android:name="android.intent.category.LAUNCHER" /&
android:name=".NormalActivity"&
android:name=".DialogActivity"
android:theme="@android:style/Theme.Dialog"
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity);
Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity);
startNormalActivity.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, NormalActivity.class);
startActivity(intent);
startDialogActivity.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, DialogActivity.class);
startActivity(intent);
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destory");
protected void onRestart() {
super.onRestart();
Log.d(TAG, "Restart");
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
依次进入每个活动,MainActivity的状态:
onCeate()-&onStart-&onResume-&
进入Normal:
onPause-&onStop
onRestart-&onStart-&onResume
点击DialogAcitivity
onPause(没有onStop,因为这是对话框形式,所以MainActivity没有stop)
最后再返回:
onPause-&onStop-&onDestory
活动被回收后
如果内存不足,先开的活动被回收了,在返回那个活动时,会重新onCreate,同时活动的数据也没了。因此需要新的机制:onSaveInstanceState来解决保存回收前的已有数据问题。
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String tempDate = "要保存的内容";
outState.putString("data_key", tempDate);
onCreate里面取数据:
if(savedInstanceState!=null){
String tempData = savedInstanceState.getString("data_key");
Log.d(TAG, tempData);
Tip:Intent可以和Bundle一起用于传递数据,首先可以将Bundle放在Intent里面,然后传递Intent
活动的启动模式
standard 是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式。因此,到目前为止我们写过的所有活动都是使用的 standard 式。在 standard 模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例
FirstActivity里的onClick:
Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
startActivity(intent);
onCreate里面:
Log.d("FirstAcitivity",this.toString())
点击按钮也就是自己调用自己,结果:需要自己按多次返回键
配置文件中的Activity加上android:launchMode=”singleTop”属性,表示只有一个实例
但是如果活动不是在栈顶,还是会创建多个实例:
FirstActivity和SecondActivity互相循环调用,就不算是singleTop模式,仍然需要按多次返回
singleTask
在整个应用程序的上下文中只有一个实例,就不能循环调用(创建)了,2调用1,因为1已经在栈,所以2直接出栈调用1,2会被销毁。不像上面直接创建一个新的1。SingleTop会往上累加Activity,而singlTask,往下找Activity,找到后进入该Activity并会退出当前活动
singleInstance
指定为 singleInstance 模式的活动会启用一个新的返回栈来管理这个活动(其实如果 singleTask 模式指定了不同的 taskAffinity,也会启动一个新的返回栈) 。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
1调用2,2调用3,2设置为singleInstance。
结果是1,3的taskid是相同的,与2不同,说明2放在了另一个栈中,返回时直接从3返回到1,再返回到2,再退出(因为1,3在同一个栈,所以2单独放在最后才退出)。
获知当前活动
加上这句(可以知道哪个Activity继承了这个Activity,如果继承了,都会打出BaseActivity,因为这句话加载BaseActivity中的onCreate中)
Log.d("BaseActivity", getClass().getSimpleName())
随时随地退出程序
每次完全退出,都要按返回,知道主活动,如何才能快速的退出
设计一个Collector类,一旦有活动(继承同一个活动)创建,在加入list(基类Activity中的onCreate方法中加入),finishAll()方法可以直接退出(最后一层调用button的onclick里面调用),这样不用一次一次返回了
public static List&Activity& activities = new ArrayList&Activity&();
public static void addActivity(Activity activity){
activities.add(activity);
public static void removeActivity(Activity activity){
activities.remove(activity);
public static void finishAll(){
for(Activity activity:activities){
if(!activity.isFinishing()){
activity.finish();
启动活动的最佳写法
假设 SecondActivity 中需要用到两个非常重要的字符串参数,在启动 SecondActivity 的时候必须要传递过来,那么我们很容易会写出如下代码:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class)
intent.putExtra("param1", "data1")
intent.putExtra("param2", "data2")
startActivity(intent)
这样写是完全正确的,不管是从语法上还是规范上,只是在真正的项目开发中经常会有对接的问题出现。比如 SecondActivity 并不是由你开发的,但现在你负责的部分需要有启动SecondActivity 这个功能,而你却不清楚启动这个活动需要传递哪些数据。这时无非就有两种办法,一个是你自己去阅读 SecondActivity 中的代码,二是询问负责编写 SecondActivity的同事。你会不会觉得很麻烦呢?其实只需要换一种写法,就可以轻松解决掉上面的窘境.
我们在 SecondActivity 中添加了一个 actionStart()方法,在这个方法中完成了 Intent 的构建,另外所有 SecondActivity 中需要的数据都是通过 actionStart()方法的参数传递过来的,然后把它们存储到 Intent 中,最后调用 startActivity()方法启动 SecondActivity(原因在于函数一般都会注明参数,可以自己看)
public static void actionStart(Context context, String data1, String data2){
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("param1", data1);
intent.putExtra("param2", data2);
context.startActivity(intent);
在FirstActivity里面的onClick中加入:
SecondActivity.actionStart(FirstActivity.this, "data1", "data2")
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:168767次
积分:3171
积分:3171
排名:第10787名
原创:147篇
转载:18篇
评论:13条
(2)(1)(1)(1)(1)(2)(3)(6)(10)(3)(27)(20)(42)(13)(21)(10)(1)(1)(Android第一行代码)活动的启动模式 - blogchen - 博客园
活动的启动模式
启动模式一共有四种,分别是 standard、singleTop、 singleTask 和 singleInstance,可以在 AndroidManifest.xml 中通过给&activity&标签指定 android:launchMode属性来选择启动模式。下面我们来逐个进行学习。
1.standard模式:(对于使用 standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建 该活动的一个新的实例。)
&&是活动默认的启动模式
&修改 FirstActivity中 onCreate()方法的代码,如下所示:
&&&&&&&&&&&&&& @Override
&&& &protected void onCreate(Bundle savedInstanceState) {&
&&&&&&&&&& &super.onCreate(savedInstanceState);&
&&&&&&&&&&//从打印信息中我们就可以看出,每点击一次按钮就会创建出一个新的 FirstActivity实例我们需要按三次back才能退出程序。
&&&&&&&&&& &Log.d("FirstActivity", this.toString());&
&&&&&&&&&&&&requestWindowFeature(Window.FEATURE_NO_TITLE);&
&&&&&&&& & &setContentView(R.layout.first_layout);&
&&&&&&&&&& &Button button1 = (Button) findViewById(R.id.button_1);
&&&&&&&&&& button1.setOnClickListener(new OnClickListener() {&
&&&&&&&&&&&&& &@Override
&&&&&&&&&&public void onClick(View v) {&
&&&&&&&&&&&& //我们,在 FirstActivity的基础上启动 FirstActivity。
&&&&&&&&&&&&&&&&&& &Intent intent = new Intent(FirstActivity.this, FirstActivity.class);&&
&&&&&&&&&&&&&&&&&&& startActivity(intent);
&&&&&&&&&&& &}
&&&&&&&&&& });
2.singleTop模式(在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用 它,不会再创建新的活动实例。)
&&&&&& 修改 AndroidManifest.xml中 FirstActivity的启动模式,
&&&&&&& &activity&&&&
&&&&&&&&&&&& &android:name=".FirstActivity"
&&&&&&&&&& //修改 AndroidManifest.xml中 FirstActivity的启动模式,
&&&&&&&&&&& & android:launchMode="singleTop"&
&&&&&&&&&&& &android:label="This is FirstActivity" &&
&&&&&&&&&& & &intent-filter&&&&&
&&&&&&&&&&&&&& & &action android:name="android.intent.action.MAIN" /&&
&&&&&&&&&&&&&& & &category android:name="android.intent.category.LAUNCHER" /&&
&&&&&&&&&&&&&&/intent-filter&
&&&&& &/activity&
&然后重新运行程序,查看 LogCat会看到已经创建了一个 FirstActivity的实例.仅按一次 Back键就可以退出程序。不过当 FirstActivity并未处于栈顶位置时,这时再启动 FirstActivity,还是会创建新的实 例的。
3.singleTask模式(当活动的启动模式指定为 singleTask,每次启动该活动时系统首先 会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这 个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。)
&修改 AndroidManifest.xml中 FirstActivity的 启动模式
&&&&& &activity&&
&&&&&&&&&&&&&& android:name=".FirstActivity"
&&&&&&& //修改 AndroidManifest.xml中 FirstActivity的 启动模式
&&&&&&&&&&&& & android:launchMode="singleTask"&
&&&&&&&&&&&&&& android:label="This is FirstActivity" &&&&
&&&&&&&& &&intent-filter&&&&&&&&
&&&&&&&&&&&&& &&action android:name="android.intent.action.MAIN" /&&&&&&&
&&&&&&&&&&&&& &&category android:name="android.intent.category.LAUNCHER" /&&
&&&&&&& &/intent-filter&
&&&&&&/activity&
&&& 然后在 FirstActivity中添加 onRestart()方法,并打印日志:
&&&& &@Override
&&&&&&&protected void onRestart() {&
&&&&&&&&&&& &super.onRestart();&
&&&&&&&&&&&&&Log.d("FirstActivity", "onRestart");
& 最后在 SecondActivity中添加 onDestroy()方法,并打印日志:
&&&&&& @Override protected void onDestroy() {&
&&&&&&&&&&&&&&&&&&& super.onDestroy();
&&&&&&&&&& & Log.d("SecondActivity", "onDestroy");
在 SecondActivity 中启动 FirstActivity 时,会发 现返回栈中已经存在一个 FirstActivity 的实例,并且是在 SecondActivity 的下面,于是 SecondActivity 会从返回栈中出栈,而 FirstActivity 重新成为了栈顶活动,因此 FirstActivity 的 onRestart()方法和 SecondActivity的 onDestroy()方法会得到执行。
4.singleInstance模式(指定为 singleInstance模式的活动会启用一 个新的返回栈来管理这个活动)
&&&&&使用场景:假设我们的程序中有一个 活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例。?使用前面三种启动模式肯定是做不到的,因为每个&&& 应用程序都会有自 己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用 singleInstance模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活 动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈。
修改 AndroidManifest. xml中 SecondActivity的启动模式:
&&&&&&&& &activity&
&&&&&&&&&&&&&& android:name=".SecondActivity"&
&&&&&&&& //修改 AndroidManifest. xml中 SecondActivity的启动模式:
&&&&&&&&&&&&& &android:launchMode="singleInstance" &&&
&&&&&&&&&&&& &&intent-filter&&&
&&&&&&&&&&&&&&&&&& &&action android:name="com.example.activitytest.ACTION_START" /&&&&&
&&&&&&&&&&&&&&&&&&&&&category android:name="android.intent.category.DEFAULT" /&&&&&&
&&&&&&&&&&&&&&&&& & &category android:name="com.example.activitytest.MY_CATEGORY" /&&
&&&&&&&&&& &&&&&&& &&/intent-filter&
&&&&&&&&&&&& &/activity&
&&&& 修改 FirstActivity 中 onCreate()方法的代码,在 onCreate()方法中打印了当前返回栈的 id.
&&&&&&&&&&&&&& Log.d("FirstActivity", "Task id is " + getTaskId());
&&&& 修改 SecondActivity中 onCreate()方法 的代码,打印了当前返回栈的 id.
&&&&&&&&&& &&&& Log.d("SecondActivity", "Task id is " + getTaskId());
&&&& 最后修改 ThirdActivity中 onCreate()方法仍然是在 onCreate()方法中打印了当前返回栈的 id.
&&&&&&&&&&& &&&&&Log.d("ThirdActivity", "Task id is " + getTaskId());
&&&&&&打印结果:
&可以看到,SecondActivity 的 Task id 不同于 FirstActivity 和 ThirdActivity,这说明 SecondActivity确实是存放在一个单独的返回栈里的,而且这个栈中只有 SecondActivity这一 个活动。

我要回帖

更多关于 d log模式 的文章

 

随机推荐