Activity加载模式及数据传递

Activity的启动方式有两种,一种是应用程序启动时默认启动,另一种是通过Intent启动。

在做Activity生命周期的实验的时候,我们发现在通过Intent做页面切换的时候新启动的Activity会覆盖到原来的Activity之上,销毁新的Activity后,原来的Activity就会出现,我们知道这是因为Activity栈的关系,其实还与Activity的加载模式有关。

Android是采用Task来管理多个Activity的,当我们启动一个应用时,Android就会为之创建了一个Task,然后启动这个应用入口的Activity。关于Tast,Android并没有为Task提供API,因此开发者无法真正访问Task,只能调用Activity的getTaskId()方法来获取它所在的Task的ID。我们可以把Task理解成Activity栈,Task以栈的样式来管理Activity,先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。

Activity的加载模式就是指Activity与Task之间的加载关系。真正的开发中,我们并不希望出现像那种新启动的Activity退出后原来的Activity又出现,如果要启动很多个Activity,那么逐个退出就会逐个显示。Activity加载模式的控制就是解决Activity大量重复创建或过多的问题。

Activity启动方式有四种,分别是:standard、singleTop、singleTask、singleInstance。配置Activity的加载模式需要在配置文件<activity>标签内设置属性launchMode,格式如下

<activity

           android:name=".FirstActivity"

           android:label="@string/app_name"

           android:launchMode="standard"></activity>

1.standard默认模式

一般创建Activity类会自动配置属性,但不会出现launchMode的属性,其实正是默认模式,默认模式可以不写出来。默认模式即是这种无限覆盖,按栈回退的模式,值得注意的是,Activity允许在自己的界面重新创建自己,默认模式下,新创建的Activity就会出来覆盖自己,再创建再覆盖。如下一个简单例子,点击按钮跳转到A界面,操作:A0->A1->A2,回退A2->A1->A0。

布局文件如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.FirstActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New A"
        android:onClick="newA" />
    <TextView 
        android:id="@+id/A_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>

</LinearLayout>

配置文件如下

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.briup.activity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FirstActivity"
            android:label="@string/app_name" 
            android:launchMode="standard">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Activity类文件如下,我们定一个静态属性,每新建一个Activity就加1

 

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

public class FirstActivity extends Activity {
	private static int A = 0;
	private TextView aTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_first);
		aTv = (TextView) findViewById(R.id.A_tv);
		aTv.setText("A-Num:"+A++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
}

效果如下

 

2.singleTop栈顶单例模式

如果当前Activity已经存在,那么不允许再次创建,即不允许在Activity上创建相同的Activity,而如果通过当前为栈顶单例模式的Activity创建了一个默认模式的Activity,再通过默认模式的Activity创建栈顶单例模式的Activity是允许的,回退也是按栈回退。如下一个简单的例子,操作:无论点几次跳转A页面的按钮都不会有跳转,A0->B0->A1,回退A1->B0->A0。

布局文件如下

第一个界面 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.FirstActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New A"
        android:onClick="newA" />
    <TextView 
        android:id="@+id/A_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New B"
        android:onClick="newB"/>

</LinearLayout>

第二个界面 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.SecondActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="new A"
        android:onClick="newA" />
	<TextView 
        android:id="@+id/B_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>
    
</LinearLayout>

配置文件如下

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.briup.activity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FirstActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop">p
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
    </application>

</manifest>

Activity类文件如下

第一个

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

