[翻译]使用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阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • Intent 是一个消息传递对象,您可以使用它从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件...
    牧童遥指2000阅读 5,034评论 0 12
  • (1)闹钟 创建闹钟(ACTION_SET_ALARM)示例Intent: 注:为了调用ACTION_SET_AL...
    sunnygarden阅读 1,582评论 0 10
  • 初识Activity: 我们都知道android中有四大组件(Activity活动,Service服务,Conte...
    wangling90阅读 938评论 2 2
  • 远方 流浪歌手中流浪的方式有很多种,但他们有一个共同的特点——有多大的能力就走多远的路。 见过最美的风景,也不及那...
    ___神经质阅读 250评论 0 0
  • BuildConfig和资源 自从SDK工具版本升级到17之后,构建工具都会生成一个BuildConfig的类,该...
    kuwork阅读 3,353评论 0 4