首先说明一下,即使不熟悉fis3,阅读文本应该也会有所收获。

  本文以fis-parser-imweb-tplv2插件为模板插件,目的不在于使用哪个模板,而是组件可视化的实现思路,不必担心。

先说说模板插件

  首先说明一下,我们的项目使用的fis3自带的mod.js做模块化开发。

  fis-parser-imweb-tplv2插件是同事在imweb待着的时候写的。模板使用和jsp写法一致,文件类型为tpl类型

  1. <div class="tips">
  2. <em>
  3. <i class="triangle"></i>
  4. <a class="close" href="javascript:void(0)" title="关闭"></a>
  5. </em>
  6. <strong><%=content%></strong>
  7. <a href=<%=linkUrl%> title=<%=linkTxt%> target="<%=target%>"> <%=linkTxt%> ></a>
  8. </div>

  实现源码也比较简单易懂。fis3的配置

  1. .match(/\/(.+)\.tpl$/, { // js 模版一律用 .tpl 作为后缀
  2. isMod: true,
  3. rExt: 'js',
  4. id: '$1.tpl',
  5. url: '$0.tpl',
  6. moduleId: '$1.tpl',
  7. release: '$0.tpl', // 发布的后的文件名,避免和同目录下的 js 冲突
  8. parser: fis.plugin('imweb-tplv2')
  9. })

  最终生成的模块化的.tpl.js文件如下

  1. define('common/module/rightsideBar/rightsideBar.tpl', function(require, exports, module) {
  2.  
  3. return function (it, opt) {
  4. it = it || {};
  5. with(it) {
  6. var _$out_= [];
  7. _$out_.push('<div class="right-sidebar"><a href="javascript:void(0)" class="right-sidebar-unregistered-close"></a><a id="rsidereg" href="/register.html?channel=pcgwzc3" class="right-sidebar-unregistered" style="visibility:', (isLogin ?'hidden' :'visible'), '"><span class="right-sidebar-unregistered-content"></span></a><a href="http://wpa.b.qq.com/cgi/wpa.php?ln=2&amp;uin=4008225538" class="right-sidebar-item right-sidebar-item3" target="_blank"><span class="right-sidebar-item1-content"></span></a><a href="javascript:void(0)" class="right-sidebar-item right-sidebar-item2"><span class="right-sidebar-item2-content"></span><div class="right-sidebar-item-tip--code"> <img src="', '/static/pc-dev/common/module/topBar/top_wx.png', '"> <i class="right-sidebar-item-tip--code-tri"><i></i></i></div></a><a href="javascript:void(0)" class="right-sidebar-item right-sidebar-item3"><span class="right-sidebar-item3-content"></span><div class="right-sidebar-item-tip--code"> <img src="', '/static/pc-dev/common/module/topBar/top_app.png', '"> <i class="right-sidebar-item-tip--code-tri"><i></i></i></div></a><a href="javascript:void(0)" id="rjsq" class="right-sidebar-item right-sidebar-item4" target="_blank"><span class="right-sidebar-item4-content"></span></a><a href="javascript:window.scrollTo(0,0)" class="right-sidebar-item right-sidebar-item5" style="display: none;"><span class="right-sidebar-item5-content"></span></a></div>');
  8. return _$out_.join('');
  9. }
  10. }
  11.  
  12. });

  fis3打包前和打包后的文件结构更改

  

  使用也比较简单

  1. var tpl_rightsideBar = require('rightsideBar.tpl');
  2. tpl_rightsideBar(opt);//opt是需要传递进去的对象。详细查看rightsideBar.tpl.js的源码对应的it参数

  当然,我们封装一个组件不可能直接去使用这个tpl。而是提供一个外部组件函数,然后传递参数到这个组件函数中,组件函数不仅渲染页面(即插入组件dom),还处理相关的逻辑。如上面的rightsideBar.js就是为外部提供一个组件函数。rightsideBar组件比较简单,只需要传递一个父节点即可,不需要其他外部数据来做处理。部分源码

  1. /**
  2. * @author chua
  3. * @date 2016-5-9
  4. * @description 首页右侧导航栏组件,依赖模版 rightsideBar.tpl,rightsideBar.scss;
  5.  
  6. * @实例化:rightsideBar = new rightsideBar(dom, datas);
  7. * @param dom {Dom} 为头部组件父级节点,将根据情况append模版,生成头部节点;
  8. * @param datas {json} 初始化组件的数据,数据格式如下
  9. */
  10.  
  11. /*
  12. * @require './rightsideBar.scss';
  13. */
  14. var tpl_rightsideBar = require('./rightsideBar.tpl');
  15. function rightsideBar(cont,opt) {
  16. this.cont = $(cont);
  17. this.opt = opt;
  18. this.init();
  19. };
  20. rightsideBar.prototype.renderHTML = function() {
  21. //渲染前处理...
  22. this.cont.empty().append(tpl_rightsideBar(this.opt));
  23. };
  24. rightsideBar.prototype.bindEvent = function() {
  25. //绑定事件
  26. this.cont.on('click', '.xxx', function() {
  27. //处理内容...
  28. });
  29. };
  30. rightsideBar.prototype.init = function() {
  31. this.renderHTML();
  32. this.bindEvent();
  33. }
  34. return rightsideBar;

  rightsideBar.js会被当做模块来编译(我们在fis-conf.js中配置的),最终编译出来后外面会被define包裹。

  1. define('common/module/rightsideBar/rightsideBar', function(require, exports, module) {
  2. //代码正文
  3. ...
  4.  
  5. rightsideBar.prototype.init = function() {
  6. this.renderHTML();
  7. this.bindEvent();
  8. }
  9.  
  10. return rightsideBar;
  11.  
  12. });

  使用方法也比较简单

  1. html:
  2. <div class="js-rightsideBar"></div>
  3. js:
  4. var rightsideBar = require('/common/module/rightsideBar/rightsideBar.js');
  5. new rightsideBar($('.js-rightsideBar'));

  而我们的所有组件都放在一个组件文件夹module中,每一个组件一个文件夹(当然页可以是多个类似的组件放在一起,公用资源),文件夹下面放置所有这个组件相关的资源。如上图rightsideBar这个组件。

  那么如何做组件可视化?有几个过程是必须要做的

  1.需要遍历module中所有的组件(即遍历每一个组件下面的.js文件,一个组件文件夹下有多个js文件,表明这个组件文件夹下有多个组件,只是为了公用组件资源才放在了同一个组件下),提取出其中的使用样例(从注释代码中提取,所以必须要规定这段demo代码的规则)。

  2.必须在每一个组件的注释中写demo代码。

  3.将提取的demo代码写入指定的组件可视化文件中,随fis编译成目标文件(最终在网上打开这个文件就能预览各个组件的demo了)。

  在上面的基础上,改如何实现组价的可视化?

