Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

xzw 2019-06-21

简介:

 首先声明本篇文章所属并不是一个常见问题,而是多个问题综合才会出现,很有可能你出现的问题并不适于本片文章且本片文章也不会解决您的问题.

 使用过分享的同学们 都知道,在分享成功或取消之后,你的应用程序 也会知道分享的结果,但是这个结果是如何传递到,大家所定义的回调中的,可能大家就不太清楚了

 今天我所碰到的问题,就和 这个机制有关

 这个机制就是 Android 的 Intent Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

 好吧虽然同是 Intent 但是所说的并不是我们常用的 Intent 跳转,但是其实我们每天都能见到他

 他就是 intent-filter ,在我们写一个app的时候也一定会加入一个 intent-filter那就是

<intent-filter>
      <action android:name="android.intent.action.MAIN" />

      <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

 已知在开发app时所有的 Activity,都需要在AndroidManifest.xml中声明和配置

 当前我们加入的Intent-filter 既是在我们启动应用的时候,标识应用的启动页

 而我现在碰到的问题既是因为某一个Intent 跳转被错误的拦截了, 而具体是什么问题还要从结果说起

一.错误结果:

 首先是未出错状态,这个页面是错误入口界面,其中有5个不同的分享按钮

Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

 然后是出错时的效果这个错误只有在 执行微博分享的时候才会出现(所有分享走的都是相同的封装方法)

 而朋友圈,微信,QQ,QQ空间都没有出现这个错误

Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

 首先先来看一下两种打开方式的结果:

 左:

Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

解释:左边的选择结果 从界面上看来似乎没有什么区别,但是仔细看会发现这和一开始选择的界面并不一样;

   左边为一个分享选择的 Dialog,而其实当时这个类中并没有任何关于这个Dialog 的代码.

 右:

Android 集成友盟分享 由一个错误的 intent-filter 引发的诡异问题

 解释:简单明了如图所示,一个空的Activity,一开始以为是因为报错崩溃导致的白屏,后证实并不是,并不会自动跳转且对返回键有正常的响应

二.错误环境:

 1.使用友盟SDK集成分享.

 2.正在进行SDK更新,从5.x版本,更新至 6.x+

 3.只有新浪微博的分享出现错误

 4.debug模式,无法通过Key校验,故没弹出分享界面(其中经过测试,问题与此无关,且错误出现与是否分享或成功与否无关)

 5.并未正确的回调分享回调

三.错误分析:

 经过部分测试之后发现出现问题的时间点和方式和回调非常相似,故而开始排查分享回调的配置,经过排查和与文档对照后并未发现错误

 且同一个方法中的微信和QQ都没有出现此问题

 继而从错误结果入手,分析两种打开方式出现的原因,当研究了友盟SDK中的回调机制后发现右侧方式中弹出的Activity

 很有可能就是友盟用来接收微博分享回调结果的 WBShareCallBackActivity

 查看源码发现在源码中onCreate方法中接收了传入的Intent,并在处理后,在相同方法中进行了 finish操作

 源码:

protected void onCreate(Bundle var1) {
    super.onCreate(var1);
    Log.um("WBShareCallBackActivity");
    UMShareAPI var2 = UMShareAPI.get(this.getApplicationContext());
    this.a = (SinaSimplyHandler)var2.getHandler(SHARE_MEDIA.SINA);
    Log.e(this.b, "handleid=" + this.a);
    this.a.onCreate(this, PlatformConfig.getPlatform(SHARE_MEDIA.SINA));
    if(this.getIntent() != null) {
        this.a(this.getIntent());
    }
}

public void a(BaseResponse var1) {
    if(this.a != null) {
        this.a.onResponse(var1);
    }

    this.finish();
}

 在思考了友盟回调逻辑后发现了这个错误出现的关键问题,也是这里要说的重点 ,上文所说的 intent-filter

 在这里多提一嘴友盟的大致的分享流程

 首先在代码中确定分享的参数等(略)

 第二步调用SDK中的方法,唤起对应分享的供应商(新浪微博app)

 经过分享逻辑后(略),由供应商页面 发起隐式Intent跳转

 当前项目中注册的 用于接收跳转的Activity 会接收到此Intent

 当Activity接收Intent后会打开,但在上述源码中的Create方法中,会在处理后finish掉Activity 所以在界面上只要处理速度正常是看不到页面打开的

 当接收回调数据的 Activity被关闭后,应为此Activity 在项目中,且在接收回调上层,故会执行发起分享页面中的 onActivityResult方法

 在onActivityResult 中的SDK方法会将参数等传给并调用分享回调(代码中所注册的回调),完成回调效果

<activity
        android:name="com.xxx.xxx.WBShareActivity"
        android:configChanges="keyboardHidden|orientation"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

 上述代码中的action name: com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY 既是用来接收Intent的标识

 这也是官方SDK中给出的写法

 这里附上一个对intent-filter的大致解释 http://blog.csdn.net/cnnumen/...

 其实这里基本可以定位错误所在了,既是在分享结果返回跳转时,有多个可接受此Action 的组件注册在项目中的 AndroidManifest.xml中

 并最终导致打开方式弹窗的出现,不过此处选择正确的Activity,并不能触发相应的代码,不知为何

4.解决问题:

 以ACTION_SDK_REQ_ACTIVITY为条件检索整个manifest发现:

<!-- 分享选择页面 -->
    <activity
        android:name="com.xxx.xxx.dialog.ShareDialog"
        android:screenOrientation="portrait"
        android:theme="@style/shareDialog">
        <intent-filter>
            <action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />

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

 此项中的intent-filter与上述代码中的 intent-filter一模一样,就是这两个一模一样的 intent-filter导致隐式跳转有多个选择

 而此项中所配置的内容既是上面图片中的 dialog 这是以dialog 模式弹出的Activity

 这样也就解释了为何左侧按钮会弹出一个 页面代码中完全没有的 dialog

 将错误的 intent-filter 移除之后问题解决.

5.问题溯源:

 使用git配合Source 的溯源功能发现此代码的第一次添加即在,一年前此app第一次集成友盟分享

 而我这一记洛阳铲,也挖出了从项目创建之初就埋藏的大BUG

 现在从结果来看,当时为何会在dialog 中添加 intent-filter 已经不得而知

 不过可以确定的是 这一年以来 新浪的分享回调,并没有被正确的执行

 当时开发的同志也确实给后面开发的同学 留下了不小的麻烦

6.尾声

 这篇文章基本到这里也就结束了,而集成友盟分享开发中遇到的其他问题也不在这里继续阐述

 谢谢大家的阅读,文中的一些逻辑与观点,也大多是本人的 分析与猜测,肯定存在不少错误,欢迎留言指出,与讨论

 谢谢~