Activity 的启动和关闭
一个 Android 应用通常都会包含多个 Activity,但后只有一个 Activity 会作为程序的入口。其他的 Activity 都需要依赖入口 Activity 或者入口启动的其他 Activity 来启动。
Activity 启动其他 Activity 有如下两种方法:
startActivity(Intent intent):启动其它 Activity。
startActivityForResult(Intent intent, int requestCode):以指定请求码(requestCode)启动 Activity,而且程序将会得到新启动 Activity 的结果(重写onActivityResult(...)方法获取)。
上面两个方法都用到了 Intent 参数,Intent 是 Android 应用里各组件之间通信的重要方式,一个 Activity 通过 Intent 来表达自己的“意图”。(想要启动哪个组件,被启动的组件既可以是 Activity 组件,也可以是 Service 组件。
相对的,也有两个关闭Activity的方法对应这两个启动的方法:
finish():结束当前 Activity。
finishActivity(int requestCode):结束以 startActivityForResult(Intent intent, int requestCode) 方法启动的 Activity。
例1:在 Activity 中启动其他 Activity
StartActivity.java
<span style="font-family:Microsoft YaHei;">public class StartActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取应用程序中的bn按钮
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
// 创建需要启动的Activity对应的Intent
Intent intent = new Intent(StartActivity.this,
SecondActivity.class);
// 启动intent对应的Activity
startActivity(intent);
}
});
}
}</span>
SecondActivity.java
<span style="font-family:Microsoft YaHei;">public class SecondActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
// 获取应用程序中的previous按钮
Button previous = (Button) findViewById(R.id.previous);
// 获取应用程序中的close按钮
Button close = (Button) findViewById(R.id.close);
// 为previous按钮绑定事件监听器
previous.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
// 获取启动当前Activity的上一个Intent
Intent intent = new Intent(SecondActivity.this,
StartActivity.class);
// 启动intent对应的Activity
startActivity(intent);
}
});
// 为close按钮绑定事件监听器
close.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
// 获取启动当前Activity的上一个Intent
Intent intent = new Intent(SecondActivity.this,
StartActivity.class);
// 启动intent对应的Activity
startActivity(intent);
// 结束当前Activity
finish();
}
});
}
}</span>
例2:
startActivity()只有一个参数,如果需要向新打开的Activity传递参数,我们得换一个函数了, Android提供了startSubActivity(Intent,int)这个函数来实现这个功能。
函数原型为: public void startSubActivity(Intent intent, int requestCode)这里的requestCode用来标识某一个调用,一般由我们定义一个常量。
如何把参数传过去呢? Intent 类在提供 setClass() 函数的同时也提供了一个 setData() 函数。
函数原型为:public Intent setData(ContentURI data)。参数类型是 ContentURI,它的详细内容下回再分析,现在就把它当成一个 String 类型来用吧。参数带到新的 Activity 后,同样用 Activity.getIntent() 函数可以得到当前过来的 Intent 对象,然后用 getData() 就取到参数了。
把参数带回来的方法是 Activity.setResult(),它有几个形式,现在先看最简单的一个吧。
函数原型是:public final void setResult(int resultCode, String data)。resultCode 是返回代码,同样用来标识一个返回类型,而 data 则是它要返回的参数。在原来的 Activity 中的事件处理回调函数 onActivityResult,会被系统调用,从它的参数里可以得到返回值。
函数原型为:protected void onActivityResult(int requestCode, int resultCode,String data, Bundle extras)
这里的 requestCode 就是前面启动新 Activity 时的带过去的 requestCode,而 resultCode 则关联上了 setResult 中的 resultCode
,data 是参数,extras 也是一个很重要的东西,后面再研究一下它的作用。
如:
A-Activity 需要在 B-Activtiy 中执行一些数据操作,而 B-Activity 又要将执行操作数据的结果返回给 A-Activtiy
//看效果
<span style="font-family:Microsoft YaHei;">public class ActivityResultDemoActivity extends Activity
{
private Button button_start_task;
private TextView TextView_result;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button_start_task=(Button) findViewById(R.id.button_start_task);
TextView_result=(TextView) findViewById(R.id.TextView_result);
button_start_task.setOnClickListener(new button_start_task_Listener());
}
private class button_start_task_Listener implements OnClickListener
{
public void onClick(View v)
{
Intent intent=new Intent(ActivityResultDemoActivity.this,SimpleTaskActivity.class);
//关键点来了,使用startActivityForResult来启动
startActivityForResult(intent, 100);
}
}
/**
* 复写onActivityResult,这个方法
* 是要等到SimpleTaskActivity点了提交过后才会执行的
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//可以根据多个请求代码来作相应的操作
if(20==resultCode)
{
String bookname=data.getExtras().getString("bookname");
String booksale=data.getExtras().getString("booksale");
TextView_result.setText("书籍名称:"+bookname+"书籍价钱"+booksale+"元");
}
super.onActivityResult(requestCode, resultCode, data);
}
}</span>
<span style="font-family:Microsoft YaHei;">public class SimpleTaskActivity extends Activity
{
private EditText EditText_bookname;
private EditText EditText_booksale;
private Button Button_task_fulfill;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
EditText_bookname=(EditText) findViewById(R.id.EditText_bookname);
EditText_booksale=(EditText) findViewById(R.id.EditText_booksale);
Button_task_fulfill=(Button) findViewById(R.id.Button_task_fulfill);
Button_task_fulfill.setOnClickListener(new Button_task_fulfill_Listener());
}
private class Button_task_fulfill_Listener implements OnClickListener
{
public void onClick(View v)
{
String str_bookname=EditText_bookname.getText().toString();
String str_booksale=EditText_booksale.getText().toString();
//判断空,我就不判断了。。。。
Intent data=new Intent();
data.putExtra("bookname", str_bookname);
data.putExtra("booksale", str_booksale);
//请求代码可以自己设置,这里设置成20
setResult(20, data);
//关闭掉这个Activity
finish();
}
}
}
</span>
使用 Bundle 在 Activity 之间交换数据
当一个 Activity 启动另一个 Activity 时,常常要传递一些数据过去,就像 Web 应用从一个 Servlet 跳到另一个 Servelet 时,习惯把数据放入到 requestScope、sessionScope 中。而对于 Activity,在 Activity 之间进行数据交换更为简单,因为两个 Activity 之间本来就有一个“信使”:Intent,因此我们吧数据放到 Intent 中即可。<span style="font-family:Microsoft YaHei;"><?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="请输入您的注册信息"
android:textSize="20sp"
/>
<TableRow>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="用户名 :"
android:textSize="16sp"
/>
<!-- 定义一个EditText,用于收集用户的帐号 -->
<EditText
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="请填写想注册的帐号"
android:selectAllOnFocus="true"
/>
</TableRow>
<TableRow>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="密码 :"
android:textSize="16sp"
/>
<!-- 用于收集用户的密码 -->
<EditText
android:id="@+id/passwd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="true"
android:selectAllOnFocus="true"
/>
</TableRow>
<TableRow>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="性别 :"
android:textSize="16sp"
/>
<!-- 定义一组单选框,用于收集用户注册的性别 -->
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"
android:textSize="16sp"
/>
<RadioButton
android:id="@+id/female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"
android:textSize="16sp"
/>
</RadioGroup>
</TableRow>
<Button
android:id="@+id/bn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册"
android:textSize="16sp"
/>
</TableLayout></span>
BundleTest.java
<span style="font-family:Microsoft YaHei;">public class BundleTest extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bn = (Button) findViewById(R.id.bn);
bn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
EditText name = (EditText)findViewById(R.id.name);
EditText passwd = (EditText)findViewById(R.id.passwd);
RadioButton male = (RadioButton) findViewById(R.id.male);
String gender = male.isChecked() ? "男 " : "女";
Person p = new Person(name.getText().toString(), passwd
.getText().toString(), gender);
// 创建一个Bundle对象
Bundle data = new Bundle();
data.putSerializable("person", p);
// 创建一个Intent
Intent intent = new Intent(BundleTest.this,
ResultActivity.class);
intent.putExtras(data);
// 启动intent对应的Activity
startActivity(intent);
}
});
}
}</span>
result.xml
<span style="font-family:Microsoft YaHei;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<!-- 定义三个TextView,用于显示用户输入的数据 -->
<TextView
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/passwd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/gender"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
</LinearLayout></span>
ResultBundle.java
<span style="font-family:Microsoft YaHei;">public class ResultActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
TextView name = (TextView) findViewById(R.id.name);
TextView passwd = (TextView) findViewById(R.id.passwd);
TextView gender = (TextView) findViewById(R.id.gender);
// 获取启动该Result的Intent
Intent intent = getIntent();
// 直接通过Intent取出它所携带的Bundle数据包中的数据
Person p = (Person) intent.getSerializableExtra("person");
name.setText("您的用户名为:" + p.getName());
passwd.setText("您的密码为:" + p.getPass());
gender.setText("您的性别为:" + p.getGender());
}
}</span>