編輯:高級開發
一、Activity 簡介
在android開發中Activity非常重要,在一個應用中,每一個顯示的屏幕都是一個Activity.所以學習android,必須要對Activity有一定的了解.
activity類處於android.app包中,繼承體系如下:
1.Java.lang.Object
2.android.content.Context
3.android.app.ApplicationContext
4.android.app.Activity
activity是單獨的,用於處理用戶操作。幾乎所有的activity都要和用戶打交道,所以activity類創建了一個窗口,開發人員可以通過 setContentView(VIEw)接口把UI放到activity創建的窗口上,當activity指向全屏窗口時,也可以用其他方式實現:作為漂浮窗口(通過windowIsFloating的主題集合),或者嵌入到其他的activity(使用ActivityGroup)。大部分的 Activity子類都需要實現以下兩個接口:
onCreate(Bundle)接口是初始化activity的地方. 在這兒通常可以調用setContentVIEw(int)設置在資源文件中定義的UI, 使用findVIEwById(int) 可以獲得UI中定義的窗口.
onPause()接口是使用者准備離開activity的地方,在這兒,任何的修改都應該被提交(通常用於ContentProvider保存數據).
為了能夠使用Context.startActivity(),所有的activity類都必須在androidManifest.XML文件中定義有相關的“activity”項。
activity類是android 應用生命周期的重要部分。
簡單的例子:
/Chapter05_Activity_Creation/src/com/amaker/test/MainActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextVIEw;
// 繼承Activity
public class MainActivity extends Activity {
// 聲明要使用的組件
private TextView myTextVIEw;
private Button myButton;
// 覆蓋onCreate方法
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設置當前視圖
setContentVIEw(R.layout.main);
// 通過findVIEwById() 方法實例化組件
接上頁
myTextView = (TextView) findViewById(R.id.TextVIEw01);
myButton = (Button) findVIEwById(R.id.Button01);
}
}
布局文件
/Chapter05_Activity_Creation/res/layout/main.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
< TextVIEw android:id="@+id/TextVIEw01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="簡單的Activity">< /TextVIEw>
< Button android:text="Click Me!"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /Button>
< /LinearLayout>
清單文件
/Chapter05_Activity_Creation/androidManifest.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< manifest XMLns:android="http://schemas.android.com/apk/res/android"
package="com.amaker.test"
android:versionCode="1"
android:versionName="1.0">
< application android:icon="@drawable/icon" android:label="@string/app_name">
< activity android:name=".MainActivity"
android:label="@string/app_name">
< intent-filter>
< action android:name="android.intent.action.MAIN" />
< category android:name="android.intent.category.LAUNCHER" />
< /intent-filter>
< /activity>
< /application>
< uses-sdk android:minSdkVersion="3" />
< /manifest>
二、啟動一個Activity
一個activity可以啟動另外一個,甚至包括與它不處於同一應用程序之中的。舉個例子說,假設你想讓用戶看到某個地方的街道地圖。而已經存在一個具有此功能的activity了,那麼你的activity所需要做的工作就是把請求信息放到一個Intent對象裡面,並把它傳遞給startActivity()。於是地圖浏覽器就會顯示那個地圖。而當用戶按下BACK鍵的時候,你的activity又會再一次的顯示在屏幕上。
接上頁
android將這兩個activity放在同一個任務中來維持一個完整的用戶體驗。簡單的說,任務就是用戶所體驗到的“應用程序”。它是安排在一個堆棧中的一組相關的activity。堆棧中的根activity就是啟動了這整個任務的那個──一般情況下,它就是用戶在應用程序加載器中所選擇的。而堆棧最上方的activity則是當前運行的──用戶直接對其進行操作的。當一個activity啟動另外一個的時候,新的activity就被壓入堆棧,並成為當前運行的activity。而前一個activity仍保持在堆棧之中。當用戶按下BACK鍵的時候,當前activity出棧,而前一個恢復為當前運行的activity。
activity相當於web開發中的頁面,從一個頁面跳轉到另外的一個頁面。
小例子:
/Chapter05_Activity_StartActivity/src/com/amaker/test/FirstActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
public class FirstActivity extends Activity {
/** Called when the activity is first created. */
private Button b1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.first);
b1 = (Button) findVIEwById(R.id.Button01);
// 響應按鍵事件
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(VIEw v) {
// 顯示方式聲明Intent,直接啟動SecondActivity
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
}
/Chapter05_Activity_StartActivity/src/com/amaker/test/SecondActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.content.Intent;
接上頁
import android.os.Bundle;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
public class SecondActivity extends Activity {
/** Called when the activity is first created. */
private Button b2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.second);
b2 = (Button) findVIEwById(R.id.Button02);
// 響應按鍵事件
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(VIEw v) {
// 顯示方式聲明Intent,直接啟動SecondActivity
Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
startActivity(intent);
}
});
}
}
布局文件
/Chapter05_Activity_StartActivity/res/layout/first.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
< Button android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Activity">< /Button>
< /LinearLayout>
/Chapter05_Activity_StartActivity/res/layout/second.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
< Button android:id="@+id/Button02"
接上頁
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="返回">< /Button>
< /LinearLayout>
三、Activity之間傳遞數據
如何在Activity中調用另一個Activity,但若需要在調用另外一個Activity的同時傳遞數據,那麼就需要 利用android.os.Bundle對象封裝數據的能力,將欲傳遞的數據或參數,通過Bundle來傳遞不同Intent之間的數據。 相當於web開發中用session等等進行參數傳遞一樣。
利用Intent傳遞數據
傳遞數據的Activity中:
Intent intent = new Intent();
intent.putExtra("name","Jon");//在Intent中加入鍵值對數據。鍵:name,值:Jon
intent.setClass(Activity01.this,Activity02.class);
Activity01.this.startActivity(intent);
在取出數據的Activity中:
Intent intent = getIntent();//獲得傳過來的Intent。
String value = intent.getStringExtra("name");//根據鍵name取出值。
利用Bundle傳遞數據
傳遞數據的Activity:
Intent intent = new Intent();
Bundle myBundle = new Bundle();
myBundle.putString("Key_Name","Tom");
intent.putExtras(myBundle);
intent.setClass(Activity01.this,Activity02.class);
Activity01.this.startActivity(intent);
取出數據的Activity:
Bundle getBundle = getIntent().getExtras();
String value = getBundle.getString("Key_Name");
利用startActivityForResult傳遞數據
startActivityForResult可以把數據傳過去,還可以把那邊的數據傳過來。
傳遞數據的Activity中:
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("data", "somedata");//把數據傳過去
intent.putExtras(bundle);
intent.setClass(Activity01.this, Activity02.class);
startActivityForResult(intent, 10);//10是一個代碼
重載onActivityResult方法,用來接收傳過來的數據:
protected void onActivityResult(int requestCode, int resultCode,Intent
接上頁
intent) {
switch (resultCode) {
case RESULT_OK:
Bundle b = intent.getExtras();
String str = b.getString("Result");
setTitle("Return data:" + str);
break;
default:
break;
}
}
接收數據的Activity:
Intent intent = getIntent();
Bundle getBundle = getIntent().getExtras();
String data = getBundle.getString("data");//讀取傳過來的數據
et.setText(data);
EditText edittext = (EditText) findVIEwById(R.id.text);
Intent intent = new Intent();//實例化一個Intent用來傳過去,可以在Intent裡存放數據。
Bundle bundle = new Bundle();
bundle.putString("Result",edittext.getText().toString());
intent.putExtras(bundle);
Activity02.this.setResult(RESULT_OK,intent);//把Intent(數據)傳過去,RESULT_OK是請求碼。
finish();//結束當前的Activity。
四、啟動一個Activity並返回結果
使用startActivityForResult()方法
實例:
/Chapter05_Activity_StartActivityForResult/src/com/amaker/test/MainActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
private EditText username,passWord;
private Button b1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
b1 = (Button)findVIEwById(R.id.Button01);
b1.setOnClickListener(new OnClickListener() {
接上頁
@Override
public void onClick(VIEw v) {
username = (EditText)findVIEwById(R.id.username);
password = (EditText)findVIEwById(R.id.passWord);
String str_username = username.getText().toString();
String str_password = passWord.getText().toString();
Bundle b = new Bundle();
b.putString("username", str_username);
b.putString("password", str_passWord);
Intent intent = new Intent(MainActivity.this,NextActivity.class);
intent.putExtras(b);
startActivityForResult(intent, 1);
}
});
}
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
Log.i("requestcode", requestCode+"-----------");
Log.i("resultCode", resultCode+"-----------");
Bundle b = data.getExtras();
String str_username = b.getString("username");
String str_password = b.getString("passWord");
System.out.println(str_username);
Log.i("abc", data.getStringExtra("abc"));
username.setText(str_username);
password.setText(str_passWord);
}
}
/Chapter05_Activity_StartActivityForResult/src/com/amaker/test/NextActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
public class NextActivity extends Activity {
private Button b2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.next);
b2 = (Button)findVIEwById(R.id.Button02);
接上頁
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(VIEw v) {
Intent intent = getIntent();
intent.putExtra("abc", "test");
NextActivity.this.setResult(5, intent);
NextActivity.this.finish();
}
});
}
}
/Chapter05_Activity_StartActivityForResult/res/layout/main.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
< TextVIEw
android:text="用戶名稱:"
android:id="@+id/TextVIEw01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /TextVIEw>
< EditText
android:text=""
android:id="@+id/username"
android:layout_width="fill_parent"
android:layout_height="wrap_content">< /EditText>
< TextVIEw
android:text="用戶密碼:"
android:id="@+id/TextVIEw02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>< /TextVIEw>
< EditText
android:text=""
android:id="@+id/passWord"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:passWord="true"
>< /EditText>
< Button
android:text="下一步"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /Button>
< /LinearLayout>
/Chapter05_Activity_StartActivityForResult/res/layout/next.XML
接上頁
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
< TextVIEw
android:text="Email:"
android:id="@+id/email"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /TextVIEw>
< EditText
android:text=""
android:id="@+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="wrap_content">< /EditText>
< TextVIEw
android:text="Mobile:"
android:id="@+id/mobile"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /TextVIEw>
< EditText
android:text=""
android:id="@+id/EditText02"
android:layout_width="fill_parent"
android:layout_height="wrap_content">< /EditText>
< Button
android:text="上一步"
android:id="@+id/Button02"
android:layout_width="wrap_content"
android:layout_height="wrap_content">< /Button>
< /LinearLayout>
五、Activity的生命周期
和其他手機平台的應用程序一樣,android的應用程序的生命周期是被統一掌控 的,也
就是說我們寫的應用程序命運掌握在別人(系統)的手裡,我們不能改變它,只能學習並
適應它。
簡單地說一下為什麼是這樣:我們手機在運行一個應用程序的時候,有可能打進來電話
發進來短信,或者沒有電了,這時候程序都會被中斷,優先去服務電話的基本功能,另
外系統也不允許你占用太多資源,至少要保證電話功能吧,所以資源不足的時候也就有可
能被干掉。
言歸正傳,Activity的基本生命周期如下代碼所示:
接上頁
1. public class MyActivity extends Activity {
2. protected void onCreate(Bundle savedInstanceState);
3.
4. protected void onStart();
5.
6. protected void onResume();
7.
8. protected void onPause();
9.
10. protected void onStop();
11.
12. protected void onDestroy();
13. }
public class MyActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
你自己寫的Activity會按需要 重載這些方法,onCreate是免不了的,在一個Activity正常啟動的過程中,他們被調用的順序是 onCreate -> onStart -> onResume, 在Activity被干掉的時候順序是onPause -> onStop -> onDestroy ,這樣就是一個完整的生命周期,但是有人問了 ,程序正運行著呢來電話了,這個程序咋辦?中止了呗,如果中止的時候新出的一個Activity是全屏的那麼:onPause->onStop ,恢復的時候onStart->onResume ,如果打斷 這個應用程序的是一個Theme為Translucent 或者Dialog 的Activity那麼只是onPause ,恢復 的時候onResume 。
詳細介紹一下這幾個方法中系統在做什麼以及我們應該做什麼:
onCreate: 在這裡創建界面,做一些數據的初始化工作
onStart: 到這一步變成用戶可見不可交互 的
onResume: 變成和用戶可交互 的,(在activity棧系統通過棧的方式管理這些個
Activity的最上面,運行完彈出棧,則回到上一個Activity)
onPause: 到這一步是可見但不可交互 的,系統會停止動畫等消耗CPU 的事情
從上文的描述已經知道,應該在這裡保存你的一些數據,因為這個時候
你的程序的優先級降低,有可能被系統收回。在這裡保存的數據,應該在
onResume裡讀出來,注意:這個方法裡做的事情時間要短,因為下一
個activity不會等到這個方法完成才啟動
onstop: 變得不可見 ,被下一個activity覆蓋了
接上頁
onDestroy: 這是activity被干掉前最後一個被調用方法了,可能是外面類調用finish方
法或者是系統為了節省空間將它暫時性的干掉,可以用isFinishing()來判
斷它,如果你有一個Progress Dialog在線程中轉動,請在onDestroy裡
把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會拋
異 常 的。
onPause,onstop, onDestroy,三種狀態下 activity都有可能被系統干掉
為了保證程序的正確性,你要在onPause()裡寫上持久層操作的代碼,將用戶編輯的內容都保存到存儲介質上(一般都是數據庫)。實際工作中因為生命周期的變化而帶來的問題也很多,比如你的應用程序起了新的線程在跑,這時候中斷了,你還要去維護那個線程,是暫停還是殺掉還是數據回滾,是吧?因為 Activity可能被殺掉,所以線程中使用的變量和一些界面元素就千萬要注意了,一般我都是采用android的消息機制[Handler, Message]來處理多線程和界面交互的問題。
/Chapter05_Activity_LifeCycle/src/com/amaker/test/MainActivity.Java
代碼
package com.amaker.test;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button b1;
private static final String TAG="lifecycle";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
Log.i(TAG, "onCreate------------------------------>");
b1 = (Button)findVIEwById(R.id.Button01);
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(VIEw v) {
MainActivity.this.finish();
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart------------------------------>");
接上頁
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart------------------------------>");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume------------------------------>");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause------------------------------>");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop------------------------------>");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy------------------------------>");
}
}
/Chapter05_Activity_LifeCycle/res/layout/main.XML
代碼
< ?XML version="1.0" encoding="utf-8"?>
< LinearLayout XMLns:android="http://schemas.android.com/apk/res/android"
android:orIEntation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
< TextVIEw
android:id="@+id/TextVIEw01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="??Activity的生命咛期">< /TextVIEw>
< Button android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="劫束Activity">< /Button>
< /LinearLayout>
android開源平台一詞的本義指“機器人”,是美國搜索引擎公司Google在2007年11月5日公布的基於Linux平台的開源智能手機操作系統名稱。該平台由操作系統、
上周,谷歌宣布將不會把android 3.0發布到開源社區,而android 3.1計劃很可能在今年造成轟動。android 3.1 Steve Jobs(史蒂夫·喬布
“android智能手機的技術結構比較緊湊,市場推進有張有馳,再加上谷歌公司長期具備的創新精神,確實值得國內很多廠商信賴。”前述分析師沈哲怡表示。北京時間1月16日消息
最近,關於Adobe在android平台上動作頻頻。昨天我們報道了Android版Flash 10.1發布 全面支持android 2.2的消息,今天又有消息稱,Ado