[翻译]使用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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • (1)闹钟 创建闹钟(ACTION_SET_ALARM)示例Intent: 注:为了调用ACTION_SET_AL...
    sunnygarden阅读 5,646评论 0 10
  • 初识Activity: 我们都知道android中有四大组件(Activity活动,Service服务,Conte...
    wangling90阅读 4,587评论 2 2
  • 远方 流浪歌手中流浪的方式有很多种,但他们有一个共同的特点——有多大的能力就走多远的路。 见过最美的风景,也不及那...
    ___神经质阅读 1,768评论 0 0
  • BuildConfig和资源 自从SDK工具版本升级到17之后,构建工具都会生成一个BuildConfig的类,该...
    kuwork阅读 8,774评论 0 4
  • 七点左右,五岁的孩子在被窝睡得正香。 快起来了,快起来了,不然会迟到啦!急促,焦燥的催促声出自一个声音粗鲁的男声。...
    雪莉诗话阅读 2,895评论 10 3