• Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。;
  • Bootstrap来自 Twitter,是目前非常流行的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。;
  • Echarts是百度开发的一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器;
  • jinja基于python的模板引擎,是一种可以渲染HTML文件的模板语言;

在你阅读本篇博文之前,你应该对上述几种技术有一定的了解,因为这几种技术网上教程非常多,我这里就不复制粘贴原理了,直接从实战中阐述4者的结合应用。

这篇博客主要目的是让你快速在你的网页上显示各种简洁明了的图表。具体思路是:

Django后台从数据库中获取图表数据,封装为Python的字典或列表数据类型,然后使用jinja2模板语言,在HTML中为ECharts提供数据源,最后,为了体现出实用性,本篇博客还从bootstrap中选取了一个不错的模板进行展示;

准备工作:

bootstrap模板:https://v3.bootcss.com/examples/dashboard/

ECharts模板:http://echarts.baidu.com/examples/editor.html?c=pie-legend

1、入门示例:

核心思想:使用jinja2的safe过滤器为HTML提供简单数据列表

示例来源:ECharts官方教程第一个条状图 :

http://echarts.baidu.com/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>ECharts</title><!-- 引入 echarts.js --><script src="echarts.min.js"></script>
</head>
<body><!-- 为ECharts准备一个具备大小(宽高)的Dom --><div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data:['销量']},xAxis: {data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);</script>
</body>
</html>

我们看到官方给的示例中,主要我们要传送这2个数据项:

data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
data: [5, 20, 36, 10, 10, 20]

上面是一个是类型,下面一个是类型对应的数值。如何传值呢?我们先看看Django后台是如何封装这些数据的:

def bootstrap_study(request):item_lst = ["衬衫233", "羊毛衫22", "雪纺衫", "裤子", "高跟鞋", "帽子"]sales_lst = [10, 20, 30, 50, 80, 25]return render(request, 'testchao/bootstrap_study.html', {'item_lst': item_lst, 'sales_lst': sales_lst,})# return render(request, 'wr_login.html')pass

我们可以惊喜的发现,data数据简直一模一样,那么直接放上去不就行了吗?

但你直接使用jinja模板语言写上去后发现双引号被转义了,这个简单,我们让它不转义:

修改后的HTML部分代码如下:

// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('bbar'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data:['销量']},xAxis: {data: {{ item_lst|safe }}},yAxis: {},series: [{name: '销量',type: 'bar',data: {{ sales_lst|safe }}}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);

运行就OK了

2、进阶:结合JS进行数据封装

直接使用原始模板语言,不能很好地进行图标展示(如饼图)http://echarts.baidu.com/examples/editor.html?c=pie-legend

这个饼图比较复杂,数据量太大,我们直接使用上面的案例数据:

解决思路:使用jinja控制语句:

<div id="charttest" class="tab-pane fade"><h1 class="page-header">这是图表测试</h1><!-- 为ECharts准备一个具备大小(宽高)的Dom --><div id="pie" style="width: 600px;height:600px;"></div>var dom = document.getElementById("pie");var myChartPie = echarts.init(dom);var pie_data = getData()option = {title : {text: '同名数量统计',subtext: '纯属虚构',x:'center'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},legend: {type: 'scroll',orient: 'vertical',right: 10,top: 20,bottom: 20,// data: data.legendData,data: pie_data.legendData,selected: pie_data.selected,},series : [{name: '类型',type: 'pie',radius : '55%',center: ['40%', '50%'],selectedMode: 'single',data: pie_data.seriesData,itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]}function getData() {var legendData = [];var seriesData = [];var selected = {};{% for item in sales_class %}legendData.push('{{ item.0 }}');seriesData.push({name: '{{ item.0 }}',value: {{ item.1 }},});selected['{{ item.0 }}'] = true;{% endfor %}return {legendData: legendData,seriesData: seriesData,selected: selected};}if (option && typeof option === "object") {myChartPie.setOption(option, true);}</script></div>

可以看到,关键处循环赋值即可:

{% for item in sales_class %}legendData.push('{{ item.0 }}');seriesData.push({name: '{{ item.0 }}',value: {{ item.1 }},});selected['{{ item.0 }}'] = true;
{% endfor %}

本部分后端业务代码为:

def bootstrap_study(request):item_lst = ["衬衫233", "羊毛衫22", "雪纺衫", "裤子", "高跟鞋", "帽子"]sales_lst = [10, 20, 30, 50, 80, 25]sales_class = list(zip(item_lst, sales_lst))human_annotated_lst = get_dc_human_annotated_statistics_sql()return render(request, 'testchao/bootstrap_study.html', {'item_lst': item_lst, 'sales_lst': sales_lst,'sales_class': sales_class, 'human_annotated_lst': human_annotated_lst,})# return render(request, 'wr_login.html')pass

3、常见问题

  1. 注意模板语言的引号问题,数字数据不需要加;
  2. 如果你的数据从数据库中(如MySQL)读取,那么你获取的是一个生成器,在模板语言中依然具有生成器特性——即,只能用一次,你可以把它转化为list再放入传到HTML中

4、完整HTML代码

注:这里对bootstrap模板进行了一些优化,添加了标签项;

(工作比较忙,代码有些乱,请多多包涵,有任何疑问请随时提出,我会第一时间回复)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --><title>bootstrap_study</title><meta name="description" content=""><meta name="author" content=""><title>Dashboard Template for Bootstrap</title><script src="/static/testchao/js/jquery-3.1.0.js"></script><!-- Bootstrap core CSS --><link href="/static/testchao/css/bootstrap.css" rel="stylesheet"><!-- IE10 viewport hack for Surface/desktop Windows 8 bug --><link href="/static/testchao/css/ie10-viewport-bug-workaround.css" rel="stylesheet"><!-- Custom styles for this template --><link href="/static/testchao/css/dashboard.css" rel="stylesheet"><!-- Just for debugging purposes. Don't actually copy these 2 lines! --><!--[if lt IE 9]><script src="/static/testchao/js/ie8-responsive-file-warning.js"></script><![endif]--><script src="/static/testchao/js/ie-emulation-modes-warning.js"></script><script src="/static/testchao/js/echarts.js"></script><!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
</head>
<body><nav class="navbar navbar-inverse navbar-fixed-top"><div class="container-fluid"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="#">Project name</a></div><div id="navbar" class="navbar-collapse collapse"><ul class="nav navbar-nav navbar-right"><li><a href="#">Dashboard</a></li><li><a href="#">Settings</a></li><li><a href="#">Profile</a></li><li><a href="#">Help</a></li></ul><form class="navbar-form navbar-right"><input type="text" class="form-control" placeholder="Search..."></form></div></div></nav><div class="container-fluid"><div class="row"><div class="col-sm-3 col-md-2 sidebar"><ul class="nav nav-sidebar"><li><a data-toggle="tab" href="#Overview">Overview </a></li><li ><a data-toggle="tab" href="#charttest">图表测试 <span class="sr-only">(current)</span></a></li><li><a data-toggle="tab" href="#Analytics">Analytics</a></li><li><a data-toggle="tab" href="#Export">Export</a></li></ul><ul class="nav nav-sidebar"><li class="active"><a data-toggle="tab" href="#linechart">统计(内测)</a></li><li><a href="">Nav item again</a></li><li><a href="">One more nav</a></li><li><a href="">Another nav item</a></li><li><a href="">More navigation</a></li></ul><ul class="nav nav-sidebar"><li><a href="">Nav item again</a></li><li><a href="">One more nav</a></li><li><a href="">Another nav item</a></li></ul></div><div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"><div class="tab-content"><div id="Overview" class="tab-pane fade">这是总览,然而啥都没有(斜眼笑)<!--<div id="opie" style="height:800px; width:800px"></div>--><table>{% for item in sales_class %}<tr><td> {{ item.0 }}</td><td> {{ item.1 }}</td></tr>{% endfor %}</table><h3>233 </h3><table>{% for item in sales_class %}<tr><td> {{ item.0 }}</td><td> {{ item.1 }}</td></tr>{% endfor %}</table><div id="opie"></div><script>var dom = document.getElementById("opie");// var myChart = echarts.init(dom);//用于使chart自适应高度和宽度,通过窗体高宽计算容器高宽var resizeMainContainer = function () {dom.style.width = window.innerWidth+'px';dom.style.height = window.innerHeight*0.8+'px';};//设置div容器高宽resizeMainContainer();// 初始化图表var myChart = echarts.init(dom);$(window).on('resize',function(){////屏幕大小自适应,重置容器高宽resizeMainContainer();myChart.resize();});var data = genData(50);option = {title : {text: '同名数量统计',subtext: '纯属虚构',x:'center'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},legend: {type: 'scroll',orient: 'vertical',right: 10,top: 20,bottom: 20,data: data.legendData,selected: data.selected},series : [{name: '姓名',type: 'pie',radius : '55%',center: ['40%', '50%'],data: data.seriesData,itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]};function genData(count) {var nameList = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危'];var legendData = [];var seriesData = [];var selected = {};for (var i = 0; i < 50; i++) {name = Math.random() > 0.65? makeWord(4, 1) + '·' + makeWord(3, 0): makeWord(2, 1);legendData.push(name);seriesData.push({name: name,value: Math.round(Math.random() * 100000)});selected[name] = i < 6;}return {legendData: legendData,seriesData: seriesData,selected: selected};function makeWord(max, min) {var nameLen = Math.ceil(Math.random() * max + min);var name = [];for (var i = 0; i < nameLen; i++) {name.push(nameList[Math.round(Math.random() * nameList.length - 1)]);}return name.join('');}}if (option && typeof option === "object") {myChart.setOption(option, true);}</script></div><div id="charttest" class="tab-pane fade"><h1 class="page-header">这是图表测试</h1><!-- 为ECharts准备一个具备大小(宽高)的Dom --><div id="pie" style="width: 600px;height:600px;"></div><div id="bbar" style="width: 600px;height:600px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('bbar'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data:['销量']},xAxis: {data: {{ item_lst|safe }}},yAxis: {},series: [{name: '销量',type: 'bar',data: {{ sales_lst|safe }}}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);var dom = document.getElementById("pie");var myChartPie = echarts.init(dom);var pie_data = getData()option = {title : {text: '同名数量统计',subtext: '纯属虚构',x:'center'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},legend: {type: 'scroll',orient: 'vertical',right: 10,top: 20,bottom: 20,// data: data.legendData,data: pie_data.legendData,selected: pie_data.selected,},series : [{name: '类型',type: 'pie',radius : '55%',center: ['40%', '50%'],selectedMode: 'single',data: pie_data.seriesData,itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]}function getData() {var legendData = [];var seriesData = [];var selected = {};{% for item in sales_class %}legendData.push('{{ item.0 }}');seriesData.push({name: '{{ item.0 }}',value: {{ item.1 }},});selected['{{ item.0 }}'] = true;{% endfor %}return {legendData: legendData,seriesData: seriesData,selected: selected};}if (option && typeof option === "object") {myChartPie.setOption(option, true);}</script></div><div id="Analytics" class="tab-pane fade">Analytics<h1 class="page-header">Dashboard</h1><div class="row placeholders"><div class="col-xs-6 col-sm-3 placeholder"><img src="https://img-blog.csdnimg.cn/2022010618461784720.gif" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"><h4>Label</h4><span class="text-muted">Something else</span></div><div class="col-xs-6 col-sm-3 placeholder"><img src="https://img-blog.csdnimg.cn/2022010618461784720.gif" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"><h4>Label</h4><span class="text-muted">Something else</span></div><div class="col-xs-6 col-sm-3 placeholder"><img src="https://img-blog.csdnimg.cn/2022010618461784720.gif" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"><h4>Label</h4><span class="text-muted">Something else</span></div><div class="col-xs-6 col-sm-3 placeholder"><img src="https://img-blog.csdnimg.cn/2022010618461784720.gif" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"><h4>Label</h4><span class="text-muted">Something else</span></div></div><h2 class="sub-header">Section title</h2><div class="table-responsive"><table class="table table-striped"><thead><tr><th>#</th><th>Header</th><th>Header</th><th>Header</th><th>Header</th></tr></thead><tbody><tr><td>1,001</td><td>Lorem</td><td>ipsum</td><td>dolor</td><td>sit</td></tr><tr><td>1,002</td><td>amet</td><td>consectetur</td><td>adipiscing</td><td>elit</td></tr><tr><td>1,003</td><td>Integer</td><td>nec</td><td>odio</td><td>Praesent</td></tr><tr><td>1,003</td><td>libero</td><td>Sed</td><td>cursus</td><td>ante</td></tr><tr><td>1,004</td><td>dapibus</td><td>diam</td><td>Sed</td><td>nisi</td></tr><tr><td>1,005</td><td>Nulla</td><td>quis</td><td>sem</td><td>at</td></tr><tr><td>1,006</td><td>nibh</td><td>elementum</td><td>imperdiet</td><td>Duis</td></tr><tr><td>1,007</td><td>sagittis</td><td>ipsum</td><td>Praesent</td><td>mauris</td></tr><tr><td>1,008</td><td>Fusce</td><td>nec</td><td>tellus</td><td>sed</td></tr><tr><td>1,009</td><td>augue</td><td>semper</td><td>porta</td><td>Mauris</td></tr><tr><td>1,010</td><td>massa</td><td>Vestibulum</td><td>lacinia</td><td>arcu</td></tr><tr><td>1,011</td><td>eget</td><td>nulla</td><td>Class</td><td>aptent</td></tr><tr><td>1,012</td><td>taciti</td><td>sociosqu</td><td>ad</td><td>litora</td></tr><tr><td>1,013</td><td>torquent</td><td>per</td><td>conubia</td><td>nostra</td></tr><tr><td>1,014</td><td>per</td><td>inceptos</td><td>himenaeos</td><td>Curabitur</td></tr><tr><td>1,015</td><td>sodales</td><td>ligula</td><td>in</td><td>libero</td></tr></tbody></table></div></div><div id="Export" class="tab-pane fade"><div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data:['销量']},xAxis: {data: {{ item_lst|safe }}},yAxis: {},series: [{name: '销量',type: 'bar',data: {{ sales_lst|safe }}}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);</script>Export</div><div id="linechart" class="tab-pane fade active in"><h2>工作量统计</h2></div></div></div></div></div><!-- Bootstrap core JavaScript================================================== --><!-- Placed at the end of the document so the pages load faster --><script src="/static/testchao/js/jquery.min.js"></script><script>window.jQuery || document.write('<script src="./js/jquery.min.js"><\/script>')</script><script src="/static/testchao/js/bootstrap.min.js"></script><!-- Just to make our placeholder images work. Don't actually copy the next line! --><script src="/static/testchao/js/holder.min.js"></script><!-- IE10 viewport hack for Surface/desktop Windows 8 bug --><script src="/static/testchao/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>

使用Echarts在网页中显示漂亮图例实战(Bootstrap+Django+ECharts+Jinja2使用入门)相关推荐

  1. 将VS2005中的.CS文件在网页中显示的方法

    今天在做AccessMembershipProvider的DEMO时,想把支持Access数据库提供程序的源码在网页中显示出来,可是复制源码后在网页中显示的是不换行的,后来我在尝试了很多办法后,终于有 ...

  2. html网页中显示乱码的问题解决

    在网页中显示中文乱码. 情景: 在html页面写了个javacript的代码,里面有alert("中文"),但弹窗出来的对话框显示的是中文乱码. 解决: 在head头加 <m ...

  3. 非常好的在网页中显示pdf的方法

    今天有一需求,要在网页中显示pdf,于是立马开始搜索解决方案,无意中发现一个非常好的解决方法,详见http://blogs.adobe.com/pdfdevjunkie/web_designers_g ...

  4. 网页中显示xml,直接显示xml格式的文件

    第一种方法 使用<pre></pre>包围代码(在浏览器中测试不行啊,但是在富编辑器中又可以,怪): 使用<xmp></xmp>包围代码(官方不推荐,但 ...

  5. html显示docx,网页中显示PDF的HTML代码.docx

    网页中显示PDF的HTML代码 您可能想打开文档至某一特别页面或目标,或显示书签.要与 链接一起放入一个动作命令,可紧接在 PDF 文件名后面键入数字符号 (#) 和该命令.以下表格显示可能的动作命令 ...

  6. 在html中显示word,如何在浏览器网页中显示word文件内容

    把word文件读到byte[]中,再Response.OutputStream.Write(bytes)到客户端去 Page_Load事件中写: //FileStream   fs   =   new ...

  7. 在网页中显示CHM (c# csharp .net asp.net winform)

    CHM即"已编译的帮助文件",主要由.hhc(目录文件)..hhk(索引文件)以及相应的帮助主题文件(.html,.htm)这些内容编译而成. 方法对比 在网页中显示CHM内容,大 ...

  8. 基于JavaWeb JavaScript的根据时间段的不同,在网页中显示不同的问候语

    题目: 根据时间段的不同,在网页中显示不同的问候语,若小时数在12点以前,则输出"早上好!"的问候语,颜色为蓝色:若在12点至18点,则输出"下午好!"颜色为红 ...

  9. 在html中加入pdf文件吗,如何在网页中显示PDF文件

    我们是不是对百度文库能直接在网页上显示PDF文件感到好奇,你是否也想实现这样的功能?很多朋友认为可以直接在网页中插入代码就可以实现这个功能,其实要在网页中完整地显示PDF文件,需要把PDF文件转换成S ...

  10. html天气插件iframe,HTML_利用iframe在网页中显示天气附效果截图,css: 复制代码代码如下: *{margi - phpStudy...

    利用iframe在网页中显示天气附效果截图 css: 复制代码代码如下: *{margin:0;padding:0;list-style-type:none;} a,img{border:0;} bo ...

最新文章

  1. MySQL登录时ERROR 1045:Access denied for user ‘root’@’localhost’ (using password: YES)
  2. Confluence 6 计划任务
  3. 写的函数符号表里没有_你有没有想过,C语言 main 函数到底为啥这么写?
  4. python3 hashlib加密库 md5 sha1 sha256 sha384 sha512 加盐
  5. OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五
  6. golang Reflect包
  7. Factory Method工厂方法模式
  8. java类的两个基本成分_Java类文件的基本结构
  9. IBM斥资3.6亿美元建史上最复杂云计算中心
  10. RabbitMq入门(七)消息处理(消息持久化autoDelete、消息确认ACK机制)
  11. faster-rcnn for tensorflow 测试过程
  12. 中职计算机老师培训总结报告,中职计算机教师个人工作总结范文5篇.doc
  13. mysql大于等于怎么写_MySQL 对于千万级的大表要怎么优化?我写了6000字的深度解读...
  14. 微信小程序上传照片加水印
  15. sif一线通输出协议以及代码实现
  16. 微信开门,给你简单极致的开门体验!
  17. PS2019工具介绍笔记(一)
  18. 黄金短线交易技巧是什么?
  19. 基于C++实现(WinForm)家谱管理系统【100010033】
  20. 将csv文件分割成多个文件

热门文章

  1. python+selenium+request实行全自动12306抢票和购票
  2. 按键精灵输出中文乱码,输出不是?,输出如Ö16:48ÀÂ
  3. 为什么我的微信小程序开发工具调试窗口一片空白?
  4. [Intellij IDEA] 通过学生认证免费激活IDEA
  5. 李白藏头诗鸿蒙,女子示爱的诗词
  6. php表格整体怎么移动,超级表格新版移动端操作指南
  7. android通讯录开发二 数据表各字段含义
  8. Redis Key(键) 命令使用
  9. codewars练习记录15 js
  10. dex2oat导致机器很卡的问题分析