问题是这样的,项目里的社交化分享是基于 UMShare
封装成的一个 ShareLib module
,为了让这个 module
对调用者说更透明,我将 WXEntryActivity
的申明从 App module
移动到了 ShareLib module
里, AndroidMainifest.xml
中关于 WXEntryActivity
的申明如下:
同时把 wxapi
目录(包含 WXEntryActivity.java
也一并转移,根目录下的 wxapi
目录如图:
App module
确实清爽了不少。但是,这么做会引发怎样的问题呢?
配置Android Mainifest XML,文档里明确指出是需要在 AndroidMainifest
里申明 WXEntryActivity
, 并在根目录下新建一个 wxapi
包,然后将 WXEntryActivity
放在里面。但说如果把这些东西放到 module
项目里会如何,友盟并没有说,emmmm…
进入 UMShare SDK
的源码里探索了一番后,将错误锁定在了 checkWxBySelf
这个静态方法上,该方法声明如下:
public static String checkWxBySelf(Context context) {
// 获取包名
String pkName = context.getPackageName();
// 获取类名
String classPath = pkName + ".wxapi.WXEntryActivity";
PackageInfo packageInfo = null;
PackageManager packageManager = null;
try {
packageManager = context.getPackageManager();
packageInfo = packageManager.getPackageInfo(pkName, 64);
} catch (NameNotFoundException var8) {
var8.printStackTrace();
}
String result = getSignatureDigest(packageInfo);
try {
// 1.通过全名加载 WXEntryActivity 类
Class<?> clz = Class.forName(classPath);
if(clz == null) {
return "请检查微信后台注册签名:" + result.toLowerCase() + "\n" + "包名:" + pkName + "\n" + "没有配置微信回调activity或配置不正确";
}
if(Config.isUmengWx.booleanValue()) {
if(clz.getSuperclass() == null) {
return "WXEntryActivity配置不正确,您使用的是精简版,请使WXEntryActivity继承com.umeng.weixin.callback.WXCallbackActivity";
}
if(!clz.getSuperclass().toString().contains("com.umeng.weixin")) {
return "WXEntryActivity配置不正确,您使用的是精简版,请使WXEntryActivity继承com.umeng.weixin.callback.WXCallbackActivity";
}
} else {
if(clz.getSuperclass() == null) {
return "WXEntryActivity配置不正确,您使用的是完整版,请使WXEntryActivity继承com.umeng.socialize.weixin.view.WXCallbackActivity";
}
if(!clz.getSuperclass().toString().contains("com.umeng.socialize")) {
return "WXEntryActivity配置不正确,您使用的是完整版,请使WXEntryActivity继承com.umeng.socialize.weixin.view.WXCallbackActivity";
}
}
} catch (ClassNotFoundException var9) {
var9.printStackTrace();
return "请检查微信后台注册签名:" + result.toLowerCase() + "\n" + "包名:" + pkName + "\n" + "没有配置微信回调activity或配置不正确";
}
try {
ComponentName componentName = new ComponentName(context.getPackageName(), classPath);
// 2.根据指定的组件,获取 ActivityInfo 信息
packageManager.getActivityInfo(componentName, 0);
return "请检查微信后台注册签名:" + result.toLowerCase() + "\n" + "包名:" + pkName + "\n" + "Activity微信配置正确";
} catch (NameNotFoundException var7) {
var7.printStackTrace();
return "请检查微信后台注册签名:" + result.toLowerCase() + "\n" + "包名:" + pkName + "\n" + "没有配置微信回调activity没有在Manifest中配置";
}
}
注释里已经写了两个可能抛出异常的地方,和 packageName 都有关系,也就是说我们能否正确获取 packageName 直接影响到能否正常使用 UMShare SDK 的功能!很显然,我们的 App Module
里并没有对应的 WXEntryActivity,所以执行到注释1的时候就会抛出异常了!
如果,我在 App module
里加上 wxapi 目录就 OK 了嘛?
答案是no!还是会报错,只不过这次是在注释2抛出异常。
又报错,这次明明加上了 wxapi 目录,已经可以找到 WXEntryActivity 了,为毛还是报错勒,emmm,再来冷静分析下吧。
关于多个 AndroidMainifest 的合并问题,可以去Android 官网补补课。
因为我们的项目有多个 module,每个 module 都有自己的 AndroidMainifest,而最终,这些文件会被合并为一个文件。
<activity
android:name="info.hellovass.sharelib.wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity
android:name="info.hellovass.sharelib.wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
因为我们并没有在 App module 下的 AndroidMainifest 对 WXEntryActivity 做任何申明,所以,merge 时会合并 ShareLib module 里的申明,于是,就变成了上面这样子。看到这里,我想事情也明了了,因为这种情况,ShareLib module
的包名和 App module
的包名是不一致的。简单来说,WXEntryActivity 并未注册到 AndroidMainifest 中,所以会在 packageManager.getActivityInfo(component, 0)
出抛出异常。