Android四大组件之Activity详解

.Activity的本质html

Activity是Android提供的四大组件之一,是进行Android开发必不可少的组件.Activity是一个界面的载体,能够把它与html页面进行类比,html页面由各类各样的标签组成,而Activity则能够由各类控件组成.然而Activity也并非那么简单.查看Activity类的源码咱们就能够看到,这个类大概有六千多行代码,说明Android对Activity的处理是至关复杂的.不过咱们平时进行开发的时候不须要了解到那么深刻的地步,由于咱们能够根据Activity中提供的方法快速的开发,Activity生命周期中涉及到七个回调方法.java

.Activity的生命周期android

Android官方文档给出的Activity生命周期图web

 

当打开一个Activity的时候,会调用这个Activity的onCreate()方法,接着调用onStart()方法,而后调用onResume()方法.当onStart()方法执行以后,咱们就能够看到这个Activity界面了.下面经过代码对单个Activity生命周期作进一步的解释.数组

MainActivity.java浏览器

package com.example.caobotao.activitylifecircle;

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;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("info","MainActivity onCreate()");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("info","MainActivity onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("info","MainActivity onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("info", "MainActivity onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("info", "MainActivity onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info","MainActivity onDestroy()");
    }


    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("info","MainActivity onRestart()");
    }

}
View Code

 

 运行项目后,Logcat输出:安全

11-24 20:00:49.160 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onCreate()
11-24 20:00:49.170 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onStart()
11-24 20:00:49.170 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onResume()

 

点击返回键,Logcat输出:数据结构

11-24 20:05:15.370 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onStop()
11-24 20:05:15.370 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onDestroy()

 

下面简单讲一下Activity生命周期中每一个函数的做用:app

onCreate() : ide

当Activity第一次被建立的时候调用此方法.通常在此方法中进行控件的声明,添加事件等初始化工做.

onStart():

当Activity被显示到屏幕上的时候调用此方法.

onResume():

当此Activity可以被操做以前,也就是可以得到用户的焦点以前调用此方法.

onRestart():

当Activity被中止后又被再次启动以前调用此方法.接着将调用onStart()方法.

onPause():

当第一个Activity经过Intent启动第二个Activity的时候,将调用第一个Activity的onPause()方法.而后调用第二个Activity的onCreate(),onStart(),onResume()方法,接着调用第一个Activity的onStop()方法.若是Activity从新得到焦点,则将调用onResume()方法;若是此Activity进入用户不可见状态,那么将调用onStop()方法.

onStop():

当第一个Activity被第二个Activity彻底覆盖,或者被销毁的时候回调用此方法.若是此Activity还会与用户进行交互,将调用onRestart方法();若是此Activity将被销毁,那么将调用onDestroy()方法.

onDestroy():

Activity被销毁以前调用此方法.或者是调用finish()方法结束Activity的时候调用此方法.能够在此方法中进行收尾工做,好比释放资源等.

(注意:重写某个Activity的这些回调方法的时候须要首先在第一行调用基类Activity的相应的回调方法.好比super.onCreate(),super.onStart()等等.)

 

接下来了解一下多个Activity交互中的生命周期.在第一个Activity中添加一个按钮,用于启动第二个Activity.

AActivity.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class AActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("info","AActivity onCreate()");
        findViewById(R.id.btnStartBAty).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(AActivity.this,BActivity.class));
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("info","AActivity onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("info","AActivity onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("info", "AActivity onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("info", "AActivity onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info","AActivity onDestroy()");
    }


    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("info","AActivity onRestart()");
    }

}
View Code

 

BActivity.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class BActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_baty);
        Log.i("info","BActivity oncreate()");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("info","BActivity onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("info","BActivity onResume()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("info","BActivity onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info", "BActivity onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("info","BActivity onRestart()");
    }

}
View Code

 

运行项目后,Logcat输出:

11-26 21:14:38.960 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onCreate()
11-26 21:14:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onStart()
11-26 21:14:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onResume()

 

点击按钮打开BActivity后,Logcat输出:

11-26 21:14:42.050 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onPause()
11-26 21:14:42.080 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity oncreate()
11-26 21:14:42.090 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onstart()
11-26 21:14:42.090 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onresume()
11-26 21:14:45.750 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onstop()

 

而后点击BACK键,Logcat输出:

11-26 21:20:38.650 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onPause()  
11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onRestart()
11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onStart()
11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onResume()
11-26 21:20:41.710 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onStop()
11-26 21:20:41.710 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onDestroy()

