微博开放SDK初始化后使用报错please init sdk before use it. Wb.install()问题解决
微博开放SDK按官方文档配置后接入所需功能,但测试反馈偶然会出现报错提示“occur exception”,多次尝试后复现,抓取报错详细信息为“please init sdk before use it. Wb.install()”,报错来源为微博开放SDK内部方法,按翻译意思是没有初始化,但明明已经进行过初始化再调用的功能,问题出在哪呢?
此文章已收入Android偶遇杂症合集(持续更新)
1、遇到的问题
前段时间做了个集成微博开放SDK的需求,接入以后把功能跑通,结果测试阶段发现偶尔会出现报错无法正常唤起微博的情况。
多次排查后发现,第一次唤起微博时很容易出错,报错信息是“occur exception”,详细报错信息是“please init sdk before use it. Wb.install()”,按翻译意思是没有初始化。
检查了代码后发现,在唤起微博之前确实已经进行了初始化操作,但依然很容易遇到这个问题。
2、原因分析
急着改bug的小伙伴可以直接看(3、解决方式)
由于不是必现,并且只出现在首次调用,初步判断初始化逻辑应该是异步的,话不多说,看微博开放SDK的源码到底做了啥。
首先我们对SDK进行了初始化操作:
// 1. 调用AuthInfo构造方法,实例化一个authInfo
val authInfo = AuthInfo(activity, mAppId, mRedirectUrl, SCOPE)
// 2. 通过WBAPIFactory实例化一个wbApi
val wbApi = WBAPIFactory.createWBAPI(activity)
// 3. 用获得的authInfo和wbApi对象注册APP
wbApi.registerApp(activity, authInfo)
看上去第一步和第二步只是实例化对象,应该内部没有什么操作,看看源码确认一下。
第一步实例化AuthInfo,看看AuthInfo的构造函数:
public final class AuthInfo implements Parcelable, Serializable {// ...public AuthInfo(Context var1, String var2, String var3, String var4) {// 都是赋值操作,没有异步逻辑this.app_key = var2;this.redirect_url = var3;this.scope = var4;this.package_name = var1.getPackageName();this.hash = e.b(var1, this.package_name);}//...
}
第二步通过WBAPIFactory实例化一个wbApi,看看WBAPIFactory源码:
public class WBAPIFactory {public WBAPIFactory() {}public static IWBAPI createWBAPI(Context var0) {// 直接构造了一个对象return new a(var0);}
}
看看WBAPIFactory构造的a对象的构造方法:
public final class a implements IWBAPI {// ...public a(Context var1) {// 也都是赋值操作,没有异步逻辑this.mContext = var1;this.s = new com.sina.weibo.sdk.auth.a((Activity)this.mContext);this.t = new e((Activity)this.mContext);}// ...
}
粗略看来好像没啥特殊的,没有异步的逻辑在其中,那问题可能出在第三步registerApp上了,看看registerApp都做了啥:
public interface IWBAPI {// ...void registerApp(Context var1, AuthInfo var2);// ...
}
是通过接口调用的,看看实现类:
public final class a implements IWBAPI {// ...public final void registerApp(Context var1, AuthInfo var2) {com.sina.weibo.sdk.a.a(var1, var2);}// ...
}
不做停留,跟进去看看:
public final class a {// ...public static void a(Context var0, AuthInfo var1) {if (!a) {if (var1 == null) {throw new RuntimeException("authInfo must not be null.");}b = var1;String var4 = var1.getAppKey();WeiboSsoSdkConfig var2;(var2 = new WeiboSsoSdkConfig()).setContext(var0.getApplicationContext());var2.setAppKey(var4);var2.setFrom("1478195010");var2.setWm("1000_0001");WeiboSsoSdk.initConfig(var2);try {// 抓到你了!一个异步操作WeiboSsoSdk.getInstance().visitorLogin(new VisitorLoginListener() {public final void handler(VisitorLoginInfo var1) {try {if (var1 != null) {com.sina.weibo.sdk.a.mAid = var1.getAid();com.sina.weibo.sdk.a.c();}} catch (Exception var2) {var2.printStackTrace();}}});return;} catch (Exception var3) {var3.printStackTrace();}}}// ...
}
果然,在初始化逻辑的第三步registerApp中有一个异步操作,WeiboSsoSdk.getInstance().visitorLogin()
,看上去是有一个SDK通过APPKey等参数进行登录的逻辑,应该是鉴权校验用的。
翻了一下官方文档,并没有提供一个初始化完成的监听回调,WeiboSsoSdk.getInstance().visitorLogin()
完成后也进入了一堆混淆过后的代码逻辑中,没有暴露给外界的方法可以用来监听状态。
换个思路,我们看看报错是从哪里来的,进入断点跟着代码的执行看看唤起微博时都发生了什么,就从微博授权登录开始看吧。首先我们知道入口是IWBAPI.authorize()
,进入实现类com.sina.weibo.sdk.openapi.a
的authorize()
方法打个断点:
public final class a implements IWBAPI {// ...public final void authorize(WbAuthListener var1) {WbAuthListener var2 = var1;com.sina.weibo.sdk.auth.a var3 = this.s;c.a("WBSsoTag", "authorize()");if (var2 == null) {throw new RuntimeException("listener can not be null.");} else {var3.e = var2;Context var4;if (com.sina.weibo.sdk.a.a(var4 = (Context)var3.d.get()) && com.sina.weibo.sdk.b.a.e(var4) != null) {// 就是这一行执行完就报错了,跟进去看看var3.d();} else {var3.e();}}}// ...
}
var3.d()
里藏着那只虫子,就快要抓住它了:
package com.sina.weibo.sdk.auth;
public final class a {// ...public final void d() {c.a("WBSsoTag", "startClientAuth()");try {Context var1;com.sina.weibo.sdk.b.a.a var2 = com.sina.weibo.sdk.b.a.e(var1 = (Context)this.d.get());Intent var3 = new Intent();if (var2 == null) {var3.setClassName("com.sina.weibo", "com.sina.weibo.SSOActivity");} else {var3.setClassName(var2.packageName, var2.ag);}// 报错的是这一行代码,之后就被catch到了错误,并提示"occur exception"AuthInfo var6 = com.sina.weibo.sdk.a.b();var3.putExtra("appKey", var6.getAppKey());var3.putExtra("redirectUri", var6.getRedirectUrl());var3.putExtra("scope", var6.getScope());var3.putExtra("packagename", var6.getPackageName());var3.putExtra("key_hash", var6.getHash());var3.putExtra("_weibo_command_type", 3);var3.putExtra("_weibo_transaction", "" + System.currentTimeMillis());Activity var4;if ((var4 = (Activity)this.d.get()) == null) {this.e.onError(new UiError(-1, "activity is null", ""));} else if (com.sina.weibo.sdk.b.a.a(var1, var3)) {var6.getAppKey();var3.putExtra("aid", com.sina.weibo.sdk.b.e.s());var4.startActivityForResult(var3, 32973);c.a("WBSsoTag", "start SsoActivity ");} else {this.e.onError(new UiError(-2, "your app is illegal", ""));}} catch (Exception var5) {var5.printStackTrace();c.b("WBSsoTag", var5.getMessage());this.e.onError(new UiError(-3, "occur exception", var5.getMessage()));}}// ...
}
看到了报错信息的产生位置了,com.sina.weibo.sdk.a.b()
做了什么,为什么会有报错产生:
package com.sina.weibo.sdk;
public final class a {private static boolean a = false;private static AuthInfo b;private static String mAid;public static void a(Context var0, AuthInfo var1) {if (!a) {if (var1 == null) {throw new RuntimeException("authInfo must not be null.");}b = var1;String var4 = var1.getAppKey();WeiboSsoSdkConfig var2;(var2 = new WeiboSsoSdkConfig()).setContext(var0.getApplicationContext());var2.setAppKey(var4);var2.setFrom("1478195010");var2.setWm("1000_0001");WeiboSsoSdk.initConfig(var2);try {WeiboSsoSdk.getInstance().visitorLogin(new VisitorLoginListener() {public final void handler(VisitorLoginInfo var1) {try {if (var1 != null) {com.sina.weibo.sdk.a.mAid = var1.getAid();com.sina.weibo.sdk.a.c();}} catch (Exception var2) {var2.printStackTrace();}}});return;} catch (Exception var3) {var3.printStackTrace();}}}private static void a() {if (!a) {throw new RuntimeException("please init sdk before use it. Wb.install()");}}public static AuthInfo b() {a();return b;}// ...
}
原来又是它,第三步registerApp中异步操作的执行类,WeiboSsoSdk.getInstance().visitorLogin()
方法的调用者。变量a的值不符合预期,所以报错了RuntimeException("please init sdk before use it. Wb.install()")
,再想看看变量a的值什么时候再赋值为true
就找不到地方了,线索就到这断了?!!
3、解决方式
别急,车到山前必有路,线索虽然断了,但是解决的办法已经出现在你眼前了。注意一下最后跟踪到报错的位置:
package com.sina.weibo.sdk;
public final class a {private static boolean a = false;// ...private static void a() {if (!a) {throw new RuntimeException("please init sdk before use it. Wb.install()");}}public static AuthInfo b() {a();return b;}// ...
}
RuntimeException("please init sdk before use it. Wb.install()")
这个错误是com.sina.weibo.sdk.a.a()
抛出的,上一个调用它的方法是com.sina.weibo.sdk.a.b()
,仔细看看,com.sina.weibo.sdk.a
类是public修饰的,虽然com.sina.weibo.sdk.a.a()
方法是private修饰的,但是com.sina.weibo.sdk.a.b()
方法是public修饰的,所以我们可以手动调用com.sina.weibo.sdk.a.b()
方法来判断是否已完成微博开放平台的初始化!
修改一下原有的初始化逻辑,增加一个初始化是否完成的判断:
val authInfo = AuthInfo(activity, mAppId, mRedirectUrl, SCOPE)
val wbApi = WBAPIFactory.createWBAPI(activity)
wbApi.registerApp(activity, authInfo)
while (true) (try {// 如果没有抛出异常,断言通过,说明初始化已完成,循环结束a.b()break} catch (e: Exception) {e.printStackTrace()}
)
到此问题就解决了,在初始化完成之后再执行后续的操作,再没有出现“occur exception”的报错提示了。如果怕出现死循环,可以对循环加一个超时机制。
完毕
今天的分享就到这里,文章多有不足,各位小伙伴有什么想法可以直接评论或是私信,要是对你有所帮助就给我一个赞吧,喜欢我的小伙伴可以关注我哦~
此文章已收入Android偶遇杂症合集(持续更新)
支持我的小伙伴们可以微信搜索“Android思维库”,或者微信扫描下方二维码,关注我的公众号,每天都会推送新知识~
微博开放SDK初始化后使用报错please init sdk before use it. Wb.install()问题解决相关推荐
- linux7yum配置后使用报错,Centos7 使用yum安装MariaDB 10.1(报错缺少依赖的解决情况,报错信息贴在最后)-Go语言中文社区...
1.创建 MariaDB yum 仓库 官方教程截图: 1.1 根据教程提示,创建MariaDB.repo 写入以下内容并保存: vi /etc/yum.repos.d/MariaDB.repo [m ...
- adb驱动安装和使用报错笔记
adb驱动安装 adb驱动下载地址:https://adb.clockworkmod.com/ 安装时候选择一个容易记住的路径,这个很重要,因为adb驱动没有自动配置环境变量,所以实验时候将adb安装 ...
- 记录webpack使用问题,使用报错“UnhandledPromiseRejectionWarning,file-loader图片过大,无法加载图片,打包html文件报错TypeError
记录webpack使用报错 版本号问题 运行npm run build,报错 "UnhandledPromiseRejectionWarning: TypeError: this.getRe ...
- “this”不能在常量表达式中使用报错的解决方法
"this"不能在常量表达式中使用报错的解决方法 问题描述与思考 在用C++书写下面一段代码时,编译器报错"'this'不能在常量表达式中使用".在这里,我最开 ...
- git使用报错:fatal: Couldn't find remote ref master的解决方法
git使用报错:fatal: Couldn't find remote ref master的解决方法 fatal: Couldn't find remote ref master 翻译过来就是:致命 ...
- Assets.car 解压工具 cartool 使用报错 segmentation fault cartool 解决方案
Assets.car 解压工具 cartool 使用报错 segmentation fault cartool 解决方案 参考文章: (1)Assets.car 解压工具 cartool 使用报错 s ...
- CentOS系统yum源使用报错:Error: Cannot retrieve repository metadata
服务器上的yum突然不好使用,使用yum的时候报错如下: [root@bastion-IDC src]# yum list ...... Could not retrieve mirrorlist h ...
- Python安装xlrd和xlwt的步骤以及使用报错的解决方法
Python安装xlrd和xlwt的步骤以及使用报错的解决方法 参考文章: (1)Python安装xlrd和xlwt的步骤以及使用报错的解决方法 (2)https://www.cnblogs.com/ ...
- git使用报错: fatal: Couldn‘t find remote ref master的解决方法
git使用报错: fatal: Couldn't find remote ref master的解决方法 参考文章: (1)git使用报错: fatal: Couldn't find remote r ...
最新文章
- python创建excel图表_python使用VBA(8):Excel创建图表(简单)
- neo4j查询多跳关系的方法
- 超云将成为数据中心演化的下一个阶段
- Jerry的Kubernetes学习笔记
- leetcode 452. 用最少数量的箭引爆气球(贪心算法)
- (转)Spring+JDBC组合开发
- 正则表达式 匹配标签里面的值 eg:image input
- 【快代理API】获取开放代理
- CrossApp环境搭建
- 表白生成器PHP源码,带自动生成的php表白程序 v1.0
- 计算机文字输入程序,电脑“造字”,其实很简单
- 某客服热线呼叫中心话务分析
- 开源直播美颜SDK工具算法分析
- PMP第四章:项目整合管理
- 玩游戏掉帧严重?看过来!
- 服务器阵列有什么作用,服务器存储-存储服务器和磁盘阵列有什么区别
- 计算机组成原理:VHDL设计微程序控制器(代码通俗易懂)
- Hive的nvl、coalesce、if、nvl2
- css–sprit_高级CSS –类已用完–通过使用结构化格式标签避免类
- 章泽天卸任刘强东旗下公司董事 官方回应:正常商业调整
热门文章
- 高维数据中特征筛选方法的思考总结——单变量分析筛选法
- 如何为员工开展针对性体检
- java根据两条直线的四个坐标点证明这两条线平行(计算直线斜率)或者三个点在一条直线上
- 对勾和叉怎么打_“对勾”“错叉”符号怎么打
- 电商数据课程-SQL笔记总结
- 手机黑屏显示服务器,三星服务器被攻击:出现黑屏、重启现象!华为迎来机会?...
- 老子云:近乎100%的还原,感觉自己玩到了端游
- 为什么带有E-Marker芯片的数据线才是快充数据线?
- mac下编译ncnn和ncnn中的pnnx
- android sqlcipher github,android – sqlcipher_export没有导出我的表