第一阶段的组件可视化

  第一阶段的组件可视化使用node+fis的方式实现。原理是在fis编译之前使用node执行一个脚本,这个脚本完成遍历组件、提取demo代码、生成组件可视化目标文件。然后在使用fis编译打包,启动服务后在网上访问即可。之所以第一阶段这么做的原因有两点:鄙人比较熟悉node但是对fis插件编写不太熟悉,不敢确定使用fis插件方式是否可行;其次上头希望能在短期内能看到一定效果。先看一下工程结构目录,v_components文件夹里包含了所有用来生成组件可视化文件的工具文件,node执行脚本为index.js

  

  工程源文件点击这里

  实现步骤:

  1.规定文件注释代码中"@example"和"@example end"之间的字符串被认为是组件demo代码。

  1. /**
  2. * @author chua
  3. * @date 2016-5-9
  4. * @description 首页右侧导航栏组件,依赖模版 rightsideBar.tpl,rightsideBar.scss;基于jQuery和jquery.cookie.js
  5.  
  6. * @实例化:rightsideBar = new rightsideBar(dom, datas);
  7. * @param dom {Dom} 为头部组件父级节点,将根据情况append模版,生成头部节点;
  8. * @param datas {json} 初始化组件的数据,数据格式如下
  9.  
  10. *
  11. * @example
  12. html:
  13. <div class="js-rightsideBar"></div>
  14.  
  15. js:
  16. var rightsideBar = require('/common/module/rightsideBar/rightsideBar.js');
  17. new rightsideBar($('.js-rightsideBar'));
  18.  
  19. @example end
  20. */

  其中html:后面跟着的是html代码,js:后面跟着的是js执行代码。注意不要出现不符合代码格式的字符,"html:"、"js:"分别为html代码段和js代码段开始的标志。其后的代码分别要严格按照html和js的格式要求书写

  

  2.为了简化和配置更加灵活。我添加了config.json和wrap.html两个文件来配合主文件index.js文件。

  

  其中index.js文件作用是作为node脚本运行,最终生成最新的v_components.html。v_components.css和v_components.js是给v_component.html使用的,毕竟组件可视化需要一些展示和交互

  config.json的作用是希望能够配置组件的一些属性,让其更灵活,移植性更加。目前只支持一个配置:组件的目录 (建议使用相对路径,否则在index.js中可能找不到)

  1. {
  2. "modulePath": "../common/module/"
  3. }

  warp.html是用来生成v_components.html的模板文件。里面包含了v_components.html文件需要的样式文件和脚本文件。这个文件也是根据实际情况配置

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>组件可视化</title>
  5. <link rel="import" href="/common/html/meta.html?__inline">
  6. <link rel="stylesheet" type="text/css" href="/common/css/common.scss" />
  7. <link rel="stylesheet" type="text/css" href="v_components.css" />
  8. <script type="text/javascript" src="/common/dep/mod.js" data-loader></script>
  9. <script type="text/javascript" src="/common/dep/jquery.js" data-loader></script>
  10. <script type="text/javascript" src="/common/js/common.js" data-loader></script>
  11. <script type="text/javascript" src="v_components.js" data-loader></script>
  12. </head>
  13. <body>
  14. </body>
  15. </html>

  3.主程序index.js读取配置文件config.json中配置的组件目录遍历每一个组件(里面的js文件),提取注释中的demo代码,以wrap.html为模板,将html代码插入为节点,将js脚本插入到script节点中。

  1. var fs = require('fs');
  2. ...
  3. var writerStream = fs.createWriteStream('v_components.html');
  4. var regs = {
  5. 'wraphtml': /^([\s\S]*<(body)>[\s\S]*)(<\/\2>[\s\S]*)$/,
  6. //懒惰匹配到第一个*/
  7. 'example': /\/\*\*([\s\S]*)@example[\s\S]*?html:([\s\S]*?)js:([\s\S]*?)@example end([\s|\S]*?)\*\//,//懒惰匹配第一个*/
  8. ...
  9. };
  10.  
  11. fs.readFile('config.json', function(err, data){
  12. ...
  13. root = obj.modulePath;
  14. if(datas){
  15. loopModule();
  16. }
  17. })
  18. fs.readFile('wrap.html', function(err, data){
  19. ...
  20. datas = data.toString();
  21. if(root){
  22. loopModule();
  23. }
  24. });
  25. //遍历所有模块文件
  26. function loopModule(){
  27. fs.readdir(root, function(err, ffiles){
  28. ...
  29. //遍历所有组件
  30. ffiles.forEach(function(ffile){
  31. ...
  32. fs.readdir(root + ffile, function (err, files){
  33. ...
  34. files.forEach(function(file){//处理每一个模块文件中的模块并找到组件主文件(js文件)
  35. if(regs.jsfile.test(file)){
  36. ...
  37. fs.readFile(pa, function(err, data){
  38. ...
  39. if(match = data.toString().match(regs.example)){//匹配demo代码段
  40. //截取相关信息并添加相关节点
  41. ...
  42. innerRightT += '<div class="right-side-top-item' + (count == 0? ' visible': '') + '" data-mod="'+ file +'">' + match[2] + '</div>';
  43. innerJs += match[3] + ";";//js脚本都放在innerJs中
  44. count++;
  45. }
  46.  
  47. if(subModLeng == 0){//处理完所有子模块才能说明处理完了整个模块文件夹
  48. unDomoduleLength--;
  49. }
  50. if(unDomoduleLength == 0){//处理完所有的模块后,最后写入文件
  51. var innerBody = warpText(innerLeftWrap, innerLeft)
  52. + warpText(innerRightWrap, warpText(innerRightTWrap, innerRightT) + warpText(innerRightBWrap, innerRightB))
  53. + warpText(jsWrap, innerJs);
  54.  
  55. //使用utf8编码写入数据
  56. writerStream.write(datas.replace(regs.wraphtml, '$1' + innerBody + '$3'), 'UTF8');
  57. //标记文件结尾
  58. writerStream.end();
  59. }
  60. });
  61. }
  62.  
  63. })
  64. });
  65. })
  66. })
  67. }
  68. //用数组wrapArr包裹inner并返回包裹结果
  69. function warpText(wrapArr, inner){...}
  70. //将str字符串转换成HTML格式
  71. function transToHtml(str){...}

  最终在v_components目录下执行:node index

  生成v_components.html文件

  在pc目录下fis3编译:fis3 release dev

  在和pc同级的目录下面生成pc-dev文件夹

  在pc-dev目录下执行:node server

  打开浏览器访问:http://localhost:3000/v_components/v_components.html

  

  左侧是所有的组件的列表,点击之能看到每一个组件的展示效果。我很丑,但是我很有内涵

