Android学习笔记(七)

活动的启动模式

活动的启动模式一共有四种,分别是standard、singleTop、singleTask和singleInstance,

可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式。

standard模式

standard模式是活动默认的启动模式。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,

每次启动都会创建该活动的一个新的实例。

在ActivityTest项目中,修改FirstActivity中onCreate()的方法,代码如下所示:

protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        Log.d("FirstActivity", this.toString());
        //隐藏标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //在活动中加载布局,使用setContentView()方法
        setContentView(R.layout.first_layout);

        Button button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(new OnClickListener(){
            public void onClick(View v){

                Intent intent = new Intent(FirstActivity.this,FirstActivity.class);
                startActivity(intent);

            }
        });
    }

上述的代码,在FirstActivity的基础上启动FirstActivity。运行程序,然后在FirstActivity界面连续点击两次按钮,可以看到LogCat打印的信息如下图所示:

从打印的信息中,可以看出每点击一次按钮就会创建一个新的FirstActivity实例。此时返回栈中存在三个FirstActivity的实例,需要连续按三次Back键才会退出程序。

singleTop模式

当活动的启动模式是singleTop模式时,在启动活动的时候如果发现返回栈的栈顶已经是该活动,

则可以直接使用它,不会在创建新的活动的实例。

修改AndroidManifest.xml中FirstActivity的启动模式,代码如下:

<activity
            android:name=".FirstActivity"
            android:label="this is Firstactivity"
            android:launchMode="singleTop" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

重新运行程序,查看LogCat的打印信息,如下图所示:

在打印出来的信息中,只有一个FirstActivity的实例,此时无论按几次按钮,都不会有新的打印信息出现。

因为当前FirstActivity已经处于返回栈的栈顶,每当在启动一个FirstActivity时都会直接使用栈顶的活动。

不过当FirstActivity并未处于栈顶位置时,这时再启动FirstActivity,还会创建新的实例。

singleTask模式

在singleTop模式中,如果FirstActivity不在栈顶时,这是如果要启动FirstActivity时还需要创建FirstActivity的实例。

如果只想活动在整个程序上下文中只存在一个实例时,就要使用singleTask模式来实现。

当活动的启动模式指定为singleTask时,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,

如果发现存在则直接使用,并把在这个活动之上的所有活动统统出栈;如果发现没有就会创建一个新的活动实例。

修改AndroidManifest.xml中FirstActivity的启动模式,代码如下:

<activity
            android:name=".FirstActivity"
            android:label="this is Firstactivity"
            android:launchMode="singleTask" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

重新运行程序,查看LogCat打印的日志信息,如下图所示:

从打印信息可以看出,在SecondActivity中启动FirstActivity时,会发现返回栈中已经存在一个FirstActivity的实例,

并且在SecondActivity的下面,于是SecondActivity会从返回栈中出栈,而FirstActivity重新成为了栈顶活动,

所以FirstActivity的onStart()方法和SecondActivity的onDestroy()方法会得到执行。

singleInstance模式

指定为singleInstance模式的活动会启动一个新的返回栈来管理这个活动。每个应用程序都会有自己的返回栈,

同一个活动在不同的返回栈中入栈时必然是创建了新的实例。

使用singleInstance模式可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,

不管哪个应用来访问这个活动,都共用同一个返回栈。

修改AndroidManifest.xml文件中SecondActivity的启动模式,代码如下:

<activity
            android:name=".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>

代码中将SecondActivity的启动模式设为singleInstance,然后修改FirstActivity中onCreate()方法的代码,代码如下:

protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        Log.d("FirstActivity", "Task id is " + getTaskId());
        //隐藏标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //在活动中加载布局,使用setContentView()方法
        setContentView(R.layout.first_layout);

        Button button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(new OnClickListener(){
            public void onClick(View v){

                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);

            }
        });
    }

在onCreate()方法中打印当前返回栈的id,然后修改SecondActivity中onCreate()方法的代码,代码如下:

protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d("SecondActivity", "Task id is " + getTaskId());
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.second_layout);
        Button button2 = (Button)findViewById(R.id.button_2);
        button2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);

                startActivity(intent);

            }
        });

    }

同样在onCreate()方法中打印当前返回栈的id,然后修改按钮点击事件的代码,用于启动ThirdActivity。

最后修改ThirdActivity中onCreate()方法的代码,代码如下:

protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d("ThirdActivity", "Task id is " + getTaskId());
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.third_layout);
    }

在onCreate()方法中打印当前返回栈的id。重新运行程序,在FirstActivity界面上点击按钮进入SecondActivity,

然后在SecondActivity界面点击按钮进入ThirdActivity。查看LogCat的打印信息,得到下图所示:

从打印信息中可以看到,SecondActivity的Task id与FirstActivity和ThirdActivity的不相同,

这就说明SecondActivity是放在一个单独的返回栈中。在ThirdActivity界面,按下Back键会直接回到FirstActivity界面,

再按下Back键又会返回到SecondActivity,再按下Back键才会退出程序。

原因是ThirdActivity和FirstActivity在同一个返回栈中,当从ThirdActivity界面按下Back键,

ThirdActivity会从返回栈中出栈,那么FirstActivity就成了栈顶活动而显示在界面上。

然后在FirstActivity界面再次按下Back键,这时当前的返回栈已经空了,于是就显示了另一个返回栈的栈顶活动,即SecondActivity。

时间: 2024-08-07 04:33:36

Android学习笔记(七)的相关文章

android学习笔记七——控件(DatePicker、TimePicker、ProgressBar)

DatePicker.TimePicker ==> DatePicker,用于选择日期 TimePicker,用于选择时间 两者均派生与FrameLayout,两者在FrameLayout的基础上提供了一些方法来获取用户所选日期.时间: 程序中如果需要获取用户选择的日期.时间,可通过添加DataPicker添加OnDataChangeListener进行监听,为TimePicker添加OnTimeChangeListener进行监听. 实例——略 进度条==> ProgressBar.标题进度

Android学习笔记七:调用打电话、发短信等

系统打电话界面: Intent intent = new Intent(); //系统默认的action,用来打开默认的电话界面 intent.setAction(Intent.ACTION_CALL); //需要拨打的号码 intent.setData(Uri.parse("tel:"+i)); callPhoneAndSendMessage.this.startActivity(intent); 系统发短信界面: Intent intent = new Intent(); //系统

七、Android学习笔记_JNI hello world

1.需要准备的工具,eclipse,cdt(c++)插件,cygwin(unix)和 android ndk. 在cygwin的etc目录下将ndk的路径引入到profile文件中,可以在cygwin的任何目录都可以访问到ndk,不同的ndk路径PATH的写法不同. : ${ORIGINAL_PATH=${PATH}} if [ ${CYGWIN_NOWINPATH-addwinpath} = "addwinpath" ] ; then PATH="/usr/local/bi

Android学习笔记(七)——显示对话框窗口

显示对话框窗口 1.创建Dialog1项目,在activity_main.xml文件中添加一个Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:l

Android学习笔记(四七):Content Provider初谈和Android联系人信息

Content Provider 在数据处理中,Android通常使用Content Provider的方式.Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据的增.删.改.查的操作.Android并不提供所有应用共享的数据存储,采用content Provider,提供简单便捷的接口来保持和获取数据,也可以实现跨应用的数据访问.简单地说,Android通过content Provider从数据的封装中获取信息. Content provider使用Uri

【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 之前,我们直接在activity中执行http通信,在通信过程中可能会出现连接超时.socket超时等情况,超时阈值一般是秒级,例如AndroidHttpClient中设置的20秒,如果出现超时,就

【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 应用有时需要从web中下载一个大文件,并保存在本地,这个操作过程是标准的,因此在Android2.3引入了DownloadManager类.相关的学习也可以参考Android学习笔记(四六):互联网通信-文件下载. 小例子 先看一个小例子,如下图所示.lay

【转】Pro Android学习笔记(七):了解Content Provider(下上)

我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,author,created_date和modified_date几列.我们通过一个名为BookProvider的内容提供者将数据源运行封装,并对外提供增删改查的接口. 首先:定义Content Provider的结构 创建一个Provider,我们首先需要定义好这个provider的结构.通过consta

【转】 Pro Android学习笔记(七六):服务(1):local和remote

文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的组件,没有UI,独立于activity的生命周期.有两种类型的服务:local services和remote services.本地服务是只能被本应用调用,而远端服务则可以被其他应用调用.远端服务通过AIDL(Android Interface Definition Language)描述.在服务

【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用service提供很多功能,例如利用Google Maps API,现在我们将聚焦在HTTP serice中. Android SDK提供HttpClient,和J2EE中的接口非常相似.最常用的就是HTTP GET和HTTP POST.相关内容也可以阅读Android学习笔记(四五):互联网通信-Htt