具体的报错内容如下
E/MainApplication.java: [(MainApplication.java:86)#uncaughtException]uncaught exception
java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.umeng.socialize.net.LinkCardResponse.url' on a null object reference
at com.umeng.socialize.media.SinaShareContent.getWebpageObj(SinaShareContent.java:138)
at com.umeng.socialize.media.SinaShareContent.getMessage(SinaShareContent.java:45)
at com.umeng.socialize.handler.SinaSsoHandler.share(SinaSsoHandler.java:327)
at com.umeng.socialize.controller.SocialRouter.share(SocialRouter.java:748)
at com.umeng.socialize.UMShareAPI$4.doInBackground(UMShareAPI.java:203)
at com.umeng.socialize.UMShareAPI$4.doInBackground(UMShareAPI.java:194)
at com.umeng.socialize.common.QueuedWork$UMAsyncTask$1.run(QueuedWork.java:141)
at java.lang.Thread.run(Thread.java:818)
代码中调用的地方大致如下:
new ShareAction(activity).withMedia(web)
.setPlatform(platform)
.setCallback(umShareListener)
.share();
经过分析,崩溃的线程和调用并非在同一个线程,此时try catch调用的地方来阻止崩溃是没用的。
最后,通过跟踪源码,发现最终调用分享的代码是SinaSsoHandler
的share()
函数,解决思路是自己创建一个SinaSsoHandler
,通过反射注入到友盟的源码里面,替换掉原有的SinaSsoHandler
,复写share()
。
代码如下:
try {
UMShareAPI umShareAPI = UMShareAPI.get(getContext());
Field socialRouterField = umShareAPI.getClass().getDeclaredField("router");
socialRouterField.setAccessible(true);
Object socialRouterObj = socialRouterField.get(umShareAPI);
Field platformHandlersHandlerField = SocialRouter.class.getDeclaredField("platformHandlers");
platformHandlersHandlerField.setAccessible(true);
Object platformHandlersHandlerObj = platformHandlersHandlerField.get(socialRouterObj);
Map<SHARE_MEDIA, UMSSOHandler> platformHandlers = (Map<SHARE_MEDIA, UMSSOHandler>) platformHandlersHandlerObj;
platformHandlers.put(SHARE_MEDIA.SINA, new SinaSsoHandler(){
@Override
public boolean share(ShareContent content, UMShareListener listener) {
try{
return super.share(content, listener);
}catch (Exception e){
e.printStackTrace();
TaskExecutors.runOnUiThread(new Runnable() {
@Override
public void run() {
Toaster.show("分享失败");
}
});
return false;
}
}
});
new ShareAction(activity).withMedia(web)
.setPlatform(platform)
.setCallback(umShareListener)
.share();
}catch (Exception e){
e.printStackTrace();
}
可以预见的缺点是 如果友盟的sdk有更新,这段反射代码可能就会失效。