第二阶段的组件可视化——fis3插件

  之前说过要将组件可视化做成fis插件,随fis编译一起编译打包,不用在手动执行node生成相应文件。主要面临的问题是:如何让组件更加通用?这里面几个需要考虑的点

  1.如何从组件代码的注释中提取出demo代码段。

  这里我使用了下面的正则来匹配

  1. /\/\*\*([\s\S]*)@example[\s\S]*?(html:([\s\S]*?)js:([\s\S]*?))@example end([\s|\S]*?)\*\//,//懒惰匹配第一个*/

  匹配文件注释中‘@example’和‘@example end’之间的代码。如

  1. /**
  2. * @example
  3. html:
  4. <div class="js-rightsideBar"></div>
  5.  
  6. js:
  7. var rightsideBar = require('/common/module/rightsideBar/rightsideBar.js');
  8. new rightsideBar($('.js-rightsideBar'));
  9.  
  10. @example end
  11. */

  这个部分本来想做成可以配置的,但是觉得没有太大的意义,就默认使用这个正则来匹配组件中的demo代码。

  2.插件需要那些参数,是的插件更加灵活

  下面是最终确定下来的参数(路径都配置绝对路径)

  1. wrap: '/v_components/wrap.html',//组件可视化原型文件,用来包裹组件可视化代码
  2. url: '/v_components.html', //目标文件
  3. COMPath: '/common/module',//组件集合目录
  4. moduleListInstead: 'instead of modules',//使用模块列表节点替换当前文本
  5. moduleViewInstead: 'instead of view htmls',//使用模块视图列表节点替换当前文本
  6. moduleCommentsInstead: 'instead of commnets',//使用模块注释列表节点替换当前文本
  7. moduleJsInstead: 'instead of js'//使用js脚本节点替换当前文本

  当前文件的目录结构

  

  其中wrap对应的文件wrap.html作用非常重要。后面四个参数moduleXXXInstead对应的值必须在wrap.html中能够找到,然后使用插件拼装好的数据来替换他。wrap.html源码如下

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>组件可视化</title>
  5. ...
  6. </head>
  7. <body>
  8. <div class="left-side">instead of modules</div>
  9. <div class="right-side">
  10. <div class="right-side-top">instead of view htmls</div>
  11. <div class="right-side-bottom">instead of commnets</div>
  12. </div>
  13. ...
  14. <script type="text/javascript">instead of js</script>
  15. </body>
  16. </html>

  最终执行fis后上面黑色粗体文字全部被替换

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>组件可视化</title>
  5. ...
  6. </head>
  7. <body>
  8. <div class="left-side"><div data-mod="financialsBar">financialsBar</div><div data-mod="financialsSmlBar">financialsSmlBar</div><div data-mod="rightsideBar">rightsideBar</div></div>
  9. <div class="right-side">
  10. <div class="right-side-top"><div data-mod="financialsBar">
  11. <!-- 新手 -->
  12. <div class="js-financialsBar1"></div>
  13. <!-- 活期 -->
  14. <div class="js-financialsBar2"></div>
  15. <!-- 定期 -->
  16. <div class="js-financialsBar3"></div>
  17.  
  18. </div><div data-mod="financialsSmlBar">
  19. <!-- 定期理财 -->
  20. <div class="js-financialsSmlBar1"></div>
  21. <!-- 债权转让 -->
  22. <div class="js-financialsSmlBar2"></div>
  23. </div><div data-mod="rightsideBar">
  24. <div class="js-rightsideBar"></div>
  25.  
  26. </div></div>
  27. <div class="right-side-bottom"><div data-mod="financialsBar"><div >样例:<div>html:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;新手&nbsp;--&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="js-financialsBar1"&gt;&lt;/div&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;活期&nbsp;--&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="js-financialsBar2"&gt;&lt;/div......</div>
  28. </div>
  29. ...
  30. <script type="text/javascript">var financialsBar = require('common/module/financialsBar/financialsBar');
  31. new financialsBar($('.js-financialsBar1'), {
  32. "type": "novice",
  33. "bdid": 1,
  34. "name": "农优宝A1231213",
  35. "title": "新手专享",
  36. "term": 1,
  37. "annualrate": 0.09,
  38. "interestRaise": 0.005,
  39. "surplusAmount": 30000,
  40. "projectScale": 50000,
  41. "status": "RZZ",
  42. "packStatus": "QGZ",
  43. "releaseDate": 425132121,
  44. "nowDate": 45641231321,
  45. "surplusBuyCount":1,
  46. 'productType': 'NYB',
  47. 'delayTime': 0
  48. });
  49. ...
  50. </script>
  51. </body>
  52. </html>

  来自相同的组件的DOM节点的属性值data-mod相同。

  fis-conf.js的配置片段

  1. .match('::package', {
  2. prepackager: fis.plugin('component-preview',{
  3. wrap: '/v_components/wrap.html',//组件可视化原型文件,用来包裹组件可视化代码
  4. url: '/v_components.html', //目标文件
  5. COMPath: '/common/module',//组件集合目录
  6. moduleListInstead: 'instead of modules',//使用模块列表节点替换当前文本
  7. moduleViewInstead: 'instead of view htmls',//使用模块视图列表节点替换当前文本
  8. moduleCommentsInstead: 'instead of commnets',//使用模块注释列表节点替换当前文本
  9. moduleJsInstead: 'instead of js'//使用js脚本节点替换当前文本
  10. })
  11. })

  更详细的demo查看fis3_component_preview_demo

  最终效果同第一阶段的组件可视化效果一样     

  实现原理:

  

  完整的插件源码查看fis3-prepackager-component-preview

  

  如果觉得本文不错,请点击右下方【推荐】!

基于fis3的组件可视化道路的更多相关文章

  1. 一行代码完成定时任务调度,基于Quartz的UI可视化操作组件 GZY.Quartz.MUI

    前言 之前发布过第一个版本,有兴趣的可以去看看: NET Core 基于Quartz的UI可视化操作组件 GZY.Quartz.MUI 简介 GitHub开源地址:l2999019/GZY.Quart ...

  2. Spring - 基于注解的组件扫描

    关于Spring的书籍都会花很大篇幅来讲解Spring如何注入各种bean的问题,非常令人头疼,自己在工作中还从来没有用到过. 所以就要跳过那些篇章,直接学习基于注解的组件扫描. 发现spring2是 ...

  3. 基于Lumisoft.NET组件的SMTP账号登陆检测

    在邮件处理的方面,Lumisoft.NET可以说是非常不错的一个选择,我在前面几篇文章中都介绍过这个组件. 基于Lumisoft.NET组件开发碰到乱码等一些问题的解决 基于Lumisoft.NET组 ...

  4. 基于CMS的组件复用实践

    目前前端项目大多基于Vue.React.Angular等框架来实现,这一类框架都有一个明显的特点:基于模块化以及组件化思维.所以,开发者在使用上述框架时,实际上是在写一个一个的组件,并且组件与组件之间 ...

  5. 基于SOA的组件化业务基础平台[转]

    转自https://www.ibm.com/developerworks/cn/webservices/1111_xiaojg_soa/index.html 业务基础平台是业务逻辑和基础架构平台之间的 ...

  6. Unit02: 参数值注入 、 基于注解的组件扫描

    Unit02: 参数值注入 . 基于注解的组件扫描 (4)IOC (Inversion Of Controll 控制反转) 什么是IOC? 对象之间的依赖关系由容器来建立. 什么是DI? (Depen ...

  7. Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    Go/Python/Erlang编程语言对比分析及示例   本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...

  8. Window服务基于Quartz.Net组件实现定时任务调度(二)

    前言: 在上一章中,我们通过利用控制台实现定时任务调度,已经大致了解了如何基于Quartz.Net组件实现任务,至少包括三部分:job(作业),trigger(触发器),scheduler(调度器). ...

  9. 手把手做一个基于vue-cli的组件库(上篇)

    基于vue-cli4的ui组件库,先贴个最终效果吧,步骤有点多,准备分上下篇,上篇:如何做一个初步的组件.下篇:编写说明文档及页面优化.开工. GitHub源码地址:https://github.co ...

随机推荐

  1. Asp.Net Mvc 使用WebUploader 多图片上传

    来博客园有一个月了,哈哈.在这里学到了很多东西.今天也来试着分享一下学到的东西.希望能和大家做朋友共同进步. 最近由于项目需要上传多张图片,对于我这只菜鸟来说,以前上传图片都是直接拖得控件啊,而且还是 ...

  2. 前端框架 EasyUI (0) 重新温习(序言)

    几年前,参与过一个项目.那算是一个小型的信息管理系统,BS 结构的,前端用的是基于 jQuery 的 EasyUI 框架. 我进 Team 的时候,项目已经进入开发阶段半个多月了.听说整个项目的框架是 ...

  3. .NET Core系列 : 2 、project.json 这葫芦里卖的什么药

    .NET Core系列 : 1..NET Core 环境搭建和命令行CLI入门 介绍了.NET Core环境,本文介绍.NET Core中最重要的一个配置文件project.json的相关内容.我们可 ...

  4. 从备考PMP到与项目经理同呼吸

    前言 PMP是什么梗? 项目管理专业人士资格认证.它是由美国项目管理协会(Project Management Institute(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证 ...

  5. category中重写方法?

    问:可以在category中重写方法吗? 答:代码上可以实现 在category中重写方法,但在实际开发中,不建议这样做.如果确实需要重写原有方法也建议使用子类进行重写. category是为了更方便 ...

  6. Vue.js 2.0 和 React、Augular等其他框架的全方位对比

    引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那么你就来对了. 客观来说,作为核心团队成员,显然我们会 ...

  7. JavaScript之职责链模式

    一.概述 职责链模式(Chain of responsibility),就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有 ...

  8. 【转】39个让你受益的HTML5教程

    闲话少说,本文作者为大家收集了网上学习HTML5的资源,期望它们可以帮助大家更好地学习HTML5. 好人啊! 不过,作者原来说的40个只有39个,因为第5个和第8个是重复的. 原文在此! 1. 五分钟 ...

  9. 【知识必备】一文让你搞懂design设计的CoordinatorLayout和AppbarLayout联动,让Design设计更简单~

    一.写在前面 其实博主在之前已经对design包的各个控件都做了博文说明,无奈个人觉得理解不够深入,所以有了这篇更加深入的介绍,希望各位看官拍砖~ 二.从是什么开始 1.首先我们得知道Coordina ...

  10. 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

    相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...