標籤:
什麼是Intent
對於一個應用,他會有多個活動,活動之間的跳轉資料傳遞可以通過Intent來實現。Intent 是 Android 程式中各組件之間進行互動的一種重要方式,它不僅可以指明當前組件想要執行的動作,還可以在不同組件之間傳遞資料。Intent 一般可被用於啟動活動、啟動服務、以及發送廣播等情境。
使用Intent使用顯式Intent
對現在修改FirstActivity中按鈕的點擊事件,代碼如下:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent); }});
首先我們建立了一個Intent,傳入FirstActivity.this,作為上下文,傳入Second.class作為目標活動,這樣我們的意圖就是就在FirstActivity這個活動中點擊button然後開啟SecondActivity這個活動,然後通過startActivity()方法來執行這個Intent。
對這種方式的Intent意圖很明顯,所以稱為顯式Intent。
使用隱式Intent
相比於顯式 Intent,隱式 Intent 則含蓄了許多,它並不明確指出我們想要啟動哪一個活動,而是指定了一系列更為抽象的 action 和 category 等資訊,然後交由系統去分析這個 Intent。
通過在標籤下配置的內容,可以指定當前活動能夠響應的action和 category,開啟 AndroidManifest.xml,添加如下代碼:
<activity android:name=".SecondActivity" > <intent-filter> <action android:name="com.example.activitytest.ACTION_START" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
action標籤中我們指明了活動SecondActivity可以響應com.example.activitytest.ACTION_START這個action,而category標籤包含了附加資訊(注意,action只能有一個,category可以有多個),更加精確指明了當前活動響應哪一個Intent。只有action和category中的內容同時能夠匹配上Intent中指定的action和category時,這個活動才能響應Intent。
修改FirstActivity中按鈕的點擊事件代碼如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.activitytest.ACTION_START"); startActivity(intent); }});
這裡我們指定了action為com.example.activitytest.ACTION_START,但是我們並沒有指定category。因為android.intent.category.DEFAULT是一種預設的category,我們在AndroidManifest.xml中代碼如下所示:
<activity android:name=".SecondActivity"> <intent-filter> <action android:name="com.example.activitytest.ACTION_START" /> <category android:name="android.intent.category.DEFAULT"/> <category android:name="com.example.activitytest.MY_CATEGORY"/> </intent-filter> </activity>
所以雖然我們在FirstActivity按鈕點擊事件代碼裡沒有指定category,但是我們在.xml檔案中註冊了預設的category,所以會響應這個活動。
更多隱式Intent的用法
使用隱式Intent,我們不僅可以啟動自己程式內的活動,還可以啟動其他程式的活動。這使得多個程式間的功能共用成為可能。
現在修改FirstActivity中按鈕點擊事件代碼,如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com")); startActivity(intent); }});
這裡我們指定了Intent的action為Intent.ACTION_VIEW,這是android系統內建的動作,常量值為android.intent.action.VIEW。通過Uri.parse()方法,可以將一個網址的字串解析成為一個Uri對象,在調用Intent的setData()方法,將這個Uri對象傳入。
點擊button會開啟內建的瀏覽器訪問百度。
當然我們也可以在intent-filter標籤中配置data標籤,用於指定當前活動能夠響應什麼類型的資料。現在我們建立一個布局和活動,並且他的註冊時data標籤指定為http協議。那麼當我們有一個事件他的action和category和我們建立的對應,並且事件協議是http,那麼我們也會響應這個活動。
除了http協議外,還有geo表示地理位置,tel表示撥打到電話等。
向下一個活動傳遞資料
之前都是關於Intent啟動活動,Intent還可以啟動活動的時候傳遞資料。
Intent 中提供了一系列 putExtra()方法的重載,可以把我們想要傳遞的資料暫存在 Intent 中,啟動了另一個活動後,只需要把這些資料再從Intent 中取出就可以了。
現在在FirstActivity活動中有一個字串,現在要把這個字串傳遞到SecondActivity中,FirstActivity代碼如下:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String data = "Hello SecondActivity"; Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("extra_data", data); startActivity(intent); }});
這裡我們用顯示的方式啟動SecondActivity,通過putExtra()方法傳遞一個字串。putExtra()方法中第一個參數為鍵,第二個為值。
在SecondActivity中擷取傳遞過來的值:
public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.second_layout); Intent intent = getIntent(); String data = intent.getStringExtra("extra_data"); Log.d("SecondActivity", data); }}
getIntent()方法可以活動啟動當前活動的Intent,然後調用getStringExtra()方法來擷取資料。如果傳遞過來的值為整型,那麼用getIntExtra(),其餘類型類似。
返回資料給上一個活動
我們可以傳遞資料給下一個活動那麼我們當然可以返回資料給上一個活動。
Activity 中還有一個 startActivityForResult()方法也是用於啟動活動的,但這個方法期望在活動銷毀的時候能夠返回一個結果給上一個活動。
startActivityForResult()方法也是用於啟動活動的,但這個方法期望在活動銷毀的時候能夠返回一個結果給上一個活動。第二個參數是請求碼,SecondActivity活動銷毀後會回調當前活動的onActivityResult()方法,該方法第一個參數就是指定了這個請求碼。
我們修改FirstActivity中按鈕的點擊事件,代碼如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivityForResult(intent, 1); }});
接下來我們在SecondActivity 中給按鈕註冊點擊事件,並在點擊事件中添加返回資料的邏輯,代碼如下所示:
public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.second_layout); Button button2 = (Button) findViewById(R.id.button_2); button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("data_return", "Hello FirstActivity"); setResult(RESULT_OK, intent); finish(); } }); }}
這裡我們new了一個Intent,但是沒有指定任何意圖,因為這個Intent僅僅用於傳遞資料。這裡調用了setResult()方法,這個方法是用於向上一個活動返回資料的。它有2個參數,第一個參數用於向上一個活動返回處理結果, 一般只使用RESULT_OK 或 RESULT_CANCELED 這兩個值;第二個參數則是把帶有資料的 Intent 傳遞迴去。
因為我們使用了startActivityForResult()方法來啟動當前活動,所以當前活動銷毀後,會回調上一個活動的onActivityResult()方法,因此我們需要寫如下代碼:
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (resultCode == RESULT_OK) { String returnedData = data.getStringExtra("data_return"); Log.d("FirstActivity", returnedData); } break; default: }}
該方法有3個參數,第一個參數表示請求碼,可能有多個返回的資料,請求碼就可以一一對應,第二個參數是返回資料時候的處理結果,是RESULT_OK或者RESULT_CANCELED,第三個參數就是帶有資料的Intent。
如果使用者在 SecondActivity 中並不是通過點擊按鈕,而是通過按下Back 鍵回到 FirstActivity,我們可以通過重寫 onBackPressed()方法來解決這個問題,代碼如下所示:
@Overridepublic void onBackPressed() { Intent intent = new Intent(); intent.putExtra("data_return", "Hello FirstActivity"); setResult(RESULT_OK, intent); finish();}
這樣的話,當使用者按下 Back 鍵,就會去執行 onBackPressed()方法中的代碼,效果和之前點擊button是一樣的。
到這裡學習了Intent。
安卓學習之Intent