第一卷 Activity

NightRain.png
1.1Activity是什麼?
Activity是一種可以包含使用者介面的元件,主要用於和使用者進行互動。一個應用程式可以有零個或者多個活動。
1.2基本使用
-
建立活動
建立java檔案 TestActivity
並繼承 AppCompatActivity
,重寫Activity的 onCreate
方法,如下:
public class TestActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
-
建立佈局並載入到活動中去
在res/layout目錄下建立佈局檔案 activity_test
,在 TestActivity
的 onCreate
方法中呼叫 setContentView()
方法,將我們建立的佈局檔案傳入次方法中即可,如下:
public class TestActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); } }
佈局檔案內容(一個簡單的按鈕)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TestActivity"> <Button android:id="@+id/btn_test_action_visible" android:text="顯示跳轉" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
-
在AndroidManifest檔案中註冊此活動
在Android中所有的活動都要在AndroidManifest檔案中進行註冊才可以使用。如下:
<activity android:name=".TestActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
注:在程式執行時必須要註冊一個主活動,這樣程式執行起來的時候才知道要首先啟動那一個活動!上面的示例程式碼就是一個標準的主活動程式碼,如果不是主活動,只需要 <activity android:name=".TestActivity"/>
就可以!
1.3活動的信使Intent
Intent是Android程式各元件之間互動的一種方式,它不僅可以指明當前元件要執行的動作,還可以在不同元件之間互相傳遞資料。Intent大致可以分為顯式Intent和隱式Intent,下面我們就分別看看。
-
使用顯式Intent進行跳轉
應用1.2中的方法,我們再建立一個活動 UseVisibleIntentActivity
,然後回到 TestActivity
中給按鈕設定一個點選事件,如下:
btn_test_action_visible.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent mIntent = new Intent(TestActivity.this, UseVisibleIntentActivity.class); startActivity(mIntent); } });
其中 btn_test_action_visible
就是我們在佈局檔案中放置的按鈕,通過 setOnClickListener()
方法設定監聽,在其 onClick()
回撥方法中即可處理我們的邏輯,這裡我們就設定一個跳轉。通過 new Intent()
獲取Intent例項,然後呼叫Activity的 startActivity()
即可!
注:
1、在活動中可以通過 findViewById()
獲取到佈局檔案中的元素,程式碼示例中的 R.id.btn_test_action_visible
就是來自activity_test佈局檔案中Button控制元件的id屬性。
2、Intent有多個建構函式的過載,其中一個是 Intent(Context packageContext, Class<?> cls)
其中引數一需要當前活動的上下文,引數二則是要指明需要啟動的目標活動。
-
使用隱式Intent進行跳轉
相對於顯式Intent,隱式Intent就顯得含蓄了許多,它沒有直接指明要啟動哪一個活動,而是指定了一系列action、category等資訊,經過系統分析,找出合適的活動並啟動。
通過以上的方法,繼續建立一個活動 UseUnvisibleIntentActivity
,並在 TestActivity
活動中在新增一個按鈕 btn_test_action_unvisible
,給按鈕設定點選事件,用隱式Intent跳轉 UseUnvisibleIntentActivity
活動。如下:
btn_test_action_unvisible.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent mIntent = new Intent(); mIntent.setAction("com.nightrain.firstvolume.useunvisibleintent"); startActivity(mIntent); } });
可以看到,我們並沒有在Intent的建構函式中指明需要跳轉的活動,但是在Intent中設定了一個動作 com.nightrain.firstvolume.useunvisibleintent
,而我們AndroidManifest檔案中同樣在UseUnvisibleIntentActivity活動的標籤下指定了這個動作:
<activity android:name=".UseUnvisibleIntentActivity"> <intent-filter> <action android:name="com.nightrain.firstvolume.useunvisibleintent"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
這樣就完成了我們的隱式跳轉!
-
使用Intent傳值
在啟動活動傳遞資料其實很簡單,Intent提供了一系列的 putExtra()
過載方法,可以傳遞各種資料,假如你想講 TestActivity
中的一個字串傳遞給 DelverActivity
活動,可以這樣編寫程式碼:
btn_test_action_delver.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String data = "我要給DelverActivity活動資料"; Intent mIntent = new Intent(TestActivity.this, DelverActivity.class); mIntent.putExtra("extra_data", data); startActivity(mIntent); } });
在 DelverActivity
活動中這樣接收資料:
String extra_data = getIntent().getStringExtra("extra_data"); Log.i(TAG, "onCreate: " + extra_data);
簡單的資料傳遞就完成 了
小妙招:
如果同一個活動會被其他活動同時使用到,這樣寫的話就會降低開發速度。因為每每有用到這個活動的位置就需要來看看這個活動需要什麼引數,讀程式碼、問同事。。。很麻煩。那麼,我們的小妙招就來了。在 DelverActivity
活動中寫一個靜態方法如下:
/** * 啟動活動 * * @param context 上下文 * @param data資料 */ public static void actionStart(Context context, String data) { Intent mIntent = new Intent(context, DelverActivity.class); mIntent.putExtra("extra_data", data); context.startActivity(mIntent); }
這樣不管多少人需要跳轉這個活動,呼叫這個靜態方法,然後傳對應的引數就可以!同時也簡化了 TestActivity
中的程式碼:
btn_test_action_delver.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String data = "我要給DelverActivity活動資料"; DelverActivity.actionStart(TestActivity.this,data); } });
-
返回資料給上一個活動
如果遇到需要返回資料給上一個活動這種需求,我們該怎麼做呢?
首先我們要在開啟這和活動時候改變一下方式,如下:
btn_test_action_delver.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String data = "我要給DelverActivity活動資料"; Intent mIntent = new Intent(TestActivity.this, DelverActivity.class); mIntent.putExtra("extra_data", data); startActivityForResult(mIntent, 100); } });
其他沒有變動,在開啟活動的時候我們不使用 startActivity()
方法,而是使用 startActivityForResult()
,這個方法多一個引數,是一個請求碼。
我們既然要給上一個活動傳資料,那麼在 DelverActivity
活動中也需要有所改變,如下:
Intent mIntent = new Intent(); mIntent.putExtra("back_data", "給上一個介面的資料"); setResult(RESULT_OK, mIntent); finish();
需要呼叫 setResult()
方法,這裡面需要一個響應碼,將封裝了資料的Intent也一併傳入,然後讓該活動出棧。接下來我們回到上一個介面,也就是 TestActivity
活動,重寫 onActivityResult()
方法,如下:
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); //請求碼 if (requestCode == 100) { //響應碼 if (resultCode == RESULT_OK) { if (data != null) { String back_data = data.getStringExtra("back_data"); Log.i(TAG, "onActivityResult: " + back_data); } } } }
小提示
按下手機上的bank鍵會回撥 onBackPressed()
方法!!!
1.4 返回棧
通過前面的練習,我們發現,在Android中,活動是可以疊加的。每每啟動一個新的活動,就會覆蓋在原來的活動上面,當銷燬這個活動的時候,原來的活動又會顯示出來。可以聯想到生活中東西裝箱子,最先裝的,取的時候就會是最後取出來,如果把這些“東西”比喻成活動的話,那麼這個箱子就是Android中的 返回棧 。
返回棧是一種後進先出的資料結構,在預設情況下,我們每啟動一個活動,它就會入棧,並處於棧頂。當按下back鍵或者finish這個活動後,這個活動就會出棧,而前一個入棧的活動就會重新處於棧頂的狀態。系統總會顯示處於棧頂的活動。
1.5 活動的四個狀態
每個活動在他的生命週期中最多可能會有四種狀態
- 執行狀態
當一個活動處於返回棧的棧頂時,這個活動就處於執行狀態。 - 暫停狀態
當一個活動不在棧頂,但是仍然是在可見的狀態的時候,這個活動就會進入暫停狀態。(當一個活動以Dialog形式開啟的時候,只會佔據螢幕中心的的部分割槽域,所以前一個活動還是可見的,此時,前一個活動已經不再棧頂的位置) - 停止狀態
當一個活動不再棧頂,也完全不可見的時候,這個活動就會進入停止狀態。 - 銷燬狀態
當一個活動從返回棧中移除的時候,這個活動就進入了銷燬的狀態。
1.6 活動的生命週期
- onCreate()
活動在第一次建立時呼叫。(建立) - onStart()
活動由不可見變為可見時呼叫。(介面可見) - onResume()
活動處於棧頂,可以可使用者互動的時候呼叫。(介面獲取焦點) - onPause()
活動不再棧頂的狀態下會呼叫。(介面失去焦點) - onStop()
活動完全不可見時呼叫。(介面不可見) - onDestroy()
活動在銷燬之前呼叫。(銷燬) - onRestart()
當活動重新回到棧頂的時候呼叫。(活動重新啟動)
1.7活動的啟動模式
- standard
Android預設的啟動模式,保持了先進後出的原則。它容許一個活動重複的入棧(例項會不同)。 - singleTop
當一個活動指定這種啟動模式的時候,如果這活動處於棧頂的時候,再去建立該活動不會有新的例項出現,系統會預設使用這一個活動。(此活動必須在棧頂的狀態,不然也會有新的例項入棧) - singleTask
當一個活動指定這種啟動模式的時候,每次建立該活動的時候,系統會在整個返回棧中尋找此活動,如果不存在就會入棧。反之,會將這個活動之上的所有活動出棧。 - singleinstance
使用這種模式建立活動,會啟動一個新的返回棧來管理這個活動。這也是一個比較難理解的一種模式。如果一個活動以這種模式啟動,那麼這個活動在 系統 內會是一個單例。也就是說這種單例是系統級的單例,不管那一個程式啟動這個活動,只會有這一個例項。