public class FirstActivity extends Activity {
	private static int A = 0;
	private TextView aTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_first);
		aTv = (TextView) findViewById(R.id.A_tv);
		aTv.setText("A-Num:"+A++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newB(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
}

第二个

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

public class SecondActivity extends Activity {
	private static int B = 0;
	private TextView bTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		bTv = (TextView) findViewById(R.id.B_tv);
		bTv.setText("B-NUM:"+B++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
}

效果如下

 



3.singleTask栈内单例模式

如果想要创建过Activity已经创建过,也允许界面跳转到该界面,但是回退发现之前创建过的Activity被移动到最上面,并且连带销毁中间其他的Activity。如下一个实例,操作:无论点几次跳转A页面的按钮都不会有跳转,A0->B0->A0,我们发现再通过B界面的按钮跳转A界面,我们设置的静态属性没有增加,也就是说还是那个Activity,回退后应用程序就退出了,可见中间创建的B界面已经被销毁了;再进行A0->B0->C0->B1->A0,同样的,回退A界面,中间三个界面并没有回退却已经被销毁。

布局文件如下

第一个界面 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.FirstActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New A"
        android:onClick="newA" />
    <TextView 
        android:id="@+id/A_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New B"
        android:onClick="newB"/>
	<Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="New C"
        android:onClick="newC"/>
    
</LinearLayout>

第二个界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.SecondActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="new A"
        android:onClick="newA" />
	<TextView 
        android:id="@+id/B_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>
	<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="new C"
        android:onClick="newC" />
    
</LinearLayout>

第三个界面

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activity.ThirdActivity" >
	<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="new A"
        android:onClick="newA" />
	<TextView 
        android:id="@+id/C_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"/>
	<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="new B"
        android:onClick="newB" />

</LinearLayout>

配置文件如下

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.briup.activity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FirstActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
        <activity
            android:name=".ThirdActivity"
            android:label="@string/title_activity_third" >
        </activity>
    </application>

</manifest>

Activity类文件如下

第一个

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

public class FirstActivity extends Activity {
	private static int A = 0;
	private TextView aTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_first);
		aTv = (TextView) findViewById(R.id.A_tv);
		aTv.setText("A-Num:"+A++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newB(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
	public void newC(View v){
		Intent intent = new Intent(this,ThirdActivity.class);
		startActivity(intent);
	}
}

第二个

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

public class SecondActivity extends Activity {
	private static int B = 0;
	private TextView bTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		bTv = (TextView) findViewById(R.id.B_tv);
		bTv.setText("B-NUM:"+B++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newC(View v){
		Intent intent = new Intent(this,ThirdActivity.class);
		startActivity(intent);
	}
}

第三个

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

public class ThirdActivity extends Activity {
	private static int C = 0;
	private TextView cTv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_third);
		cTv = (TextView) findViewById(R.id.C_tv);
		cTv.setText("C-NUM:"+C++);
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newB(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
}

效果如下





4.singleInstance全局单例模式

如果Activity被设为全局单例模式,那么它在创建时Android会给它单个提供一个Task栈,再创建别的Activity会被加入到另外一个Activity栈(以上三种模式下,所有Activity均处于同一个栈)。那么这样会有什么样的效果呢,首先它不能重复创建,其他栈中的Activity启动它也不会新建而是直接跳转,回退它只会出现一次,因为它只有一个。如下面一个例子,操作A0->B0->C0->A0->C1->B1->A0,回退A0->B1-C1->C0->B0,可见A的栈与B、C是相互独立,我们看到在切换界面的时候切换到A界面的动画都不一样了。(为什么要先进入C,因为两个Tast栈切换时,如果直接切换栈顶界面就会新建,如果不是栈顶就会弹到栈顶界面)我们在每个Activity中加入日志输出,表明它们的TaskID,这样就能验证它们属于不同的Task栈。

布局文件与上一个例子相同。

配置文件如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.briup.activity"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FirstActivity"
            android:label="@string/app_name"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
        <activity
            android:name=".ThirdActivity"
            android:label="@string/title_activity_third" >
        </activity>
    </application>

</manifest>

Activity类文件如下

第一个

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

public class FirstActivity extends Activity {
	private static int A = 0;
	private TextView aTv;
	private static final String TAG = "briup";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_first);
		aTv = (TextView) findViewById(R.id.A_tv);
		aTv.setText("A-Num:"+A++);
	}
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Log.i(TAG, "FirstActivity:"+getTaskId());
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newB(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
	public void newC(View v){
		Intent intent = new Intent(this,ThirdActivity.class);
		startActivity(intent);
	}
}

第二个

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

public class SecondActivity extends Activity {
	private static int B = 0;
	private TextView bTv;
	private static final String TAG = "briup";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		bTv = (TextView) findViewById(R.id.B_tv);
		bTv.setText("B-NUM:"+B++);
		Log.i(TAG, "SecondActivity:"+getTaskId());
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newC(View v){
		Intent intent = new Intent(this,ThirdActivity.class);
		startActivity(intent);
	}
}

第三个

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

public class ThirdActivity extends Activity {
	private static int C = 0;
	private TextView cTv;
	private static final String TAG = "briup";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_third);
		cTv = (TextView) findViewById(R.id.C_tv);
		cTv.setText("C-NUM:"+C++);
		Log.i(TAG, "ThirdActivity:"+getTaskId());
	}
	public void newA(View v){
		Intent intent = new Intent(this,FirstActivity.class);
		startActivity(intent);
	}
	public void newB(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		startActivity(intent);
	}
}

效果如下

 






日志输出如下

 

可以看到A的栈ID与BC是不同的。

 

Activity中Activity间的数据传递是依靠Intent的putExtra()方法完成的。这个方法功能非常强大,可以传递字符串、数组、数字类型、对象、图片等等。(要传递对象需要实现Serializable接口)

putExtra()需要一个标记自己的String类型和一个数据作为参数,可以通过getStringExtra(),getIntExtra()等方法获取数据。

有时候,我们希望传递一定的数据到另一个界面,由这个界面返回数据,可以通过startActivityForResult()方法传递数据,它需要一个标记的int类型参数(请求码),下一个界面可以通过setResult()方法传回数据,也需要一个标记的int类型参数(结果码),传递数据的界面需要通过onActivityResult(int requestCode, int resultCode, Intent data)方法接受传回数据。下面做一个简单的实例进行测试

布局文件如下

第一个界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activitystart.MainActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="GotoSecond"
        android:onClick="gotoSecond" />
	<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="GotoThird"
        android:onClick="gotoThird" />
    
</LinearLayout>

第二个界面

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activitystart.SecondActivity" >
	
	<Button 
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Copy That"
	    android:onClick="back"
	    android:layout_centerInParent="true"/>
</RelativeLayout>

第三个界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.briup.activitystart.ThirdActivity" >

    <ImageView 
        android:id="@+id/third_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/third_tv1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />
	<TextView
        android:id="@+id/third_tv2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />
    
</LinearLayout>

Activity类文件如下

第一个

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
	private Bean b;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		b = new Bean("德莱厄斯", 40, "诺克萨斯");
	}
	public void gotoSecond(View v){
		Intent intent = new Intent(this,SecondActivity.class);
		intent.putExtra("name", "Testing,do you copy?");
		startActivityForResult(intent,1);//请求码
	}
	public void gotoThird(View v) {
		Intent intent = new Intent(MainActivity.this,ThirdActivity.class);
		intent.putExtra("name", "德莱文");
		intent.putExtra("age", 20);
		intent.putExtra("bean", b);
		Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);//位图
		intent.putExtra("bitmap", bitmap);
		startActivity(intent);
	}
		
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// 接收数据方法
		super.onActivityResult(requestCode, resultCode, data);
		if(requestCode==1&&resultCode==1){
			String name = data.getStringExtra("data");
			Toast.makeText(MainActivity.this, name, Toast.LENGTH_LONG).show();
		}
	}
}

第二个

 

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

public class SecondActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		Intent intent = getIntent();
		Toast.makeText(this, intent.getStringExtra("name"), Toast.LENGTH_LONG).show();
	}
	public void back(View v){
		Button b = (Button) v;
		Intent intent = new Intent();
		intent.putExtra("data", b.getText().toString());
		setResult(1, intent);//结果码
		finish();//要想让第一个界面收到信息必须销毁这个界面,否则无法收到,如果通过跳转等于重新创建了第一界面,和这个界面的联系就是新的了
	}
}

第三个

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

public class ThirdActivity extends Activity {
	private TextView thirdTv1,thirdTv2;
	private ImageView thirdIv;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_third);
		thirdTv1 = (TextView) findViewById(R.id.third_tv1);
		thirdTv2 = (TextView) findViewById(R.id.third_tv2);
		thirdIv = (ImageView) findViewById(R.id.third_iv);
		
		Intent intent = getIntent();//拿到上一层传递的意图
		if(intent!=null){
			String name = intent.getStringExtra("name");//接收字符串
			int age = intent.getIntExtra("age", 18);//接收整数,18为默认值,若没有传过值就使用默认值,可不填
			thirdTv1.setText("字符串-name= "+name+"\n整数-age= "+age);
			
			Bean b = (Bean) intent.getSerializableExtra("bean");//接受对象
			thirdTv2.setText("对象:\n"+b.toString());
			
			Bitmap bitmap = intent.getParcelableExtra("bitmap");//接收位图
			thirdIv.setImageBitmap(bitmap);
		}
	}
}

Bean类文件如下

 

import java.io.Serializable;

public class Bean implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	private String desc;
	public Bean(String name, int age, String desc) {
		super();
		this.name = name;
		this.age = age;
		this.desc = desc;
	}
	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 getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	public static long getSerialversionuid() {
		return serialVersionUID;
	}
	@Override
	public String toString() {
		return "Bean [name=" + name + ", age=" + age + ", desc=" + desc + "]";
	}

}

效果如下

 




在Activity的运行过程中有时会由于Activity的原因导致数据丢失,Android为Activity准备了两个方法来保存和恢复数据onSaveInstanceState和onRestoreInstanceState。

那么这来你两个方法什么时候执行呢?当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。

何为“容易”呢?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。这种可能性有哪些?通过重写一个activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我们可以清楚地知道当某个activity(假定为activity A)显示在当前Task的最上层时,其onSaveInstanceState方法会在什么时候被执行,有这么几种情况:

1、当用户按下HOME键时。

这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则

2、长按HOME键,选择运行其他的程序时。

3、按下电源按键(关闭屏幕显示)时。

4、从activity A中启动一个新的activity时。

5、屏幕方向切换时,例如从竖屏切换到横屏时。

在屏幕切换之前,系统会销毁activityA,在屏幕切换之后系统又会自动地创建activity A,所以onSaveInstanceState一定会被执行。

总而言之,onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据。

至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的,onRestoreInstanceState被调用的前提是,activity A“确实”被系统销毁了,而如果仅仅是停留在有这种可能性的情况下,则该方法不会被调用,例如,当正在显示activity A的时候,用户按下HOME键回到主界面,然后用户紧接着又返回到activity A,这种情况下activity A一般不会因为内存的原因被系统销毁,故activity A的onRestoreInstanceState方法不会被执行。

另外,onRestoreInstanceState的bundle参数也会传递到onCreate方法中,你也可以选择在onCreate方法中做数据还原,我们关于数据传递的例子都是在onCreate方法中执行的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值