您的位置:首页 > 其它

Intents and Intent Filters

2016-07-27 16:07 357 查看
Intents 分为显示Intents和隐士intents

1:显示的Intents举例如下:一般用于启动特定的app 组件,如下例就是启动downloaderservice。

Intent downloadIntent = new Intent(this, DownloadService.class);

downloadIntent.setData(Uri.parse(fileUrl));

startService(downloadIntent);

2:隐士的Intents不指定类名,而是指定满足某种条件就可以,当然符合条件的activity或者service 可能有好几个,这个时候系统就会弹出一个对话框,让用户自己选择。

Intent sendIntent = new Intent();

sendIntent.setAction(Intent.ACTION_SEND);

sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);

sendIntent.setType("text/plain");

这样当所有在manifest中定义ACTION_SEND 的activity 或者service 都会响应这个Intent。但是如果没有一个activit或者service响应,你的app可能就要crash掉,所以我们一般先查询是否有activity 响应这个Intent,如果有响应,在发送,就像下面这样.

// Create the text message with a string

Intent sendIntent = new Intent();

sendIntent.setAction(Intent.ACTION_SEND);

sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);

sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity

if (sendIntent.resolveActivity(getPackageManager()) != null) {

    startActivity(sendIntent);

}

其中intent.resolveactivity 会调用pm.resolveactiviy 开查询是否有符合的activity.

/frameworks/base/core/java/android/content/Intent.java

5790    public ComponentName resolveActivity(PackageManager pm) {

5791        if (mComponent != null) {

5792            return mComponent;

5793        }

5794

5795        ResolveInfo info = pm.resolveActivity(

5796            this, PackageManager.MATCH_DEFAULT_ONLY);

5797        if (info != null) {

5798            return new ComponentName(

5799                    info.activityInfo.applicationInfo.packageName,

5800                    info.activityInfo.name);

5801        }

5802

5803        return null;

5804    }

而activity的信息是在安装的时候由PMS parse 出来。后面在详细分析.

如果有多个activity响应的话,可以弹出一个对话框让用户选择,sample code 如下:

Intent sendIntent = new Intent(Intent.ACTION_SEND);

// 选择Android 默认的chooser,也可以客制化

String title = getResources().getString(R.string.chooser_title);

// Create intent to show the chooser dialog

Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity

if (sendIntent.resolveActivity(getPackageManager()) != null) {

    startActivity(chooser);

}

resolveactivity 最终在ActivityStackSupervisor.java实现。重点是869行会向packagemanager 查询是否有符合的intent

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,

864            ProfilerInfo profilerInfo, int userId) {

865        // Collect information about the target of the Intent.

866        ActivityInfo aInfo;

867        try {

868            ResolveInfo rInfo =
869                AppGlobals.getPackageManager().resolveIntent(

870                        intent, resolvedType,

871                        PackageManager.MATCH_DEFAULT_ONLY

872                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);

873            aInfo = rInfo != null ? rInfo.activityInfo : null;

874        } catch (RemoteException e) {

875            aInfo = null;

876        }

877

878        if (aInfo != null) {

879            // Store the found target back into the intent, because now that

880            // we have it we never want to do this again.  For example, if the

881            // user navigates back to this point in the history, we should

882            // always restart the exact same activity.

883            intent.setComponent(new ComponentName(

884                    aInfo.applicationInfo.packageName, aInfo.name));

885

886            // Don't debug things in the system process

887            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {

888                if (!aInfo.processName.equals("system")) {

889                    mService.setDebugApp(aInfo.processName, true, false);

890                }

891            }

892

893            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {

894                if (!aInfo.processName.equals("system")) {

895                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);

896                }

897            }

898

899            if (profilerInfo != null) {

900                if (!aInfo.processName.equals("system")) {

901                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);

902                }

903            }

904        }

905        return aInfo;

906    }

intent filters 有两种方式注册,一种是在manifest文件中静态注册如下所示:只要action是send的intend 都会被myactivity 接收到.

<activity android:name="MyActivity">

    <intent-filter>

        <action android:name="android.intent.action.SEND"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:mimeType="text/plain"/>

    </intent-filter>

</activity>

第二种方式是在java code中动态注册.

546        final IntentFilter filter = new IntentFilter();

547

548        filter.addAction(Intent.ACTION_TIME_TICK);

549        filter.addAction(Intent.ACTION_TIME_CHANGED);

550        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);

552        getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());

注册三个action.

有两个action 需要额外主要:

ACTION_MAIN:这个是aplication的入口activity,不接收任何intent data。

CATEGOTY_LAUNCHER : 这个会把activity的icon放到桌面(launch)。

这两个必须按顺序放好,才能让activity在桌面上显示图标

pending intent:

pending intent 是intent的一个包装,其设计的目的是让其他process的application 有权限启动其他process的activity,service,broadcast,就像在自己process 一样.

主要由三种用途:

notification,alarmManager或者app wiget 的时候可以可以传递一个pending intent,这样当用户点击的时候其他一个activity,service,broadcast.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: