Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> android基本程序單元Activity

android基本程序單元Activity

編輯: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的基本生命周期如下代碼所示:

 
  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.   }   

 

   你自己寫的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>
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved