前言
本文档为插件集成开发android版,适用于采用Dcloud公司旗下的MUI+HTML5Plus开发的跨平台移动App,开发人员可为不懂原生开发的前端人员,在2017、2018这两年参考价值为最大。
背景
纯MUI+HTML5Plus开发的B2B商城项目需要引入客服,其客服的需求包括对PC端客户端与移动端的对接,自己开发的话成本不合项目需求,故有引入第三方供应商的想法。前期引入美恰客服的WEB版,但使用体验不尽人意,另外,对于一个客服聊天功能来说最重要的消息推送WEB难以达到。
在领导层的三令五申下引入小能客服,故需要引入小能客服,作为Hybrid APP,需要在小能文档的指导下分别集成Android版及IOS版,预期达到的功能有原生聊天界面体验、连接十分钟内消息提醒、客服咨询列表。
工具
一旦用到插件集成,项目代码需分为前端代码和原生代码两部分。分别对应工具:Hbuilder和Android Studio,以及版本管理工具-Git,和一部随时准备测试的真机。(分别点击即可进行下载)
集成步骤
离线打包
这一步可直接按照Dcloud官方人员给出的Android Studio 离线打包示例文章进行操作。众所周知,Dcloud的官方文章还是挺遭人诟病的,因为文章太简陋难以让一些小白看懂,而且突发情况也多。这里我就我遇到情况给出解决措施。
当你美滋滋引入HBuilder-Hello这个工程项目到AS中之后,以为就能像官方人员开始编译运行,结果是一大堆红的绿的报错提醒,答应我请不要崩溃,更坑的始终还在后面。
1、环境SDK不全还是缺少什么gradle包。
如果是AS环境配置不全引发的错误,你还得去网上找篇文章按照着的把SDK什么的配置完整。至于gradle包之类的缺少,因为墙的原因,这个东西基本要下下来起码得等个一天一夜,一般我们没时间等的只能离线去csdn下载。
根据图1处需要什么版本号的,你就去CSDN下载渠道下载或者如果你本地已经有的话,就将这里的版本号改成你已有的。
2、很多不可描述错误
如果不是缺少包的问题,但还是有些不可描述的报错信息,比如图2。
看到这种错误控制台左侧出现这种错误其实挺无奈,因为你根本不知道错在哪!但是天不绝前端之路,还是有途径的。在百度或者Google寻寻觅觅,凄凄惨惨戚戚找不到解决方法,但是那方法却在灯火阑珊处,请不要忽视控制台右侧。
如果你在左侧控制台没找到什么错误,请按照右侧控制台的做法点下去,善良且智慧的AS会告诉你,一大堆具体哪个位置报错,正如图4所看到,是AndroidManIfest.xml这个文件的第202行开始报错,然后找到这个位置,在这个位置又有具体的标红信息告诉你,它为什么错?要怎么办?很多错误都可以通过这个方法自己解决了,不求人只求AS!
说到这里,上面的报错是Hbuilder-Hello这个目录里将AndroidManIfest.xml配置了小米推送和小米登录的信息,这个不删掉一定会导致运行报错。另外,其他配置信息,如果你在替换自己的项目资源后运行没有报错,那就不要删掉,留着,因为一旦删掉,删一而动全身,你的项目又跑不起来了。
值得一提的是,替换了自身资源你要逐一配置测试自己本身那些分享和推送、定位等原生插件,按照官方文档走是没错的,但是对于包名相关的东西不要轻易乱动。还有如果出现plus.nativeUI这个插件不能使用,请尝试我的做法。
在如图5的文件里的所标注的位置上,将此处的applicationId替换成自己App的packname,再重新运行看看。
最后值得一提的就是打包,点击图6这个位置进入按照提示填写证书然后一步步打包是没问题的。
在最后一步,很多非Android开发人员会迷惘,应该怎么勾哪个?
这里给出解释:v1和v2的签名使用,只勾选v1签名并不会影响什么,但是在7.0上不会使用更安全的验证方式,只勾选V2签名7.0以下会直接安装完显示未安装,7.0以上则使用了V2的方式验证,同时勾选V1和V2则所有机型都没问题。
另外建议,在打包的过程中,如果遇到什么问题实在卡住没有办法解决。最好重新那一个新的SDK包重新开始,然后步步为营地避免走到上一次僵局,亲测,这种做法比你硬生生纠结有效率多了。
插件开发
走到这个步骤表示你的项目已经成功离线打包,并各项功能能够成功执行,那么恭喜你。在插件开发上,首先得从官方的实例文档Android平台第三方插件开发指导开始参考起,毕竟在H5+方面这是相当教科书级别。
官方文档写的还是可以让人理解其运行原理的,只是一些细节没有详细指出,让前端小白有点捉摸不清。我在这里提纲挈领地概况一下:
1、插件分为同步拓展和异步拓展,这里我用异步拓展,所以只看异步拓展的部分就够了;
2、在前端JS层需要创建一个js文件,专门作为用来将第三方插件功能封装进plus里面。
该JS的基本思路就是:在能够运行plus环境里,封装一个第三方插件对象,对象里封装的一些方法通过JSbridge可以调用Native层定义的方法。值得注意的是,你要注意传的参数是什么类型的,此处我传的是数组类型,那么在调用方法的时候,我就应该以数组的形式传参进去。
plus.ntalkerPlugin.nTalkerFunction(["xxxxx",“xxxx”,"xxxx"])
相对应,在Native层定义的方法也要用接收数组的方式来接收。
还有,在manifest.json这个文件中也有加入正确格式的插件名,格式与其他插件一样,如图9。
3、在Native层,也就是在AS中需要操作插件开发剩下的流程。首先需要新建com包,再在其中新建plugin包,再在其中新建xn包,在xn包中新建一个类,类名必须与前端层定义对象名一致,最后结果如图10。
接着在自定义插件类,即NtalkerPlugin类中定义要使用第三方插件的功能,
//打来对客服的聊天窗口
public void nTalkerFunction(IWebview pWebview, JSONArray array);
//登录小能
public void login(IWebview pWebview, JSONArray array);
//退出小能
public void logout(IWebview pWebview, JSONArray array);
//获取咨询列表
public void getServiceList(IWebview pWebview, JSONArray array);
写到这里,先不急着集成小能的代码,还需要在配资一个文件,在该文件你需要引入自定义的插件以及配置service层,这一点后面会用到,如图11
现在试试在你的JSBridge将JS层和Native层连通了没?可以用以上任一方法来调试一番,如下:
public void logout(IWebview pWebview, JSONArray array){
Log.i("调试输出","logout");//此处AS控制台打印出来则说明方法调用得到,已配通。
String CallBackID = array.optString(0);//固定格式
// 调用方法将原生代码的执行结果返回给js层并触发相应的JS层回调函数
JSUtil.execCallback(pWebview, CallBackID,String.valueOf(code), JSUtil.OK,false);
}
集成插件
开始集成小能(集成之前建议备份),打开小能官方给你分配的开发文档,点击到安卓集成的那一部分。
根据文档提示进行集成是没有什么问题的,集成完毕重新运行一遍,跑得起来说明集成成功,继续进行代码集成。首先是小能SDK初始化,根据文档说明,打开APP需要进行初始化,本来将其写在插件方法里是没什么问题,但是DCloud封装的插件基类StandardFeature中封装着
public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {
/**
* 如果需要在应用启动时进行初始化,可以继承这个方法,并在properties.xml文件的service节点添加扩展插件的注册即可触发onStart方法
* */
}
因此,将初始化写在其中更加适合。其后,是打开客服聊窗。在小能的文档上是这么写的:
Ntalker.getInstance().startChat(Context appContext, String settingid,String groupName, String kefuid, String kefuname ,ChatParamsBody chatparams);
也就是一个方法传递一些参数,其他参数可以直接看文档可以写,值得一提的是Context appContext 这个方法对于前端是有点头痛,这个应该怎么传?这个方法指的是当前应用环境,直接传递进去当前方法的上下文环境即可,即:this.context。所以也就是简简单单的,调用这个方法就可以打开聊窗。
登录、登出等直接可以通过方法调用的模块直接用以上方法就可以进行集成了,所谓一步通百步通。另外还有一点要点出的是,想在原生SDK这里获得数据给JS层引用,特别要注意格式,好比如我JS层需要显示客服列表,这个数据结构在前端应该就是对象数组:
[{msgId:xx,msgContent:xxx,.....},{msgId:xx,msgContent:xxx},.....]
但小能那边所返回给你只会是Java List<Map>格式的数据,如下,
[{msgId=xx,msgContent=xxx,.....},{msgId=xx,msgContent=xxx},.....]
而你通过jsonAraay返回到JS就是字符串数组,需要开发者用前端手段去将其转化成JSON数组:
[“{msgId=xx,msgContent=xxx,.....}”,“{msgId=xx,msgContent=xxx}”,.....]
文尽于此,你以为结束了吗?不,你忘记一个最重要的功能,就是对于未读消息的监听。说到这里,还是得小小地吐槽一下小能的消息监听机制:当用户点击进入与客服聊天,非关闭式地退出聊窗的十分钟以内才能起到监听未读消息。言归正传,先看小能的文档要求监听未读消息应该怎么写?
通过图13,我们可以知道需要监听未读消息需要实现一个接口且注入一个监听器。示例代码中是在Ativity类中实现继承,但我们并没有这个,怎么办?其实道理是一样,监听器需要在哪里用,这个接口就可以给哪个类实现,于是就有
public class NtalkerPlugin extendsStandard Featureimplements XNSDKListener
然后直接在onCreate的方法中添加如图12红圈中的监听器。在你引入监听器接口后,聪明的AS会自动帮你引入该接口需要你重写的方法,如下
public void onChatMsg();
public void onUnReadMsg() ;
public void onClickMatchedStr() ;
...
这些方法用不到的也要留着,不能删除,否则就会报错。我们在其中 onUnReadMsg方法中打上监听日志,就会发现一有未读信息,日志就会打印出来,因此好了,未读消息已经被监听到了,怎么将这个监听反馈给JS层呢?思路就是:在该监听方法了执行JS层的方法,一有未读消息就执行JS层中的某个方法,即实质问题是Native层调用JS层的函数。
经过对DCloud安卓SDK文档的查询,可得出下列代码
ArrayList iWebs = SDK.obtainAllIWebview();
for(IWebview iWebview : iWebs) {
if(iWebview.getOriginalUrl().indexOf("index.html")>=0) {
iweb= iWebview;
break;}}
//该代码放于打开聊窗的方法体内
通过接口获得JS层首页的对象,然后在监听未读消息的接口内执行
iweb.evalJS("recievedFromXN('"+settingid+"')");
其中,recievedFromXN是写在JS层主页的一个函数,能保证每次一有未读消息都能调用到。
文章到了这里已接近尾声,本文以小能客服作为第三方插件集成示例对DCloud中H5+集成第三方插件进行梳理与概况,从背景、工具、集成步骤三方面对插件开发新手进行循循善诱式地指导,其中集成步骤更加具体化成离线打包、插件开发、集成插件让读者对整个开发工程有一定掌握和理解。因为避免文章篇幅过度冗长,更多无伤大雅的细节并未加入,读者可评论提问。最后希望读者可以给个赞赏或者好评来缅怀我几个小时枯坐码字的心,也希望本文档对你起到作用。