能够看出,当启动第二个Activity时,老是先调用第一个Activity的onPause()方法,而后若是第二个Activity是第一次建立的话,则再调用第二个Activity的onCreate()方法,不然调用第二个Activity的onRestart()方法,接着调用onStart(),onResume()方法.

.Activity生命周期交互设计思想

到这里,你们可能会有些疑问,谷歌为何要这样设计呢?如:

1.当从第一个Activity启动第二个Activity的时候,为何先调用第一个Activity的onPause()方法,而后再调用第二个Activity的onCreate()等方法呢?

解释:假若有这样一个状况,你正在使用APP听音乐,忽然来了一个电话,那么固然须要先暂停音乐,而后进行电话的处理。因此这就是onPause()方法的做用:能够用来保存当前的各类信息.能够在这个APP的onPause()方法中实现暂停音乐的逻辑,而后再处理电话的业务处理.

2.当从第一个Activity启动第二个Activity的时候,为何第一个Activity的onStop()方法是调用完第二个Activity的系列方法后才调用呢,为何不在第一个Activity的onPause()方法以后就调用呢? 

解释:这是谷歌对安全方面的一个考虑.假如先调用第一个Activity的onStop()方法,那么此时第一个Activity将不可见,若是接下来调用第二个Activity的一系列建立方法失败了,那么就会致使这两个Activity都没显示在屏幕上,就会出现黑屏等不友好界面.若是是调用完第二个Activity一系列建立方法后,再调用第一个Activity的onStop()方法,就会避免这种状况的发生.

 

.Activity生命周期的应用场景

讲了这么多,你们可能会问,Activity生命周期到底实际中怎么使用.下面经过实例来作简单的运用.在AActivity中进行音乐的播放,当点击按钮打开BActivity后,音乐须要暂停,而后点击BACK键返回到AActivity后音乐继续播放.这就须要在AActivity中的onPause()方法中进行音乐的暂停操做,以及暂停时音乐播放位置的记录.在AActivity中的onResume()方法中实现从新返回前台时继续音乐的播放.

AActivity.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class AActivity extends Activity {
    private MediaPlayer mediaPlayer;
    private int position;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mediaPlayer = MediaPlayer.create(this,R.raw.song);
        mediaPlayer.start();
        Log.i("info","AActivity onCreate()");
        findViewById(R.id.btnStartBAty).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(AActivity.this,BActivity.class));
            }
        });
    }


    @Override
    protected void onStart() {
        super.onStart();
        Log.i("info","AActivity onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        //若是播放的位置不是0
        if (position != 0){
            mediaPlayer.seekTo(position);//获取播放的位置
            mediaPlayer.start();//开始播放
        }
        Log.i("info","AActivity onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        //若是播放器正在播放
        if (mediaPlayer.isPlaying()){
            mediaPlayer.pause();//暂停播放
            position = mediaPlayer.getCurrentPosition();//得到暂停时播放的位置
        }
        Log.i("info", "AActivity onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("info", "AActivity onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info","AActivity onDestroy()");
    }


    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("info","AActivity onRestart()");
    }

}
View Code

BActivity.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class BActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_baty);
        Log.i("info","BActivity onCreate()");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("info","BActivity onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("info","BActivity onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("info","BActivity onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("info","BActivity onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("info", "BActivity onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("info","BActivity onRestart()");
    }

}
View Code

  

.其余应用程序中的Activity

咱们能够经过ComponentName启动其余应用程序中的Activity,好比启动相机等.

用法:

Intent intent=new Intent();  
intent.setComponent(new ComponentName(String packageName,String activityName ));  
startActivity(intent); 

 

.启动系统中常见的Activity

系统给咱们提供了不少经常使用的Activity,能够用来打开浏览器,打开发短信界面,打开相册界面,打开拨号界面等等.

打开浏览器网页:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com")); 
startActivity(intent);

打开相册:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivity(intent);

打开发送短信界面:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT,"Hello World !");
startActivity(intent);

打开拨号界面:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("tel:110"));
startActivity(intent);

 .Activity之间的数据交互

咱们可使用Intent对象进行数据的传递.Intent重载了不少putExtra()方法,囊括了JAVA八大基本类型及其数组类型等.

Activity1.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity1 extends Activity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity1);
        button = (Button) findViewById(R.id.startAnotherActivity);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Activity1.this,Activity2.class);
                intent.putExtra("name","zhangsan");
                intent.putExtra("age",23);
                startActivity(intent);
            }
        });
    }

}
View Code

 

Activity2.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity2 extends Activity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity2);
        textView = (TextView) findViewById(R.id.textView);
        Intent intent = getIntent();
        if (intent != null){
            String name = intent.getStringExtra("name");
            int age = intent.getIntExtra("age",0);//设0为默认值
            textView.setText("姓名: " + name + "\n年龄: " + age);
        }

    }
}
View Code

 

Intent对象还有一个putExtras(Bundle bundle)方法,bundle的意思为一捆,就是把须要传递的数据打成一捆进行传递.下面利用Bundle实现上面的示例,效果同样.

Activity1.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity1 extends Activity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity1);
        button = (Button) findViewById(R.id.startAnotherActivity);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Activity1.this,Activity2.class);
                Bundle bundle = new Bundle();
                bundle.putString("name","zhangsan");
                bundle.putInt("age",23);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }

}
View Code

 

Activity2.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity2 extends Activity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity2);
        textView = (TextView) findViewById(R.id.textView);
        Intent intent = getIntent();
        if (intent != null){
            String name = intent.getStringExtra("name");
            int age = intent.getIntExtra("age",0);//设0为默认值
            textView.setText("姓名: " + name + "\n年龄: " + age);
        }

    }
}
View Code

 

在实际开发中,可能须要传递的数据比较多,不只有姓名,年龄,可能还有性别,学校,爱好等等.根据面向对象的思想,咱们应该想到把这些信息封装成一个java实体类,以达到更好的复用性,耦合性等目的,而后使用Bundle对象的putSerializable()方法将此须要传递的对象传递出去,在另外一个Activity中用Intent对象的getSerializableExtra()方法进行接收.

Person.java

package com.example.caobotao.activitylifecircle;

import java.io.Serializable;

/**
 * Created by caobotao on 15/11/29.
 */
public class Person implements Serializable {
    private String name;
    private int age;
    private String school;
    private String address;
    public Person(){}
    public Person(String name,int age,String school,String address){
        this.name = name;
        this.age = age;
        this.school = school;
        this.address = address;
    }

    @Override
    public String toString() {
        return "姓名: " + name + "\n年龄: " + age + "\n学校: " + school + "\n地址: " + address;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }
}
View Code

 

Activity1.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity1 extends Activity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity1);
        button = (Button) findViewById(R.id.startAnotherActivity);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Activity1.this,Activity2.class);
                Person person = new Person("zhangsan",23,"USST","ShangHai");
                Bundle bundle = new Bundle();
                bundle.putSerializable("person",person);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }

}
View Code

 

Activity2.java

package com.example.caobotao.activitylifecircle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by caobotao on 15/11/29.
 */
public class Activity2 extends Activity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity2);
        textView = (TextView) findViewById(R.id.textView);
        Intent intent = getIntent();
        if (intent != null) {
            Person person = (Person) intent.getSerializableExtra("person");
            textView.setText(person.toString());
        }

    }
}
View Code

.Task与Back Stack(引自官方文档)

task 是一系列被操做的 activity 的集合,用户进行操做时将与这些 activity 进行交互。 这些 activity 按照启动顺序排队存入一个栈(即“back stack”)。咱们知道栈是一个后进先出的数据结构,在一个task中,每打开一个新的activity,就会将其压入栈顶的位置;每次点击Back键,栈顶的activity就会被移除.

大部分 task 都启动自 Home 屏幕。当用户触摸 application launcher 中的图标(或 Home 屏幕上的快捷图标)时,应用程序的 task 就进入前台。 若是该应用不存在 task(最近没有使用过此应用),则会新建一个 task,该应用的“main”activity 做为栈的根 activity 被打开。

当用户返回到 home屏幕执行另外一个 task 时,一个 task 被移动到后台执行,此时它的返回栈(back stack)也被保存在后台, 同时 android 为新 task 建立一个新的返回栈(back stack),当它被再次运行从而返回前台时,它的返回栈(back stack)被移到前台,并恢复其以前执行的activity,以下图所示。 若是后台有太多运行 task ,系统将会杀死一些 task 释放内存。

