美文网首页Android札记技能get翻译·译文
【译文】通过 android:ssp 高效过滤 Android

【译文】通过 android:ssp 高效过滤 Android

作者: zerob13 | 来源:发表于2014-09-06 01:48 被阅读454次

    翻译自 chris.orr 译文最早发布于 伯乐在线

    我发现在Android 4.4(API level 19) 中<data>标签增加了一个新的没有在文档中记录的 XML 属性,而这个属性是用来过滤 intent 的。

    android:ssp属性旨在比对URI,顾名思义 "ssp" 是 "scheme-specific part"的缩写,也就是说 URI 中除了 scheme 以外的所有剩下的内容。

    举个例子,如果我们有个一个 URI 内容是

    "https://example.com/foo/bar"

    那么这个 URI 的 scheme 是 https ,而它的 ssp 则是
    "//example.com/foo/bar"

    但事实上,这个属性一般不会用来匹配例子中所说的常规 HTTP URL,因为我们已经有了 android:host 以及 android:path* 这样的方便好用的过滤器去解决这个问题。ssp 这个过滤则是让我们更高效的去监控一些特定的 intent 事件。

    实际问题

    Android 的 Broadcast Receiver 的机制是保证你的 App 收到系统各类信息通知的好方法,无论你的应用是否启动,你都可以接收到系统的 Broadcast。比如,当前网络的状态,电池电量低等等。

    另一方面,由于许多不同的 App 可能会注册同一个高频率的事件,这就导致了系统有可能会同时唤起很多进程,这会让你的系统变的很慢。

    举个常见的例子就是当你安装,升级以及卸载应用的时候往往会引起系统的卡顿。这个问题原因呢,显然是许多带统计SDK的应用都试图去监控和报告当前机器中app的安装和卸载情况,一般来说需要接收的 Broadcast Receiver 就如同下文所示的代码那样:

    <receiver android:name=".PackageReceiver">
      <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED" />
        <data android:scheme="package" />
      </intent-filter>
    </receiver>
    

    可以注意到的一点是,我们其实往往只是对一部分的事件有兴趣,比如说 URI 是类似于 "package:com.example.someapp" 。但由于这个 URI 并不是一个层次结构的 URI ,它并没有 host ,port 抑或 path 这些信息,我们是没有办法精确的指定需要监控的包的,所以每次有 Package 相关的操作时监听的 App 都会被唤醒!

    巧用 android:ssp

    到了 Android 4.4 ,我们可以是使用 scheme-specific 部分来匹配 URI,只需要利用 android:ssp , android:sspPrefix 以及 android:sspPattern 这三个属性就可以做到。
    还是以上面的 Package 事件做例子,我们现在可以指定特定的一个或几个我们有兴趣的包来进行监控。

    比如说,我的 app 拥有三个不同的 package ID 分别给开发版,beta版以及正式版。那么我们可以通过如下的方式去匹配这三个 app :

    <receiver android:name=".DataClearedReceiver">
      <intent-filter>
        <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
        <data android:scheme="package"
              android:sspPrefix="com.myswitzerland.hotels" />
       </intent-filter>
    </receiver>
    

    这样,只有包含特定 Package URL 的 intent 才会换起我们 App 并且触发Broadcast Receiver了。如果是其他的 App 的包操作,我们的应用并不会被唤起,简直太棒了!

    当然,这个也可以用在其他的无层次结构的 URI 比如 mailto 或者 tel 这种。

    再举一个稍有不同的例子,我们可以通过这个手法来截获特定的邮件地址的intent,让用户选择我们特定的 Activity,而不是用系统默认的邮件客户端。

    <activity android:name=".PremiumSupportActivity">
      <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="mailto"
              android:sspPattern="support-.*@example.com" />
       </intent-filter>
    </activity>
    

    有趣的是,SSP 属性目前并没有在 <data> 的官方文档中提及,但是在 IntentFilter 文档中有提到这个属性的 Java 等效实现。

    所以,我们也可以在代码中动态来注册这样的 Intent:

    IntentFilter pkgFilter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
    pkgFilter.addDataScheme("package");
    pkgFilter.addDataSchemeSpecificPart("com.example.someapp",
                                        PatternMatcher.PATTERN_LITERAL);
                             
    

    这些例子在 Android 4.4 上可以正常使用,但请放心他们在低版本的 Android 上也是安全的,低版本的系统会自动忽略掉这个不支持的属性。

    最后,如果你有想到其他使用 scheme-specific 来提高匹配的应用点,欢迎来告知我。

    相关文章

      网友评论

        本文标题:【译文】通过 android:ssp 高效过滤 Android

        本文链接:https://www.haomeiwen.com/subject/eyvytttx.html