问题描述
在使用微信开放平台(https://open.weixin.qq.com/)开发插件的时候,遇到项目中的WXActivity和WXPayEntryActivity必须在Activity符合如下规范配置:
项目包名.wxapi.WXEntryActivity项目包名.wxapi.WXPayEntryActivity
简单示例如下:
通常意义上,如果我们制作的插件只使用一次的话,我们可以将以上两个类的包名写死,但是考虑到插件的通用性,这种方式肯定是有问题的。
解决方法一:使用activity-alias
activity-alias是给Activity一个别名,同样的,如果通过别名访问真实的Activity,那么也会自动关联到真实的activity,具体配cordova plugin.xml如下。
注意:
① activity-alias使用android:targetActivity链接到真实的acitivity
② activity-alias中的配置和同样也会传递给真实的activity
③ 通过activity-alias调用activity和直接调用activity时,activity-alias可以传递配置给activity,但不能更改原有的配置,因此,直接调用时,安装真实的配置启动Activity。
解决方法二:使用Cordova Hooks
Cordova插件开发过程中,因为核心是plugin.xml的配置,我们既可以使用自动化构建工具,也可以不使用。但是,在解决某些特殊的问题时,使用自动化构建工具可以给我们很方便的解决这些问题。
Cordova Hooks支持很多语言,其中nodejs是比较主流的自动化构建语言,这里的脚本是以nodejs开发的。
配置plugin.xml如下:
两个Acitivity包名配置如下:
package __PACKAGE_NAME__;
脚本如下:
#!/usr/bin/env nodemodule.exports = function (context) { var path = context.requireCordovaModule('path'), fs = context.requireCordovaModule('fs'), shell = context.requireCordovaModule('shelljs'), projectRoot = context.opts.projectRoot, plugins = context.opts.plugins || []; // 判断调用此脚本时加载或者卸载的插件是否是当前微信插件 if (plugins.length > 0 && plugins.indexOf('cordova-plugin-wechat') === -1) { return ; } var ConfigParser = null; try { ConfigParser = context.requireCordovaModule('cordova-common').ConfigParser; } catch(e) { // fallback ConfigParser = context.requireCordovaModule('cordova-lib/src/configparser/ConfigParser'); } var config = new ConfigParser(path.join(context.opts.projectRoot, "config.xml")), packageName = config.android_packageName() || config.packageName();//获取包名 // replace dash (-) with underscore (_) packageName = packageName.replace(/-/g , "_"); console.info("Running android-install.Hook: " + context.hook + ", Package: " + packageName + ", Path: " + projectRoot + "."); if (!packageName) { console.error("Package name could not be found!"); return ; }//判断是否是android插件,否则不需要执行此插件 if (context.opts.cordova.platforms.indexOf("android") === -1) { console.info("Android platform has not been added."); return ; }//获取要生成WXActivity和WXPayEntry的目录 var targetDir = path.join(projectRoot, "platforms", "android", "src", packageName.replace(/\./g, path.sep), "wxapi"); targetFiles = ["EntryActivity.java", "WXEntryActivity.java", "WXPayEntryActivity.java"];//如果卸载插件时,删除原有的Activity if (['after_plugin_add', 'after_plugin_install'].indexOf(context.hook) === -1) { // remove it? targetFiles.forEach(function (f) { try { fs.unlinkSync(path.join(targetDir, f)); } catch (err) {} }); } else { // create directory shell.mkdir('-p', targetDir); // sync the content targetFiles.forEach(function (f) { fs.readFile(path.join(context.opts.plugin.dir, 'src', 'android', f), {encoding: 'utf-8'}, function (err, data) { if (err) { throw err; }//替换包名 data = data.replace(/^package __PACKAGE_NAME__;/m, 'package ' + packageName + '.wxapi;');//将两个activity写入到指定的目录 fs.writeFileSync(path.join(targetDir, f), data); }); }); }};
参考: