[翻譯]使用intent的activity之間的交互

原文:Intentを用いたActivity間のやりとり

翻譯前的廢話:因為不熟悉intent-filter和intent,調bug時浪費了很多時間,這篇也就是在官方文檔的技術上,有個淺顯但是實用的解釋。

調用activity

intent與startActivity

從當前activity去調用其他activity的過程是,創建intent、作為參數傳入startActibity()來調用。intent分為Explicit intents(明確的intent)與 Implicit intents(隱性的intent),相關詳細內容請直接參考官方文檔。
隱性的intent,比如想打開指定的url的情況:(譯注:總之就是沒有指明本app中activity名的情況

Uri uri = Uri.parse("http://www.bar.com/hoge");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

調用activity時的數據設定

startActivity()之前可以設定intent中的Extra。這次以明確的intent為例:

/**調用端*/
import android.content.Intent;
...
Intent intent = new Intent(this, SubActivity.class);
intent.putExtra("foo", someData);
startActivity(intent);
/**被調用端*/
import android.content.Intent;
...
Intent intent = getIntent();
String someData = intent.getStringExtra("foo"); // someData是String的情況
SomeData someData = (SomeData) intent.getSerializableExtra("foo"); // Serializable用implement封裝后,自定義格式的數據也可以傳遞
Bundle args = intent.getExtras(); // 傳遞的Extra通過Map形式全部取得

被其他actibity調用

intent-filter

通過前面說的startActivity()、隱性的intent形式被調用的場合,必須在AndroidManifest.xml里定義intent-filter:

<activity
    android:name="com.example.android.hoge"
    android:label="@string/foo">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="https" android:host="www.bar.com" />
    </intent-filter>
</activity>

想接受隱性的intent的場合一定要設定android.intent.category.DEFAULT的category。原因是把隱性的intent傳遞進startActivity()或者startActivityForResult()以調用其他activity時,默認作為CATEGORY_DEFAULT來處理,要是intent-filter里沒有對應的category系統就認為是不合適的intent而不進行處理。

Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity.

通過隱性的intent被調用的區別

通過隱性的intent被調用的場合,應該有指定intent里的URL,取出這個URL并判斷會比較好:

Intent intent = getIntent();
Uri uri = intent.getData();
if uri == null {
  Log.d("test", "這是app里明確的Intent");
} else {
  Log.d("test", uri.toString());
}

(譯注:p.s. Uri uri = intent.getData(); 注意根據activity的lauchMode,除了standard以外另外三個屬性會可能調用onNewIntent()而不是onCreate()來更新activity)

Try to override onNewIntent. The problem is that getIntent
returns the Intent that started the Activity, but not the most recent one. But you can override it using setIntent method.

因此需要重載onNewIntent():

@Override
protected void onNewIntent(Intent intent) { 
  super.onNewIntent(intent); 
  setIntent(intent);
}

限制調用activity

因為安全的原因要限制其他的activity的調用,或者需要確認那些啟動調用的activity。就會使用下面的兩種方式。

android:exported設定false

AndroidManifest.xml的activity的設定里,android:exported設定false的話,其他activity的component無法調用該activity:

AndroidManifest.xml
<activity
    android:name="com.example.android.foo.SomeActivity"
    android:label="@string/app_name"
    android:exported="false">

API Guides的官方說明:

android:exported
Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.

Activity.getCallingActibity()取得啟動調用的activity

使用Activity.getCallingActivity()的話,就可以知道startActivityForResult()的調用元。(startActivity()的話就還是不知道哦。) (譯注:getCallingActivity()返回依舊是null。寶寶就在這里調了好久~

參考文檔

Intents and Intent Filters
activity

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容

  • (1)鬧鐘 創建鬧鐘(ACTION_SET_ALARM)示例Intent: 注:為了調用ACTION_SET_AL...
    sunnygarden閱讀 1,654評論 0 10
  • 初識Activity: 我們都知道android中有四大組件(Activity活動,Service服務,Conte...
    wangling90閱讀 994評論 2 2
  • 遠方 流浪歌手中流浪的方式有很多種,但他們有一個共同的特點——有多大的能力就走多遠的路。 見過最美的風景,也不及那...
    ___神經質閱讀 259評論 0 0
  • BuildConfig和資源 自從SDK工具版本升級到17之后,構建工具都會生成一個BuildConfig的類,該...
    kuwork閱讀 3,423評論 0 4
  • 七點左右,五歲的孩子在被窩睡得正香。 快起來了,快起來了,不然會遲到啦!急促,焦燥的催促聲出自一個聲音粗魯的男聲。...
    雪莉詩話閱讀 368評論 10 3