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>