編輯:Android開發實例
一、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的基本生命周期如下代碼所示:
你自己寫的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>
注冊很多app或者網絡賬戶的時候,經常需要手機獲取驗證碼,來完成注冊,那時年少,只是覺得手機獲取驗
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
什麼是Android UDP? UDP是User Datagram Protocol的簡稱,中文名是用戶數據包協議,是OSI參考模型中一種無連接的傳輸層協議,提供
本文實例講述了Android實現文字和圖片混排(文字環繞圖片)效果。分享給大家供大家參考,具體如下: 在平時我們做項目中,或許有要對一張圖片或者某一個東西進行文字