若是当前 activity 启动了另外一个 activity,则新的 activity 被压入栈顶并得到焦点。 前一个 activity 仍保存在栈中,可是被中止。activity 中止时,系统会保存用户界面的当前状态。 当用户按下返回键,则当前 activity 将从栈顶弹出(被销毁),前一个 activity 将被恢复(以前的用户界面状态被恢复)。 activity 在栈中的顺序永远不会改变,只会压入和弹出——被当前 activity 启动时压入栈顶,用户用返回键离开时弹出。 这样,back stack 以“后进先出”的方式运行。下图以时间线的方式展现了多个 activity 切换时对应当前时间点的 back stack 状态。

                                     

                图: task 中的每一个新 activity 都会相应在 back stack 中增长一项。当用户按下返回键时,

                  当前 activity 被销毁,前一个 activity 被恢复。

若是用户不停地按下返回键,则栈中每一个 activity 都会依次弹出,并显示前一个 activity,直至用户回到 Home 屏幕(或者任一启动该 task 的 activity)。 当全部 activity 都从栈中弹出后, task 就此消失。

.Activity启动模式(引自官方文档)

在 manifest 文件中声明 activity 时,你能够利用activity元素的launchMode属性来设定 activity 与 task 的关系。

launchMode 属性指明了 activity 启动 task 的方式。 launchMode 属性可设为四种启动模式:

 

standard(默认模式):
默认值。系统在启动 activity 的 task 中建立一个新的 activity 实例,并把 intent 传送路径指向它。该 activity 能够被实例化屡次,各个实例能够属于不一样的 task,一个 task 中也能够存在多个实例。

 singleTop:

若是 activity 已经存在一个实例并位于当前 task 的栈顶,则系统会调用已有实例的onNewIntent()方法把 intent 传递给已有实例,而不是建立一个新的 activity 实例。activity 能够被实例化屡次,各个实例能够属于不一样的 task,一个 task 中能够存在多个实例(但仅当 back stack 顶的 activity 实例不是该 activity 的)。
好比,假定 task 的 back stack 中包含了根 activity A 和 activities B、C、D(顺序是 A-B-C-D;D 在栈顶)。
这时过来一个启动 D 的 intent。若是 D 的启动模式是默认的"standard",则会启动一个新的实例,栈内容变为 A-B-C-D-D。
可是,若是 D 的启动模式是"singleTop",则已有的 D 实例会经过onNewIntent():接收这个 intent,由于该实例位于栈顶——栈中内容仍然维持 A-B-C-D 不变。固然,若是 intent 是要启动 B 的,则 B 的一个新实例仍是会加入栈中,即便 B 的启动模式是"singleTop"也是如此。 

注意: 一个 activity 的新实例建立完毕后,用户能够按回退键返回前一个 activity。 可是当 activity 已有实例正在处理刚到达的 intent 时,用户没法用回退键回到 onNewIntent() 中 intent 到来以前的 activity 状态。

singleTask:
系统将建立一个新的 task,并把 activity 实例做为根放入其中。可是,若是 activity 已经在其它 task 中存在实例,则系统会经过调用其实例的onNewIntent() 方法把 intent 传给已有实例,而不是再建立一个新实例。 此 activity 同一时刻只能存在一个实例。

注意: 虽然 activity 启动了一个新的 task,但用户仍然能够用回退键返回前一个 activity。

singleInstance:

除了系统不会把其它 activity 放入当前实例所在的 task 以外,其它均与"singleTask"相同。activity 老是它所在 task 的惟一成员;它所启动的任何 activity 都会放入其它 task 中。

举个例子,Android 的浏览器应用就把 web 浏览器 activity 声明为老是在它本身独立的 task 中打开——把 activity设为singleTask模式。 这意味着,若是你的应用提交 intent 来打开 Android 的浏览器,则其 activity 不会被放入你的应用所在的 task 中。 取而代之的是,或是为浏览器启动一个新的 task;或是浏览器已经在后台运行,只要把 task 调入前台来处理新 intent 便可。

不管 activity 是在一个新的 task 中启动,仍是位于其它已有的 task 中,用户老是能够用回退键返回到前一个 activity 中。 可是,若是你启动了一个启动模式设为singleTask的 activity,且有一个后台 task 中已存在实例的话,则这个后台 task 就会整个转到前台。 这时,当前的 back stack 就包含了这个转入前台的 task 中全部的 activity,位置是在栈顶。下图就展现了这种场景。

 

            

          图 . 启动模式为“singleTask”的 activity 如何加入 back stack 的示意图。 若是 activity 已是在后台 task 中并带有

            本身的 back stack,则整个后台 back stack 都会转入前台,并放入当前 task 的栈顶。

 

做者: caobotao
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接,不然保留追究法律责任的权利。