webapi轨迹占用内存 高德地图_高德地图webapi - CSDN
精华内容
参与话题
  • 【JS API V2.0】 本指望全面提升一下性能,结果发现一些硬伤,迫不得已转到1.4.15版本,先说一下最新的v2.0的问题。 因为务业需要规划线路,但是这个版本中,规划线路,并且经过中间点时,部分window 7 旗舰 ...

    【JS API V2.0】

    本指望全面提升一下性能,结果发现一些硬伤,迫不得已转到1.4.15版本,先说一下最新的v2.0的问题。

    1. 因为务业需要规划线路,但是这个版本中,规划线路,并且经过中间点时,部分window 7 旗舰 chrome 报错,报错信息:Uncaught Error: createProgram fail  chrome 版本 81.0.4044.113(正式版本) (64 位) win7 64位即便是官方demo 也会报错,后来和提交工单,回复未复现,后来工期急就没跟踪,上线后有极少部分用户反馈报错
    2. LabelMarker 部分点位在地图放大到一定程度后 不再触发click mouseover 等事件,极少量点位会出现这种情况,目测是某些点位附近可能有什么隐藏物吧,总之就是不触发,但是奇怪的是,同样的经纬度有时确是可以正确触发事件,也可能是LabelMarker 有问题
    3. dblclick 事件 LabelMarker 的dblclick 事件 触发的同时还会触发click 事件,如果同时绑定click 事件 那就尴尬了,先触发click 再触发dblclick 事件,目测是底层对dblclick 处理有问题,click 事件应该有300ms 延时以确认是否有双击,这个还好,可以手动纠正,

    【JS API V1.4.15】

    1. SvgMarker  在创建及地图缩放时的处理有极大的性能问题,SvgMarker 本身不建议大量的点位应用,海量点不合适的话,建议使用LabelMarker,
    2. LabelMarker 在这个版本不提供dblclick 事件,解决办法就是手动判断两次点击是否超300ms 来断定
    3. LabelMarker 实例 第一次调用setText setIcon 后再次调用方法不起作用,解决办法,调用前先隐藏,调用后再显示,
    4. LabelMaker 在某些座标下的某种缩放级别时(10+)事件不触发,暂未发现

    【性能优化】

    先说结论,再说问题

    1. 关掉所有能关掉的动画效果 (参照文档)
    2. SvgMarker 创建时请先隐藏,添加完成后再显示,或使用 AMap.OverlayGroup 统一处理下
    3. 如果点位超过500还是不要用SvgMarker 试试LabelMarker,并关掉动画
    4. 千万要慎用地图实例 setFitView 方法,如果要用请一定要带上参数,禁掉动画,可以使用地图实例的setBounds方法或setZoomAndCenter 等曲线救国,后面会说这个问题的严重性
    5. 认真阅读官方文档,很多时候是使用不规范造成的性能问题

    下面来看下1.4.15版本创建4000 SvgMarker 的性能问题

    8.67 s 创建用了这么长时间。。。

    再看其中一个SvgMarker性能开销,

    使用地图实例的add 方法添加 一组SvgMarker ,显然它们是被一个个加到页面当中的,这些marker dom节点被不断的加入dom必然引起性能开销,根据dom性能优化策略,可以在创建时就指定marker 为隐藏,后边再显示, 或是用官方的AMap.OverlayGroup处理,经此处理后,创建SvgMarker性能有了较大提升,4000点位用时不到3s

    再往下看setFitView 的性能问题

    1.9 min 。。。

    再往下看这密密麻麻的是什么

     不知道在执行什么鬼动画,明明感觉已经把动画都关了呢,点进去看看,

    实在是报歉,这个段源码目测是个公共方法,一定在一个地方在调用,修改它是徒劳的,也可能是api的某个方法会触发它,原来的业务逻辑 在4000 marker 创建后会修复一下视图范围,原来就直接调用了setFitView ,会不会是它呢?干掉它,一试,果然,

    怪不得就算是 v2.0 api 使用labelMarker都能卡成狗,被这货给坑了。

    虽然4000点位已经跑进3s内但为了支撑1万+点位的marker  新需求,显然不能再使用SvgMarker 经过计算发现1万点位性能开销要6s,实在是不合适,好在1.4.15版本提供了labelMaker 作为海量点同样为了达到svgMaker一样的外观效果,可以指定svg 作为icon 即便你需要动态的改变它的颜色等,贴出代码(和SvgMarker 一样的水滴形状)

    export const getSVGSrc = (color: string) => {
        return `data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2245%22%20height%3D%2260%22%20%3E%3Cg%20%3E%3Cpath%20stroke-width%3D%220%22%20fill%3D%22${encodeURIComponent(color)}%22%20d%3D%22M22.5%2C0C10.043%2C0%2C0%2C9.75%2C0%2C21.75C0%2C41.125%2C22.5%2C60%2C22.5%2C60s22.5%2C-19.25%2C22.5%2C-38.25C45%2C9.75%2C34.958%2C0%2C22.5%2C0z%22%20%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E`
    };

    需要注意的是labelMaker 是不会被地图实例的clearMap 方法所清除,要清除请使用labelsLayer 的clear 或remove 方法

    下面来看labelMaker的性能开销情况(同样4000点位)ps:准确的说此时maker还未绘制

    下面看2万点的完整绘制时间

    2万点创建耗时

    绘制耗时4S左右

    咨询高德 地图渲染就是靠动画帧驱动的所以有这个耗时,后边的Microtasks目测也是绘制的一部分

    暂时告一段落,可以松一口气,待续其它性能问题

     

    展开全文
  • 地图战争

    千次阅读 2013-02-20 10:29:40
    地图毫无疑问将会是未来重要的入口之一,如今各大巨头都争先恐后的在这块领域上下功夫。国外有谷歌、诺基亚等元老巨头,而苹果也在近年加入角逐。回头看看国内,有高德、四维图新等老大哥,而百度、腾讯等移动互联网...
    地图毫无疑问将会是未来重要的入口之一,如今各大巨头都争先恐后的在这块领域上下功夫。国外有谷歌、诺基亚等元老巨头,而苹果也在近年加入角逐。回头看看国内,有高德、四维图新等老大哥,而百度、腾讯等移动互联网巨头也纷纷加入,希望能问鼎中原。
    

      不管出师何因,都只想得到移动互联网的船票,但地图这条路不是那么容易走的。

      高德

      从2002年公司成立开始,高德耗费了大量时间和数以千计的人力,定位中国的楼宇、商户的经纬度,搜集各地道路属性信息。在这个变化巨大的国度(每年要更新的地图信息高达30%至50%),这是一个和时间赛跑的工作。

      但这种依靠时间积累起的门槛也让别人很难再进入这个领域。截至2012年第三季度,高德拥有1200万个用于导航的POI,覆盖56个城市7500平方公里的街区。“你要想做成一件事,首先要从最脏最累的活干起,那就去全国各地扫街吧。”高德创始人和CEO成从武曾这样解释自己的创业史。

      中国有11家拥有电子地图测绘资质的公司,最终高德和另一家地图数据商四维图新成为最底层的地图数据双寡头。包括百度地图、谷歌地图在内的绝大多数你所见到的电子地图,都依赖它们提供地图数据。它们还理所当然地垄断了中国的汽车预装导航地图市场。

      2011年,高德软件的总营收达到创纪录的1.27亿美元,但在这一年的年底,成从武决定把高德变成为一个互联网公司。“不惜一切代价投资移动互联网业务。”他说。

      两年之内,高德在副总裁这一层级中,就加入了CTO崔海、CMO金俊、云平台中心VP陈军、移动互联网产品技术VP冯汉平等多名高管,这些人全都有互联网及跨国公司背景。原来的高德以两类人为主—蓝领采集员和汽车导航的销售人员,现在越来越多的85后、90后加入进来。高德地图应用负责人就是一位80后。“公司里是两种文化,说两种语境的话,你不得不来回切换。”金俊说。

      2011年高德正式上线了面向个人用户的智能手机地图。成从武对于从B2B走到B2C这一战略的急迫性显而易见。他曾公开批评团队在移动互联网时代的执行力不够,并让一位创业元老提前退休。这一系列转变,源自中国互联网巨头已经发起了一场关于未来地图的战争。

      地图,正成为每个智能手机里的必备工具。同时,基于地图的大数据和基于位置的服务成为移动互联网的角逐焦点,手机地图俨然有成为下一个重量级入口的趋势。

      对高德来说,这是一个机会,但如跟不上也是一个危险。更直接的坏消息则是,中国汽车在2010年结束了连续多年增长30%的速度,随后两年增长都不足10%。为家用轿车提供导航数据一直占据高德软件一半以上的收入。继续依靠汽车导航产品,高德迟早会碰到天花板。

      无论怎样,高德这家传统电子地图行业里的隐形冠军,现在必须参与一场新的地图大战。作为中国最大的地图数据供应商之一,高德占据了产业链最上游,但这场基于移动互联网的战争,游戏规则完全不一样了。

    地图战争:一张船票惹的祸


      四维图新

      2011年底,因为高德在欧洲导航新标准NDS上跟进不力,曾经是它金牌客户的宝马宣布在新车系中将预装四维图新的导航数据。

      在汽车导航市场,高德一直主打高端车型,宝马和奥迪是其最重要的两个客户。而四维图新则在中端车市场占有优势。二者合计占汽车导航市场超过90%的份额。

      和高德一样,四维图新同样拥有基础数据采集资质。不同的是,四维图新并没有试图向消费端转型,而是通过一系列的并购后将自己的产品定位于导航数据、动态交通信息、车联网服务,专注于地图导航的产业链上游。

      对于高德来说更大的威胁是,这个老对手已经开始在车联网上积累技术,并进行了商业化尝试。

      四维图新的子公司世纪高通也签下了宝马的单子,提供路况信息服务。路况信息很多地图服务商都能提供,但要做到即时和精确却是一个复杂的过程,而这种数据的获得和发送正是移动互联网的核心内容。

      出租车公司是世纪高通采集数据的核心来源,因为出租车每时每刻都在城市道路上行驶,行驶的路线也基本囊括所有道路,通过它收集到的数据,准确性和稳定性相对高得多。

      世纪高通几乎和每个重点城市的出租车公司都建立了深度合作,方式是购买或资源互换。这意味着,每一辆有合作的出租车只要在路上,都会通过一个数据采集器,每隔几十秒就把自己所在位置的路况发到世纪高通公司的数据库里。

      对于出租车发送的数据,负责数据清洗和鉴别的工程师会根据出租车的连续轨迹,把不准确的挑出去弃置一旁。

      这是一个极其复杂的过程。比如出租车发回的路况信息显示不动,工程师就要分析,这是司机停在某个地方趴活,还是它行驶途中遇到了堵车。这时候需要出租车公司给出信息,这辆车是空载还是有客。如果有客人,堵车的可能性就更大。如果是空车,还要进一步分析路况,这辆车是在主路还是辅路上。如果是在主路上,司机停车趴活几乎是不可能的,堵车的可能性更大。如果是辅路,又要根据它最近发回的两个轨迹点之间进行判断,如果是在机场或酒店,则是上下客的可能性更大。

      通过出租车采集到的数据被称为浮动车数据,世纪高通拥有中国最大的浮动车数据平台。此外,世纪高通在其他城市还有一些来自政府的固定检测器、红外雷达等合作项目,它们会传达一些另外的信息,来帮助工程师对数据进行判断甄别。

      为了保证服务的质量,宝马对信息的安全性做了严格的要求。在宝马中国的安全手册里罗列了所有可能发生的情况,比如服务器和服务器的对接,如果服务器做一些扩容,要提前多少天通知,要把扩容的具体步骤报上去;还有软件的升级,也要提前在自己的空间里测试多少天,才能给客户的车上软件升级。

      为了和宝马的需求对接,世纪高通同样有一套自己的管理体系来保证信息服务的不中断,比如保障服务器不被恶意攻击、不会中病毒等等。世纪高通还有自己的监控软件,USB对接、磁盘写满、风扇温度保护等措施,一旦出现问题,这些系统就会报警,技术人员可立即处理。

      显然,这一系列带有移动互联网特质的操作方式和高德之前的数据处理方式不太一样。

      百度

      百度与酷讯网进行了合作,在百度地图网页端和手机端均呈现来自酷讯的酒店预订信息。

      酷讯网是一家在线旅游服务提供商,提供机票、酒店和旅游路线推荐。百度看中它20万家酒店房型、价格和经纬度等一系列有用数据。而酷讯则是看中百度带来的网页端和移动端的流量入口。“像酷讯这些更加细分、更Web1.0的数据,是百度这种根植于互联网页面搜索的公司不大会涉及的。这也是第三方公司最大的价值。”酷讯无限事业部总监陈波告诉《财经天下》周刊。

      事实上,在百度地图4.3版本的酒店中,百度不只用了酷讯的数据,他们同样使用了去哪儿、携程和艺龙的数据来丰富酒店类POI点。这就对百度地图的去重复算法提出了很高的要求,以免同一POI点出现了多个不同命名,让用户不明就里。

      同时,第三方公司也会将自己掌握的POI点数据接入不同地图平台的API,利用这些互联网公司的流量,为自己的服务带去用户。酷讯网就不单单是只与百度合作,他们的数据也会在搜狗地图的网页端出现。还有一个典型的例子就是大众点评网,你可以在百度、搜搜地图的网页端看到大众点评的评论和打分信息。

      对于大多数第三方公司来说,自然是接入越多平台越好。但平台商也同样会对合作伙伴进行挑选,力求呈现的信息高质,毕竟用户不会有那么强的耐心去一条条检索。

      百度的底层数据直接来自四维图新、灵图等多家地图数据提供商。这固然会带来很多POI点信息重复的难题,但数据在量上的叠加至少从某种程度上弥补了不是自采的劣势。至于数据重复、出错,利用算法和用户纠错可以大致解决这些问题。“这些底层的数据提供商也在不断根据反馈进行更改,事实上百度地图的数据质量与自采的差距已经没有那么明显了。”一位来自百度地图的管理层人士说。

      这种购买地图底层数据,自己先做后改或者边做边改的方式,事实上是各大互联网地图服务提供商的一致玩法。这些巨头级别的玩家并不怕出错和更改,对他们来说,互联网地图存在几十米的误差并不是大问题。同时,与用户更加贴近且基数大,也不用害怕缺乏用户的反馈。互联网公司的特质就是产品反应速度快、版本更新速度快、对用户需求的嗅觉更加灵敏。

      在众多涉足地图应用的互联网公司中,百度无疑是动力最强的一个。

      2012年10月17日,百度宣布分拆百度地图、百度身边等部门,成立专门的LBS事业部。随后,百度的招聘页面出现了大量和LBS相关的岗位。

      百度“框计算”的这种一站式思路在地图平台上做了一次平移。在这之前,百度地图的移动端产品也进行了一次大规模升级,百度地图4.0版本多出了“免费语音导航、室内定位、实时公交、生活搜索”四大新功能。加载页面的口号也从“全能地图助手”更改为“开启智能生活”。

      “开启智能生活”的背后,是接入了各式各样的功能:搜索附近团购、优惠、美食、酒店等一系列生活信息。越多的数据接入,百度就知道得越多,只需要对用户选择这一行为进行挖掘,比如用户喜欢在哪些场景选择哪些服务,这些再与百度整个账号体系一打通,其平台战略的商业模式便呼之欲出。毕竟在地图平台这个概念中,查询即搜索。而搜索如何变现,百度自然是极其擅长的。

    地图战争:一张船票惹的祸


      腾讯

      在北京北四环的中国技术交易大厦6楼,腾讯地图平台部的数据总监张弦给《财经天下》周刊算了一笔账。“养活200多人的团队一年几千万,买服务器几千万,油费差旅费、服务器电费、外包费用、研发费用等等,这些加起来,差不多几个亿。”他没有说出一个具体数字,但绝对超过外界盛传的两个亿。这还仅仅是目前腾讯搜搜街景团队采集北京、上海、广州、拉萨这四个城市的街景数据花费的资金。

      但张弦并没有觉得这有什么大不了的,他对搜搜地图的街景产品更感兴奋:地图终于不再是一条条线和一个个点,而是一张又一张可以自由放大缩小的实景。“这是一个革命,”他强调,“地图形态上的革命。”

      为什么做街景?据张弦回忆,在2007年谷歌推出街景计划时,马化腾表现出了极大的兴趣,但因为看不清商业模式而作罢。“卖给导航仪生产商?一台几十块,一年卖个几万台,连市场部都养不起。”张弦笑称。

      但现在就不一样了。坐拥QQ、微信的腾讯已经拥有完善的生态圈。街景跟杀手级别应用微信的结合,一直被业内看好。更关键的是,街景具有的真实性会让用户获得极佳的体验。最新的搜搜地图应用上线不到24小时,便已冲至App Store免费榜第一名。而这个版本号为2.3的应用内置了街景功能,隐藏在二级菜单内。分享街景图片至微信的功能则隐藏得更深–但这短短的24小时内,就有上万次分享。

      这个成绩让整个开发团队十分惊喜,同时也惊讶,他们似乎看到了街景的潜力,此前,他们一直以为街景项目的声誉价值更大。

      搜搜地图监控了上线的四个城市街景地图的访问来源,发现了一组很有意思的数字:北上广的街景只有10%的访问者IP是来自当地,剩下90%来自这些城市周边省市。“我们让人们不用出门就可以看到他们一辈子可能都不会踏足的地方。”张弦十分自豪。

      这也很自然地衍生出街景产品的旅游价值。已经有在线旅游服务商和酒店预订商找上门来,谈论接入街景API的商业合作。有了这类需求,下一步街景团队要做的就很清晰:将一个又一个POI点标注在街景的高清照片上即可。

      事实上,巨头们也并不着急赚钱。

      “属于地图的商业模式并没有明确出现,除了发展时间短之外,最根本原因还是单一产品的使用人数没有达到一个更高的量级。3亿之后,讨论这个问题才有意义。”孔祥来说。他是国内最早一批互联网地图人,曾在Go2map(图行天下)任职。2004年,Go2map被搜狐收购后改名为搜狗地图,现任搜狗地图总经理。根据他的观察,在一个由LBS衍生出的O2O闭环中,从开启地图应用到找到一个可以消费的商户过程太长,仅有小部分用户会完全走完这个行为链条。只有当基数足够大时,才可以探讨商业模式。现在,巨头们做的事情还是在烧钱。

      结尾

      目前地图仍没有真正的霸主,即使现在算是巨头的高德和四维图新,只要急功近利,随时都有可能走火入魔。

    本文转自雷锋网

    展开全文
  • UNIAPP项目之旅

    2020-03-03 09:49:00
    一:uniapp(吹捧一波) uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、微信小程序,百度小程序,支付宝小程序等多个平台。(听起来好像很强大!...

    **

    一:uniapp(简介)

    **

    1. 优点:uni-app 是DCloud公司出品的国产产品。是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、微信小程序,百度小程序,支付宝小程序等多个平台,即混合开发。(听起来好像很强大!) 。官网:https://uniapp.dcloud.io/
      uniapp封装的组件和微信小程序的组件几乎没差。扩展能力强,封装了H5+,支持原生Android,ios开发。可以将原有的移动应用和H5应用改成uni-app应用。uni-app在跨平台的过程中,不牺牲平台特色,可调用平台专有能力,也就是uniapp封装的满足不了需求时,可以调用对应平台的专有API。
      在这里插入图片描述
      2:**缺点:**问世时间短,有些地方不完善,对于使用中的一些bug及问题,官方回应的不是很及时。可以加一下qq群或者去社区和其他uni-app开发者一起讨论。
      **

    二:编辑工具HbuilderX

    **
    HBuilderX内置相关环境,开箱即用,无需配置nodejs,下载App开发版,可开箱即用;如下载标准版,在运行或发行uni-app时,会提示安装uni-app插件,插件下载完成后方可使用。(还是很方便的)
    **

    三:uniapp(注意事项)

    1. 地图功能:使用uniapp框架中封装的map组件,在手机上显示的是高德地图,在浏览器里打开显示的是腾讯地图。

    2. uni-app分 应用生命周期 , 页面生命周期,组件生命周期

      应用生命周期:可以理解为整个应用的事件函数,全局只触发一次,例如:监听应用在手机进程中的前后台切换,就可以在onShow和onHide生命周期里监听,同时也可以检测出手机是否锁屏,这些函数都必须只可在app.vue文件里监听。在我的项目里用到了onLaunch去监听手机的推送消息。
      在这里插入图片描述
      ② 页面生命周期:
      在这里插入图片描述
      在这里插入图片描述
      ③ 组件生命周期:
      在这里插入图片描述
      总结:组件没有onLoad事件,那么created,onload,mounted的执行顺序经验证是这样的:created > onload > mounted,created是在模板渲染前,mounted是在模板渲染之后,onload是在页面渲染之后,如果你在onload中对页面参数赋值,正好要将这个值传给组件。组件又正好需要onload时调用时,要使用mounted事件,例如:

      页面代码:
      在这里插入图片描述
      组件代码:
      在这里插入图片描述
      **

    四:背景图片

    **
    当时写项目的时候,使用的是background-image,本地的图片,在手机上运行的时候不显示,也没有报错,看官网如下介绍:然而我直接更换为image标签就可以了,之后又巩固了下使用背景图片和image标签的利弊。
    ① background-image的优势:
    节省img标签所占用的空间
    便于布局(例如将文字布局在图片上,直接使用padding调整即可,使用margin会导致边距冲突)
    ②什么情况下应该使用img标签:
    由于搜索引擎不搜索css,所以当图片可以帮助网页获取流量时,应该使用img标签,且同时设置alt 属性对图像进行说明
    在这里插入图片描述
    **

    五:页面跳转API (注意事项)

    1. uni.navigateTo(OBJECT):跳转到应用内某个非 tabBar 的页面的路径 , 路径后可以带参数,但保留当前页面(页面栈内),使用uni.navigateBack可以返回到原页面,跳转的url有长度限制,太长的字符串会传递失败,可使用窗体通信(emit,emit,on)、全局变量,或encodeURIComponent(JSON.stringify(item)等多种方式解决
      在这里插入图片描述在这里插入图片描述
      2.uni.redirectTo(OBJECT) 和navigareTo的唯一区别是跳转的时候会关闭当前页面,
      3.uni.reLaunch(OBJECT) 关闭所有页面,打开到应用内的某个页面。
      在这里插入图片描述
      总结:注意用的场景不一样,针对不同的业务场景需要去使用。
      **

    六:UNIAPP实现高德地图轨迹回放注意事项:(只针对app,其他平台可能就是其他的方法,不同平台有受限制)

    1.uni-app框架里没有地图轨迹回放的API,需要引入高德地图在线原生API,在HTML文件里使用API,那么如何来引入高德的在线地址呢?
    ① Uni-app中有介绍到使用标签组件,(当然也可以在.VUE文件里直接JS创建一个子web-view来加载HTML)App 平台同时支持网络网页和本地网页,但本地网页及相关资源(JS、CSS等文件)必须放在uni-app项目根目录 hybrid–>HTML文件夹下,试例如下:第一张是项目里的.VUE文件,此文件里SRC绑定的是第二张图片里的HTML文件的本地地址,注意HTML文件里引入高德在线API地址时,地址后面需要加上你在高德地图官网申请的key,弄完这些后就可以在HTML文件里调用高德地图的API了;

    在这里插入图片描述
    在这里插入图片描述
    注意点:web-view是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面,在招商运营管理这个app项目里,轨迹回放只能是另起一个页面来承载,又涉及到一个uni-app里.VUE文件和HTML网页之间互相传参的问题,实际项目里用到的是.VUE文件向HTML文件传参以及HTML文件接收参数,所以只分享这一部分:如果传递的数据类型是object和array类型,则需要JSON.strignfy()序列化后才能正常传递过去,那在HTML页面接收就需要把参数截取下来JSON.parse()处理后能正常使用;
    Web-view加载的HTML向UNIAPP应用内通信请参考:https://ask.dcloud.net.cn/article/35083

    七:UNIAPP推送之 – unipush(支持HBUILDERX1.7.2以上)

    UNIPUSH是DCloud推出的集成型统一推送服务,内建了苹果、华为、小米、OPPO、VIVO、魅族等手机厂商的系统级推送和个推等第三方推送。首先需要先开通此服务,开通前又需要先创建自己的hbuilder账号登录到Dcloud开发者中心进行实名认证:详见unipush开通指南
    unipush使用指南
    以下截图是Dcloud账号创建的项目应用,其中APPID就是在hbuilder里创建项目后自动分配给此项目的一个唯一标识,打包的时候也会用到
    在这里插入图片描述
    在这里插入图片描述
    由于UNIAPP里没有专门的API调用push功能,在app里处理的话,需要调用H5里的plus.push.addEventListener(‘receive’,function(msg){}),当然,一次可能会接收到多条推送消息,那么如何处理点击对应的消息到达对应的消息页面呢?在这个项目里,解决方法是使用了getCurrentPages()来获取栈中所有的页面实例,返回的是一个不可序列化的数组对象,再获取当前的实例,处理逻辑:根据当前页面的路由决定使用跳转页面的方式,如果当前页面的路由是需要打开的页面的路由,则关闭当前的页面跳转到新得一个页面,使用redirectTo跳转页面,如果当前页面的路由不是需要打开的页面的路由,则直接跳转到需要打开的页面,使用navigateTo跳转页面。
    在这里插入图片描述

    八:定位偏移问题

    1.UNIAPP框架里对地图进行了封装,在app上显示的是高德地图,在浏览器显示的是腾讯地图。在招商运营管理app项目里有记录运行轨迹的功能,即在地图上描点连线形成轨迹,期间遇到的问题:多久打一个点合适,以及打点连线后轨迹偏移,经过多次测试,由最开始1s,5s打一次点,运行到一定时间后,程序就会跑死的情况,到最后决定10s打一次点,并采用对比两点之间的距离,大于20m才视为有效点显示在地图上(可通过H5规范里的plus.map里的API来实现),同时后台需要的数据是wgs84的坐标,而高德的是gcj02的坐标,那么此时打点的坐标数据其实都是gcj02的,不是后台需要的数据,需要转换成wgs84的格式传给后台,而地图上还需保留gcj02的坐标来显示。
    安卓解决方法:uniapp支持引入原生插件,感谢公司安卓团队提供的原生安卓纠偏插件
    1.找到uni-app项目中的manifest.json文件,打开后勾选高德定位地图,填入appkey_android(需要生成keystore文件,并去高德api开放平台申请key,包名为运行->运行到手机或模拟器->制作自定义调试基座->Android包名 此处为设置Android包名)

    2.将nativeplugins文件夹放入到uni-app的根目录下

    3.插件方法说明:startLocation()开始定位 stopLocation()结束定位
    代码示例:
    const gpsLocation = uni.requireNativePlugin(‘Hdsx-GpsLocation’);//获取插件
    //开始持续定位的方法,经纬度信息通过result持续返回,格式为(纬度,经度)
    startLocation(){
    gpsLocation.startLocation(result => {
    console.log(“123”,result)
    });
    },
    //停止定位的方法
    stopLocation(){
    gpsLocation.stopLocation();

    }
    

    备注:使用android原生插件需要制作自定义调试基座,制作成功后,将运行基座选择为自定义调试基座,并将手机上原先安装的工程删除掉,再运行才能生效
    IOS暂无解决方向

    九:Android 和 ios 打包

    1.离线和在线云打包
    离线打包方法 弊端:离线打包不支持unipush推送功能,官网有明确说明,所以可以app有推送需求的可以放弃离线打包了;
    云打包:android云打包使用公用证书即可满足项目需求,ios云打包则需要苹果开发者账号申请各种证书,申请指南

    在这里插入图片描述在这里插入图片描述

    十:uniapp封装的picker标签组件默认不选中数据的第一项

    picker接收的数据是数组形式的,考虑到用户操作picker时不选择,传参的时候需要根据情况处理默认传数组的第0项

    十一:网络请求

    使用uniapp在app端不支持axios,这也是写完请求测试后发现在移动端运行都无法请求,在浏览器可以正常请求到,查了好久网上资料也没有具体说明,最终还是在uniapp官方社区群里问了官网技术人员才解决,更换为官网的uni.request请求网络资源的API即可,但是事情也并不顺利,在项目里习惯把所有的请求写在同一个文件里,需要再封装一遍请求方法,然后直接在.vue文件里去调用这个请求即可,然而问题出在post方式,数组形式的参数,在浏览器调试的时候,发现数组格式的参数都被转成了对象,导致传参错误,所以最后还是老老实实用框架封装的uni.request

    在这里插入图片描述在这里插入图片描述

    十二:IOS系统的APP版本更新处理

    在此项目里实现的是手动更新,当用户检查版本更新的时候,安卓平台的可以直接下载链接,但是iOS平台的ipa无法安装,此时需要跳转到apps-tore,提示用户自动点击升级更新,跳转到apps-tore的方法为打开应用的apps-tore地址,示例如下:
    在这里插入图片描述
    那么如何获取你的app在appstore的链接地址?首先你的APP在appstore里应是审核通过的状态,便可以在ituns里搜索你的app名称,可以直接复制应用链接,那么就可以在代码里处理跳转到appstore里去更新版本了,第二种方法是也可以在苹果开发者账号里的app-connect里查找到,方法参考

    IOS上架审核注意事项:
    1:需添加用户隐私协议说明
    2:要有注册账户的界面显示(可以不接接口,为了审核)
    3:访问系统权限时需具体说明什么功能使用什么权限,参考IOS上架审核关于用户权限问题

    android:使用h5的plus.runtime.version获取的是打包后的manifest里设置的版本

    十三:cover-view标签使用注意事项

    1. 何时使用?
      当使用map,video,组件时,如果想在这些原生组件上覆盖文本视图等,可以使用这些标签,也可以使用组件自带的marker、controls等属性,App端还可以使用plus.nativeObj.view 或 subNVue 绘制原生内容,可参考;但app端不支持嵌套其它组件,包括再次嵌套cover-view,嵌套了也不生效
      在这里插入图片描述

    十四:条件编译

    条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台,比如混合开发中想把指定的代码块只在app平台编译,那么就可以使用条件编译,注意正确注释;但是不适用于app平台的手机系统(android / ios)区分,如果要识别系统,需要调用uni.getSystemInfo来获取平台系统信息在这里插入图片描述

    十五:在uniapp应用内如何调用第三方应用,也可反之在别的应用内调用uniapp的应用,比如:在微博app中如何打开淘宝,京东等应用,(前提是要打开的应用在手机上是已安装的,如没有安装可通过plus.runtime.isApplicationExist()判断是否安装)

    参考网址https://ask.dcloud.net.cn/article/35621

    1:调用第三方程序打开指定的 URL:
    url组成:scheme机制,比如手机淘宝,其安装后会在手机os中会注册一个scheme协议,taobao://。
    这种协议还支持参数,比如taobao://s.taobao.com/search?q=uni-app启动淘宝并打开搜索页面搜索uni- app;scheme可以根据第三方应用打包信息里面查看到,在我的项目里第三方应用开发者直接提供即可
    在这里插入图片描述
    2:调用第三方程序
    参数appInf是个JSON对象,对象属性常用的有:
    ① pname:包名;
    ② action:程序操作的行为,Android平台上与系统的action值一致,iOS平台为要调用程序的URLScheme格式字符串),代码示例在第二张图片
    在这里插入图片描述
    在这里插入图片描述
    3:Android和ios平台设置UrlSchemes,实现被第三方应用调用(由于项目中没有涉及到此需求,所以没有深入探索)
    anroid:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/409
    ios:https://ask.dcloud.net.cn/article/64

    4:以下是常见的对接第三方应用所需要的包名和scheme协议:在这里插入图片描述

    十六:自动登录处理方法(算是一个小技巧吧)

    **起因:**需求要实现自动登录,本来想着是挺简单,在全局里边写(这个想法最开始已经固定了,导致后来转钻了好长时间的牛角尖)但是问题出现了,全局app.vue里不支持页面跳转,又尝试在login页面处理,而uniapp跳转配置都是在一个pages.json文件里的pages数组里定义的,app的启动页默认为数组的第一项,最开始配置的第一项是login登录页的路径,所以app启动时默认是最先进入到登录页,在登录页里处理自动登录的代码写完后测试,果不其然问题出现了,当app启动时虽然会自动登录并跳转到首页,但是会出现一个页面跳转的效果,实际上是不需要出现这个页面跳转的过程的,启动后直接就跳到首页并携带登录人的信息
    在这里插入图片描述
    **经过:**寻思优化优化吧,第一次尝试判断的方法动态修改pages.json里的跳转路径,但是行不通,没法操控;废话不多说,多亏这位大神( ls_bottom)指点,给app添加一个专门放启动页的文件,处理自动登录的逻辑改放在这个启动页文件里,以这个启动页文件的路径作为pages.json里的第一项,这样就完美避开以上的bug了;

    **结果:**不仅解决了上述问题,还总结了启动页的两种方式实现:一是在manifest.json里配置,二是以.vue文件的形式

    十七: uniapp在手机上运行的时候依赖微信开发者工具

    在这里插入图片描述

    十八:适配rpx

    在这里插入图片描述
    在hbuilder里配置:工具-----设置
    在这里插入图片描述

    十九

    展开全文
  • Android开发笔记(成长轨迹)

    万次阅读 2014-07-17 18:38:28
    1.控制台输出:called unimplemented OpenGL ES API 调用了未实现的OpenGL ES API函数,一般由于导入的第三方库如地图库,里面有用到OpenGL,但是模拟器的硬件默认是没有这个的,所以需要我们编辑模拟器Emulation ...


    1.控制台输出:called unimplemented OpenGL ES API

    调用了未实现的OpenGL ES API函数,一般由于导入的第三方库如地图库,里面有用到OpenGL,但是模拟器的硬件默认是没有这个的,所以需要我们编辑模拟器Emulation Options选项勾选 Use Host GPU 然后重启模拟器再尝试,如果还是这个错误,那么我们只好用真机测试了。


    2.控制台输出:


    这个错误是由于真机里已经存在一个相同签名的应用程序,最简单是真机先卸载掉,然后再run。


    3.高德地图android版本,导入地图库,项目打开后报错:

    06-05 09:10:46.718: W/dalvikvm(932): Unable to resolve superclass of Lcom/amapv2/cn/apis/BasicMapActivity; (29)
    06-05 09:10:46.718: W/dalvikvm(932): Link of class 'Lcom/amapv2/cn/apis/BasicMapActivity;' failed

    06-05 09:10:46.888: E/AndroidRuntime(932): FATAL EXCEPTION: main
    06-05 09:10:46.888: E/AndroidRuntime(932): java.lang.ExceptionInInitializerError
    06-05 09:10:46.888: E/AndroidRuntime(932):         at java.lang.Class.newInstanceImpl(Native Method)
    06-05 09:10:46.888: E/AndroidRuntime(932):         at java.lang.Class.newInstance(Class.java:1319)
    06-05 09:10:46.888: E/AndroidRuntime(932):         at android.app.Instrumentation.newActivity(Instrumentation.java:1054)


    这个错误是由于你的android开发环境adt升级到最新版本导致的错误,属于你Android开发环境问题,选中你的项目,右击选择“Properties”---------》“Java Build  Path”--------》“Order  and  Export” ,把“Android  Private Libraries”选项打上勾,再次编译就可以了。


    4.android横竖屏锁定:

    xml文件中设置:
      要实现这个目的,只需要在AndroidManifest.xml里声明Activity的时候加上一个属性:android:screenOrientation,属性取值landscape为固定横屏、portrait为固定纵屏幕。
      代码:
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE););//强制为横屏
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
      ============延伸========
      屏幕会自动切换时,默认状态的应用程序,会重新调用onCreate,相当于重新启动了一次应用程序。同时,layout可能因为横屏带来不能合理适配的问题。为了解决旋屏和键盘切换引起的程序重启问题,还需要增加一个属性:android:configChanges。这个属性可以理解为一个监听器,它将拦截旋屏和键盘切换事件,阻止程序重启而变为回调onConfigurationChanged方法。这里常用的属性取值为:keyboardHidden|orientation。


    Socket TCP/UDP通信原理http://wenku.baidu.com/view/47437d4dcf84b9d528ea7a67.html



    5,android 谷歌地图开发时,控制台输出:



    也就是调试时真机运行后地图显示空白。造成这种现状的原因是由于 google api key配置错误。

    Api key分为两种情况

    一种是使用debug keystore生成的api key

    一种是使用release keystore生成的api key

    不同的api key使用不同的sha1字符生成 ,所以如果是调试,如果使用android自带的debug keystore,一定要是当时生成debug api key的那个 keystone。如果是release,自己的keystore来签名,APP配置文件就用 release下生成的api key。不能混用。否则显示不了地图。

    解决办法:

    1,把debug keystone替换成生成 api key 的那个:

    ,

    2,APP配置文件里要启用debug 的 key:



    6,Android Your content must have a ListView whose id attribute is 'android.R.id.list'错误

    错误提示:Your content must have a ListView whose id attribute is 'android.R.id.list'

    对于以上错误,其实可能是因为我们要实现对ListView中setOnItemClick的事件监听而去继承了LiseActivity,但是却没有ListView的标签,网上有说过只要在布局文件中添加如下代码即可:

    <ListView   
    android:id="@android:id/list" 或android:id="@id/android:list"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content">  
    </ListView>  

    7,view的onFinishInflate()何时调用的?

    比如:自定义一个view叫myView ,路径是,com.test.view.MyView,此view是继承LinearLayout,定义的布局文件是my_view.xml
    里面内容是:
    <com.test.view.MyView>
            <xxxx />
    </com.test.view.MyView>

    当在使用的时候,可以这样使用
    MyView mv = (MyView)View.inflate (context,R.layout.my_view,null);
    当加载完成xml后,就会执行那个方法。

    8,onInterceptTouchEvent与onTouchEvent 执行顺序

    ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.


    ViewGroup里的onTouchEvent默认值是false。


    View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件

    http://blog.csdn.net/android_tutor/article/details/7193090


    9,Jar mismatch! Fix your dependencies


    这个问题是我们添加了多个开源应用例如ABS 或者 PageIndicator 由于他们都包含 support V4.jar, 或者你的工程目录里 libs 中包含这个包,所以冲突发生了,他们各自的签名SHA 不一致,解决方案:

    去掉某一个libs里面的supportv4.jar,直接在引用  external jar using build path menu > add external jar,在目录外选一个(supportV4.jar)即可。


    10,明明卸载掉了豌豆荚,可是.apk文件还是显示 wandoujia.file,如何去除?

    开始=运行=输入CMD回车 输入assoc .apk=null (记得assoc后面有个空格和点) 回车即可。



    11,gen already exists but is not a source folder. Convert to a source folder or rename it.



    解决办法:



       1. Right click on the project and go to "Properties" //鼠标右键点击项目,然后选中Properties
       2. Select "Java Build Path" on the left //选择java Build Path
       3. Open "Source" tab // 打开源文件的tab栏
       4. Click "Add Folder..." //点击添加文件夹
       5. Check "gen" folder and click Ok and Ok again //选中gen目录 然后点确定  应该就可以了【保证source下是gen和src,缺少哪个就添加哪个,缺一不可多余的全部删除】

       6. Again right click on the project and in the "Andriod Tools" click on "Fix Project Properties"  //右键点击项目 选择     Andriod Tools 点击 Fix Project Properties

    按照以上做法,虽然library项目不报错了,可是在其它的项目中引用不到library的类,并且library项目本身都无法引用到,如下:




    解决办法:

    右键项目,build path ----->config build path 在SourceTab栏,addFolder:这一回添加src


    在看看项目组织:


    没问题了吧。


    12,获取当前设备屏幕宽度和高度

    		Display display = getWindowManager().getDefaultDisplay();
    		display.getWidth();
    <span style="white-space:pre">		</span>display.getHeight();

    13,项目工程下的lint.xml什么作用?


    代码性能改进工具,Lint会自动扫描现有工程的Java和xml文件,给出性能优化改进建议,最终将会在Android的工程目录下生成lint.xml文件。简单点说就是检查项目里不推荐的代码文件。


    14,无论真机还是模拟器运行项目,总是闪退,后台报错Class找不到:



    解决:找半天,clean好多次,都解决不了,一开始以为少了相关的库文件或路径不对,后来才发现,只要把R文件里的所有包下的文件全部remove掉,让系统自动重新生成,就可以拉。



    15,ClassNotFoundException: Didn't find class "org.osmdroid.views.MapView" on path: /data/app/net.yu-2.apk


    这个错误是指apk打包时发现:org.osmdroid.views.MapView找不到,但是我们在代码里,引用此路径,就能找到MapView,后来终于想到:

    这个jar包在Android private Libraries里

    build config里应该勾选这个,否则打包时不会添加android Private Libraries里的库



    16,基于XMPP的android连接openfile服务时出错:SASL authentication DIGEST-MD5 failed 




    出现这个问题是由于客户端连接openfile时SASL验证出错,网上找了些相关资料,说是关闭相关鉴权验证就可以了:

    config.setTLSEnabled(false);
    config.setCompressionEnabled(false);
    config.setSelfSignedCertificateEnabled(false);
    config.setSASLAuthenticationEnabled(false);
    config.setVerifyChainEnabled(false);
    可是设置后,还会出现这些错误,终于找到原因,是因为连接服务器时,username和password出错了,看log日志发现我的password传递的为null,所以造成了SASL验证出错。确保你的username和password都有正确的值(和服务器的key对应)就可以了。


    参考文章:

    http://blog.sina.com.cn/s/blog_7e3fa7ec0101894b.html 基于XMPP协议的Android IM研究 

    http://blog.csdn.net/onelight1997/article/details/6301289 gloox 链接openfire服务器问题解决办法

    http://www.oschina.net/question/872914_80498



    17,使用HttpClient时:Target host must not be null, or set in parameters

    出现这个问题,原因是url,连接地址不完整, 必须加上"http://"

    HttpPost post = new HttpPost("http://gps.google.com/geo");


    18,真机调试时错误:INSTALL_FAILED_INSUFFICIENT_STORAGE

    出现这个问题,原因是设备(真机或模拟器)的内容空间不足,APP无法安装,如过用的手机,删除一些没用的软件腾出一些空间来,如用的是模拟器,设置device的内存更大一些。


    19,如何把工程项目下的文件归档?(use as Source Folder)


    (我们有时候看项目下会有上图中的文件夹打开后都是一层包一层(树状)的并不像com.ka.tradk这样,原因在于当前的包不是Source Folder)

    添加完后感觉特别混乱,还是有错误,就看本文第11个截图的解决办法,右键点击工程,选择 "Properties",选择左边的 "Java Build Path",打开 "Source" 标签面板,点击 "Add Folder...",删除没用的,勾选 "gen和src" 文件夹,点击OK,点击YES,再点击OK。


    20,在java中,如何四舍五入保留小数点x位?

    方法一:

    			float temp = 0.6922224f;
    			BigDecimal bd = new BigDecimal(temp);
    			bd =bd.round(new MathContext(2));
    结果:

    System.out.println("bd:"+bd);               bd =  0.69 

    显然MathContext中的参数就是保留几位小数点,这种方法返回的是对应类型(float)的结果,如上bd

    方法二:

    			String parten = "#.#";
    			DecimalFormat decimal = new DecimalFormat(parten);
    			String str= decimal.format(temp);
    			interval = Float.valueOf(str);

    结果:

    System.out.println(interval);    interval = 0.7

    显然这种方法关键的就是parten参数, #.##就是保留两位小数点并且四舍五入,这种方法返回的是字符串类型。


    21,使用eclipse打包时:Export aborted because fatal lint errors were found


    解决办法:

    1,点中项目右键  Properties

    2,左边Android列表打开 Android Lint Preference,如下图:


    3,在上图右上角,点击文字超链接,Configure workspace settings,如下图:


    4,将"Run full error check when exporting app and abort if fatal errors are found "前的勾去掉,点击Apply再点击OK,全部保存。

    5,再次选中项目,鼠标右键,AndroidTools-> Clean Lint Markers。稍等片刻,等待APP清除并重新生成Lint.xml文件。

    这个时候再打包,就不会再有错误了。


    22,listview如何自定义或不显示分割线?

    1,ListView中每个Item项之间都有分割线,设置android:footerDividersEnabled表示是否显示分割线,此属性默认为true。

    <ListView
    	android:id="@+id/local_groups_list"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:footerDividersEnabled="false" />
    或是在代码中mListView.setFooterDividersEnabled(false);

    2,改变ListView的分割线颜色和宽度,需要在布局中定义android:divider和android:dividerHeight属性。

    <ListView
    	android:id="@+id/local_groups_list"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:divider="@color/divider_color"
    	android:dividerHeight="1px" />
    setDivider方法就可以设置自己想要的分割线样式,可以是color也可以是Drawable

    3,也可以设置listview不显示分割线,然后给每一个listview item 的底部添加一个imageview,来充作分割线,这也是一种方法。


    23,android:inputType="numberSigned"和代码EditText中setInputType以及setRawInputType区别

    android中inputType属性在EditText输入值时启动的虚拟键盘的风格有着重要作用。这也大大的方便的操作。有时需要虚拟键盘只为字符或只为数字。所以inputType尤为重要。

        android:inputType="none"
        android:inputType="text"
        android:inputType="textCapCharacters"
        android:inputType="textCapWords"
        android:inputType="textCapSentences"
        android:inputType="textAutoCorrect"
        android:inputType="textAutoComplete"
        android:inputType="textMultiLine"
        android:inputType="textImeMultiLine"
        android:inputType="textNoSuggestions"
        android:inputType="textUri"
        android:inputType="textEmailAddress"
        android:inputType="textEmailSubject"
        android:inputType="textShortMessage"
        android:inputType="textLongMessage"
        android:inputType="textPersonName"
        android:inputType="textPostalAddress"
        android:inputType="textPassword"
        android:inputType="textVisiblePassword"
        android:inputType="textWebEditText"
        android:inputType="textFilter"
        android:inputType="textPhonetic"
    //数值类型
        android:inputType="number"
        android:inputType="numberSigned"
        android:inputType="numberDecimal"
        android:inputType="phone"//拨号键盘
        android:inputType="datetime"
        android:inputType="date"//日期键盘
        android:inputType="time"//时间键盘

    在代码中设置的方法:setInputType和setRawInputType的区别,前者是以TEXT类型的键盘,后者是单独Number类型的键盘:


    fuelcity和fuelhighway都是EditText
    				fuelCity.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL);
    				fuelHighway.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL);

    			        fuelCity.setRawInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_SIGNED);
    				fuelHighway.setRawInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_SIGNED);

    注意,参数必须要有InputType.TYPE_CLASS_NUMBER,否则会显示全键盘。

    24,从SD卡获取一个png,然后转化为Bitmap或是Imageview

    		String path = Environment.getExternalStorageDirectory().toString()
    				+ "/test.png";
    		Bitmap mSharedPic = BitmapFactory.decodeFile(path);
    转化为Imageview

    ImageView iv = (ImageView) findViewById(R.id.image_test); 
    iv.setImageBitmap(<span style="font-family:Helvetica,Tahoma,Arial,sans-serif">mSharedPic </span><span style="font-family:Helvetica,Tahoma,Arial,sans-serif">);</span>

    25 Android string.xml通配符(%$)和转义字符的用法


    StringFormat通配符 

    <string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

    在这个例子中,这个格式化的字符串有2个参数

    属性值举例说明
    %n$ms:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格 
    %n$md:代表输出的是整数,n代表是第几个参数,设置m的值可以在输出之前放置空格,也可以设为0m,在输出之前放置m个0 
    %n$mf:代表输出的是浮点数,n代表是第几个参数,设置m的值可以控制小数位数,如m=2.2时,输出格式为00.00


    在程序中按照下面的方法来根据参数来格式化字符串:

    Resources res = getResources();

    String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

        <string name="info_address">Address: %1$s(%2$s %3$.3f°,%4$s %5$.3f°,Altitude %6$md)</string>
        <string name="info_address_english">Address: %1$s(%2$s %3$.3f°,%4$s %5$.3f°,Altitude %6$.1ft)</string>
        <string name="info_address_a">Approximate address: %1$s(%2$s %3$.3f°,%4$s %5$.3f°,Altitude %6$.1fm)</string>
        <string name="info_address_ab">Approximate address: %1$s(%2$s %3$.3f°,%4$s %5$.3f°,Altitude %6$.1ft)</string>



    XML转义字符 
    以下为XML标志符的数字和字符串转义符 
    "     (&#34; 或 &quot;) 
    '     (&#39; 或 &apos;) 
    &     (&#38; 或 &amp;) 
    lt(<) (&#60; 或 &lt;) 
    gt(>) (&#62; 或 &gt;) 


    比如:在string.xml中定义如下一个字符串, 
    <string name="first">大家好,欢迎来到mryang社区。welcome to here!</string> 
    我想以 
    大家好,欢迎来到eoeandroid社区。 
    welcome to here! 
    两行的形式输出,如何做?加\n,看下面:
     
    <string name="hello">大家好,欢迎来到mryang社区。\nwelcome to here!</string> 

    android中的空格编码 string.xml前后加空格的技巧 
    <string name="space">&#160;&#160;&#160;&#160;我来看空格</string> 
    &#160; 这个就代表着空格
     

    1. 遇到如下错误的时候说明你需要在单引号签名加转义字符(\): 
    Description Resource Path Location Type error: Apostrophe not preceded by \ (in Search' Titles) strings.xml 
    只要将定义的字符串中的单引号('), 修改为(\')即可
     

    2. 变量文本格式(%s)提示: 
    Multiple annotations found at this line: 
    - error: Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" 
    attribute? 
    - error: Unexpected end tag string 

    这是由于新的SDK采用了新版本的aapt(Android项目编译器), 这个版本的aapt编译起来会比老版本更加的严格, 在Android最新的开发文档中描述String的部分,已经说明了如何去设置 %s 等符号, 可以点击去看. 
    简单解决方法就是:把%s之类的变量格式替换成%1$s, %1表示第一个位置的变量, $s表示为字符串类型 
    例如: 
    <string name="welcome_messages">Your First Var is %1$s! You Second Var is %2$d.</string>
     


    26,如何导入第三方library库?

    导入的前提是lib已经被添加到了当前workspace里面,这样的话就可以使用相对路径了。


    方法一:

    直接在project.properties里添加:

    target=android-17
    android.library.reference.1=..\\LibSlidingMenu2


    方法二:

    手动导入:


    导入完成后:


    方法二的和一的区别在于路径引用上,如上图,1,2是方法一来引用的;3,4是方法二引用的。


    27,R cannot be resolved to a variable

    遇到这种情况可以看一下RES里是否有错误,如果有错误,必然导致R无法成功生成,所以先解决所有资源文件的错误。

    1. 检查Android 的SDK是否丢失需要重新下载,检查build path
    2. 确保class没有import Android.R;
    3, 错误class引用的layout的xml文件没有错误
    4. 检查AndroidManifest.xml文件,里边的package,layout配置文件,strings.xml等的字符串全部书写正确
    5. layout的xml文件中引用的strings.xml中的字符串拼写完全正确
    6. 在layout 的xml文件手写添加一个控件,看id能否在R.java中自动生成,如果不能,那很大可能就是这个layout 的xml文件有问题,查看格式是否使用正确,或者包含什么非法字符串,或者调用到了不正确的字符串,等等,可以使用排除法,挨个去掉控件,直到发现error message消失或者id能在R.java中自动生成。
    7. 删掉gen文件夹,使R.java重新自动生成一次,如果不能生成,继续检查layout的xml文件是否有如上不易发觉的问题
    8. Clean project ,重新build,或者重新import project。
    9. 重启eclipse。

    28,当import一个新的android项目时,项目名称上出现一个红色的感叹号,程序不能运行

    右键项目---BuildPath---Configure Build Path, 切换libraries标签页,你应该会看到Android Dependencies里红色的X号,也就是说某一个jar包现在不可用了,查看一下是否jar包路径有变化,修复了就没问题了。

    还有在我们引用第三方jar包或是自己写的support支持库时,一定记得要在project.properties里添加: android.library=true  否则,其它项目引用此库时,是无法生产库名.jar包名的。

    以下为引用:

            你用myeclipse新建 web工程, 在工程目录下会生成一个 .classpath 配置文件, 里面是你工程里面引用的jar的配置。这个.classpath 对你的web工程没有什么影响 
    其实是给 myeclipse 识别的。 你说的这种情况是因为 .classpath 文件里面配置引用了某个jar,但是实际上你的 lib 里面并没有这个jar 所以才会有红色的提示。 
            你不用拿.classpath文件和你的jar一个个去找, 你现在打开MyEclipse 右键单击你的web工程,找到 Build Path > Configure Build Paht... > 然后上面有几个选项卡找到 Libraries。  这里看到的就是你工程里面引用的 所有的 jar , 看看是不是在某个jar图标上有个很小的黄色的感叹号? 
             如果有的话就没错了, 先选中这个jar, 点击右边的 Remove  > 点击OK 等待几秒, 现在web工程上面的红色XX是不是没有了,哈哈。 解释一下: 黄色的感叹号的jar,表示.classpath配置文件引用了jar, 但是实际上lib里面没有这个jar。


    29,如何实现屏幕截图(Mapview)

    直接附上实现代码,截取当前屏幕,并保存到手机内。

    	public Bitmap takeScreenShot(){
    		View view = this.getWindow().getDecorView();
    		view.setDrawingCacheEnabled(true);
    		view.buildDrawingCache();
    		Bitmap bt = view.getDrawingCache();
    		
    		Rect frame = new Rect();
    		view.getWindowVisibleDisplayFrame(frame);
    		int statusHeight = frame.top;
    		
    		int width = this.getWindowManager().getDefaultDisplay().getWidth();
    		int height = this.getWindowManager().getDefaultDisplay().getHeight();
    		
    		Bitmap create = Bitmap.createBitmap(bt, 0,statusHeight,width,height-statusHeight);
    		mMapView.destroyDrawingCache();
    		
    		return create;
    	}
    	
    	public void saveScreenShot(Bitmap bitmap,String filepath){
    		
    		FileOutputStream fos = null;
    		
    		try {
    			fos = new FileOutputStream(filepath);
    			
    			if (null!=fos) {
    				bitmap.compress(CompressFormat.PNG, 90, fos);
    				fos.flush();
    				fos.close();
    				System.out.println("succccesss");
    			}
    			
    			
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		
    	}

    实现:

    			Bitmap bitmap = takeScreenShot();
    			saveScreenShot(bitmap, Constants.defaultScreenPath);


    30,android-support-v4.jar混乱冲突


    这是由于不同的library同时引用了android-support-v4.jar,但是他们不是同一个文件,SHA-1不相同,系统只允许libraries must be the same,所以我们删除那个不相同的jar包,把其余的使用同一个的jar拷贝到library里就可以了。


    31,eclipse中git插件的cannot open git-upload-pack问题


    我们在eclipse上使用插件egit向代码服务器push或pull代码时,有时候会发现出现cannot open git-upload-pack这个问题。一般引起这个问题的原因有两个:

    一、网络问题,确定你可以访问自己所要操作的代码仓库地址!【这是最关键的,我就是折腾半天发现公司关闭了地址的外网访问】

    二、eclipse中git插件的配置问题。

    打开eclipse中的windows-->Preferences-->Team-->Git-->Configuration-->User Settings.然后点Add Entry新建一个键值对,输入http.sslVerify=false。如图所示:


    32,Fragment出现异常:java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

    在使用Fragment保存参数的时候,可能是因为需要保存的参数比较大或者比较多,这种情况下页会引起异常。比如代码

    		Bundle b = new Bundle();
    		b.putParcelable("bitmap", bitmap2);
    		imageRecognitionFragment.setArguments(b);
    设置好参数,并且添加hide(),add(),方法之后,需要commit(),来实现两个Fragment跳转的时候,这种情形下参数需要进行系统保存,但是这个时候你已经实现了跳转,系统参数却没有保存。此时就会报这这个异常

    分析原因:你并不需要系统保存的参数,只要你自己设置的参数能够传递过去,在另外一个Fragment里能够顺利接受就行了,现在android里提供了另外一种形式的提交方式commitAllowingStateLoss(),从名字上就能看出,这种提交是允许状态值丢失的。到此问题得到完美解决,值的传递是你自己控制的。
    这里也说一下另外一个问题,bitmap 也可以通过Bundle传递的,使用putParacelable就可以了。


    33,conversion to dalvik format failed with error 1


    在我们Android Tools--Export Signed Application Package 进行签名打包时会遇到这个问题,不是特别严重的问题,最简单的是刷新一下自己的工程,clean一下、再次打包,如果还不行就重新打开eclipse试试。

    project.properties里Target改变一个其他的版本,再变回来保存一下(相当于刷新的操作)这样也能起到清理的作用。


    34,在版本更新时,新版本数据库增加了字段,安装直接替换apk运行后报错(数据库字段找不到),除非卸载旧版本再安装新的


    主要是因为新增加了字段,在当前版本里查找字段时出错了,所以要切记一个问题,当更新版本时添加或删除了字段,数据库version一定要更换,也就是说新版本运行时要让系统知道数据库有更新,要remove db 然后再创建db,如下所示:


    35,android:layout_weight用法

    layout_weight 用于给一个线性布局中的诸多视图的重要度赋值。默认为零,意思是需要显示 多大的视图就占据多大的屏幕空 间。若赋一个高于零的值,则将父视 图中的可用空间分割,分割大小具体取决于每一个视图的layout_weight 值以及该值在当前屏幕布局的整体 layout_weight值和在其它视图屏幕布局的layout_weight值中所占的比率而定。 

    举个例子:比如说我们在 水平方向上有一个文本标签和两个文本编辑元素。 该文本标签并无指定layout_weight值,所以它将占据需要提供的最少空间。  如果两个文本编辑元素每一个的layout_weight值都设置为1,则两者平分在父视图布局剩余的宽度(因为我们声明这两者的重要度相等)。如果两个文本编辑元素其中第一个的layout_weight值设置为1,而第二个的设置为2,则剩余空间的三分之二分给第一个,三分之一分给第二个(数值越小,重要度越高)。 


    36,xml文件中的转义字符

     HTML中<, >,&等有特别含义,(前两个字符用于链接签,&用于转义),不能直接使用。使用这三个字符时,应使用他们的转义序列,如下所示:

    &amp; 或 &

    &

    &lt; 或 <

    <

    小于号

    &gt; 或 >

    >

    大于号

    &quot;

    "

    双引号

     

    &nbsp;

     

     

    空格

    &copy;

    ©

    版权符

    &reg

    ®

    注册符

      前者为字符转义序列,后者为数字转义序列。数字转为字符对应的ASCII码值。例如 & lt; font &gt;显示为,<font>,若直接写为则被认为是个链接签。

      需要说明的是:

      a. 转义序列各字符间不能有空格; 
             b. 转义序列必须以";"结束; 
         c. 独立的&不被认为是转义开始; 
            d.区分大小写。

      另一个需要转义的字符是引号,他的转义序列为"" "或"""

      HTML使用的字符集是ISO &859 Larin-1字符集,该字符集中有许多标准键盘上无法输入的字符。对这些特别字符只能使用转义序列。
      XML转义字符 
           不合法的XML字符必须被替换为相应的实体。

      如果在XML文件中使用类似"<" 的字符, 那么解析器将会出现错误,因为解析器会认为这是个新元素的开始。所以不应该像下面那样书写代码:

    <message>if salary < 1000 then</message>

      为了避免出现这种情况,必须将字符"<" 转换成实体,像下面这样:

    <message>if salary &lt; 1000 then</message>

      下面是五个在XML文件中预定义好的实体:

    &lt;

    <

    小于号

    &gt;

    >

    大于号

    &amp;

    &

    &apos;

    单引号

    &quot;

    "

    双引号

      实体必须以符号"&"开头,以符号";"结尾。

      注意: 只有"<" 字符和"&"字符对于XML来说是严格禁止使用的。剩下的都是合法的,为了减少出错,使用实体是个好习惯。


    37,如何读取当前项目版本信息(version name和version code)?

    			PackageManager packageManager = getPackageManager();
    			PackageInfo packInfo = null;
    			try {
    				packInfo = packageManager.getPackageInfo(getPackageName(), 0);
    			} catch (NameNotFoundException e) {
    				e.printStackTrace();
    			}
    <span style="white-space:pre">			</span>int versionName = packInfo.versionName;
    			int versionCode = packInfo.versionCode;

    38,如何判断当前是否有网络以及使用的网络环境(2G、3G或WIFI)?

    	/**
    	 * 判断当前是否有网络 有 返回 true 无 返回 false
    	 * 
    	 * @param context
    	 * @return
    	 */
    	public static boolean isNetWorkAble(Context context) {
    
    		if (context == null) {
    			throw new NullPointerException("context can`t be null!");
    		}
    		ConnectivityManager connManager = (ConnectivityManager) context
    				.getSystemService(Context.CONNECTIVITY_SERVICE);
    		if (null != connManager) {
    			NetworkInfo[] networkinfo = connManager.getAllNetworkInfo();
    			if (null != networkinfo) {
    				for (int i = 0; i < networkinfo.length; i++) {
    					if (networkinfo[i].getState() == NetworkInfo.State.CONNECTED) {
    						return true;
    					}
    				}
    			}
    
    		}
    		return false;
    	}
    判断网络环境:



    39,This tag and its children can be replaced by one <TextView/> and a compound drawable

    当我们在xml里布局的时候,有时会遇到这样的一段黄色警告,简而言之就是说,我们可以优化一些(TextView可以直接添加图片)

        <LinearLayout 
            android:orientation="horizontal"
            android:layout_centerInParent="true"
    	    android:layout_height="wrap_content"
    	    android:layout_width="wrap_content">
    	    <ImageView 
    	        android:id="@+id/item_icon"
    	        android:layout_width="wrap_content"
    	        android:layout_height="wrap_content"/>
    		<TextView
    		    android:id="@+id/item_text"
    		    android:layout_height="wrap_content"
    		    android:layout_width="wrap_content"
    		    android:text="@string/app_name"/>
    	</LinearLayout>
    看这个xml,发现原来可以直接给TextView加图片.. ,通过 setCompoundDrawable 方法, 或者直接在xml中使用android:drawableLeft.、android:drawableRight等属性指定!这样的话就省去了一个ImageView组件,岂不是更有效率一些?

    40,SQlite 简单 事物处理

    最近在做应用程序的集团版本,初始化时需要批量的向sqlite中插入大量数据,单独的使用for+Insert方法导致应用响应缓慢,因为 sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。应用有的账号有500+记录,需要500多次循环,insert。


    解决方法:
    添加事务处理,把500+条插入作为一个事务

    我们使用SQLite的事务进行控制:
            db.beginTransaction();  //手动设置开始事务
            try{
                //批量处理操作
                for(Collection c:colls){
                    insert(db, c);
                }
                db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交
               }catch(Exception e){
                   MyLog.printStackTraceString(e);
               }finally{
                   db.endTransaction(); //处理完成
               }

    1.使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。
    2.下面两条SQL语句在同一个事务中执行:

    		try {
    			database.beginTransaction();//开始事务
    			for (Tracker tracker : lists) {
    				Tracker t = findByTid(tracker.getTid()); //读取一条记录
    				if (t != null) {
    					tracker.setId(t.getId());//设置相应的属性
    					tracker.setSelected(t.isSelected());
    					tracker.setDeleted(t.isDeleted());
    				}
    				dao.createOrUpdate(tracker);//循环插入记录
    			}
    			database.setTransactionSuccessful();//保存提交
    			database.endTransaction();//结束事务
    
    		} catch (Exception e) {
    		}


    41,使用googleMap如何获取两点(经纬度之间的距离)

    方法一:

    	/**
    	 * 通过Location类获取两点间距离 单位:m
    	 * 
    	 * @param slat起点经度
    	 * @param slon起点纬度
    	 * @param elat终点经度
    	 * @param elon终点纬度
    	 * @return
    	 */
    	public static int getDistance(double slat, double slon, double elat,
    			double elon) {
    		float[] result = new float[1];
    		Location.distanceBetween(slat, slon, elat, elon, result);
    		return (int) result[0];
    	}

    在没有类似android的Location的distanceBetween方法开采用如下代码获取:

    double distance(double lat1, double lon1, double lat2, double lon2) {   
            double theta = lon1 - lon2;   
            double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))   
                        + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))   
                        * Math.cos(deg2rad(theta));   
            dist = Math.acos(dist);   
            dist = rad2deg(dist);   
            double miles = dist * 60 * 1.1515;   
            return miles;   
        }   
        //将角度转换为弧度   
        static double deg2rad(double degree) {   
            return degree / 180 * Math.PI;   
        }   
        //将弧度转换为角度   
        static double rad2deg(double radian) {   
            return radian * 180 / Math.PI;   
        }   


    42,Android 之Gson如何使用

    Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。
    jar和源码下载地址: http://code.google.com/p/google-gson/downloads/list

    实体类:

    public class Student {
    	private int id;
    	private String name;
    	private Date birthDay;
    
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public Date getBirthDay() {
    		return birthDay;
    	}
    
    	public void setBirthDay(Date birthDay) {
    		this.birthDay = birthDay;
    	}
    
    	@Override
    	public String toString() {
    		return "Student [birthDay=" + birthDay + ", id=" + id + ", name="
    				+ name + "]";
    	}
    
    }

    测试类(Gson使用)

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    
    public class GsonTest1 {
    
    	public static void main(String[] args) {
    		Gson gson = new Gson();
    
    		Student student1 = new Student();
    		student1.setId(1);
    		student1.setName("kaka");
    		student1.setBirthDay(new Date());
    
    		// //
    		System.out.println("----------简单对象之间的转化-------------");
    		// 简单的bean转为json
    		String s1 = gson.toJson(student1);
    		System.out.println("简单Bean转化为Json===" + s1);
    
    		// json转为简单Bean
    		Student student = gson.fromJson(s1, Student.class);
    		System.out.println("Json转为简单Bean===" + student);
    	
    		// 简单Bean转化为Json==={"id":1,"name":"kaka","birthDay":"Jun 22, 2012 8:27:52 AM"}
    		// Json转为简单Bean===Student [birthDay=Fri Jun 22 08:27:52 CST 2012, id=1,name=kaka]
    
    		Student student2 = new Student();
    		student2.setId(2);
    		student2.setName("coco");
    		student2.setBirthDay(new Date());
    
    		Student student3 = new Student();
    		student3.setId(3);
    		student3.setName("caca");
    		student3.setBirthDay(new Date());
    
    		List<Student> list = new ArrayList<Student>();
    		list.add(student1);
    		list.add(student2);
    		list.add(student3);
    
    		System.out.println("----------带泛型的List之间的转化-------------");
    		// 带泛型的list转化为json
    		String s2 = gson.toJson(list);
    		System.out.println("带泛型的list转化为json==" + s2);
    
    		// json转为带泛型的list
    		List<Student> retList = gson.fromJson(s2,
    				new TypeToken<List<Student>>() {
    				}.getType());
    		for (Student stu : retList) {
    			System.out.println(stu);
    		}
    
    		// 结果:
    		// 带泛型的list转化为json==[{"id":1,"name":"kaka","birthDay":"Jun 22, 2012 8:28:52 AM"},{"id":2,"name":"coco","birthDay":"Jun 22, 2012 8:28:52 AM"},{"id":3,"name":"柳波","birthDay":"Jun 22, 2012 8:28:52 AM"}]
    		// Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=1, name=kaka]
    		// Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=2, name=coco]
    		// Student [birthDay=Fri Jun 22 08:28:52 CST 2012, id=3, name=caca]
    
    	}
    }
    

    43,Hashmap如何遍历所有的key?

    方法一:

    Map map = new HashMap();
    Iterator iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        //通过Entity获得当前item
        Map.Entry entry = (Map.Entry) iter.next();
        Object key = entry.getKey();
        Object value = entry.getValue();
       
    }

    方法二:

    	HashMap<String, String> maps = new HashMap<String, String>();
    		  Iterator it= maps.keySet().iterator();
    		  while (it.hasNext())
    		  {
    		   Object key=it.next();
    		   System.out.println("key:"+key);
    		   System.out.println("value:"+maps.get(key));
    		  }


    44,Android中Parcelable注意事项

    在实例化对象时,如果实现了Parcelable接口,一定注意两个方法中,get/set属性的顺序不要错了,否则会造成数据不一致。



    45,Fragment异常:not attached to Activity

    传送门:http://blog.csdn.net/walker02/article/details/7995407


    46,Android自带Location和百度DistanceUtil计算两点间距离

    		float[] results = new float[1];
    		double lat = 144122796/3600000.0;
    		double lon = 418747182/3600000.0;
    		double plat =144121792/3600000.0;
    		double plon =418749216/3600000.0;
    		Location.distanceBetween(lat, lon, plat, plon, results);
    		System.out.println("Location:"+results[0]);
    		GeoPoint start = new GeoPoint((int) (144122796 / 3.6), (int) (418747182 / 3.6));
    		GeoPoint end = new GeoPoint((int) (144121792 / 3.6), (int) (418749216 / 3.6));
    		double distance = DistanceUtil.getDistance(start, end);
    		System.out.println("baidu:"+distance);

    输出:

    01-21 14:33:33.060: I/System.out(6935): Location:57.310047
    01-21 14:33:33.060: I/System.out(6935): baidu:56.9168298996976

    可以看出百度和Android自带的算法计算出来的差距不是很大,其实出现不一样的结果,主要是算法过程中,椭球中的地球长半径数据不一致(WGS84和天朝的标准,你懂的),导致差异,具体可看如下算法公式。


    47,国际国内通用两点间(经纬度)的距离算法:

    	static double DEF_PI = 3.14159265359; // PI
    	static double DEF_2PI = 6.28318530712; // 2*PI
    	static double DEF_PI180 = 0.01745329252; // PI/180.0
    	static double DEF_R = 6370693.5; // radius of earth
    
    	/**
    	 * 利用勾股定理计算,适用于两点距离很近的情况
    	 * 
    	 * @param lon1
    	 * @param lat1
    	 * @param lon2
    	 * @param lat2
    	 * @return
    	 */
    	public double GetShortDistance(double lon1, double lat1, double lon2,
    			double lat2) {
    		double ew1, ns1, ew2, ns2;
    		double dx, dy, dew;
    		double distance;
    		// 角度转换为弧度
    		ew1 = lon1 * DEF_PI180;
    		ns1 = lat1 * DEF_PI180;
    		ew2 = lon2 * DEF_PI180;
    		ns2 = lat2 * DEF_PI180;
    		// 经度差
    		dew = ew1 - ew2;
    		// 若跨东经和西经180 度,进行调整
    		if (dew > DEF_PI)
    			dew = DEF_2PI - dew;
    		else if (dew < -DEF_PI)
    			dew = DEF_2PI + dew;
    		dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
    		dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
    		// 勾股定理求斜边长
    		distance = Math.sqrt(dx * dx + dy * dy);
    		return distance;
    	}
    
    	/**
    	 * 按标准的球面大圆劣弧长度计算,适用于距离较远的情况
    	 * 
    	 * @param lon1
    	 * @param lat1
    	 * @param lon2
    	 * @param lat2
    	 * @return
    	 */
    	public double GetLongDistance(double lon1, double lat1, double lon2,
    			double lat2) {
    		double ew1, ns1, ew2, ns2;
    		double distance;
    		// 角度转换为弧度
    		ew1 = lon1 * DEF_PI180;
    		ns1 = lat1 * DEF_PI180;
    		ew2 = lon2 * DEF_PI180;
    		ns2 = lat2 * DEF_PI180;
    		// 求大圆劣弧与球心所夹的角(弧度)
    		distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1)
    				* Math.cos(ns2) * Math.cos(ew1 - ew2);
    		// 调整到[-1..1]范围内,避免溢出
    		if (distance > 1.0)
    			distance = 1.0;
    		else if (distance < -1.0)
    			distance = -1.0;
    		// 求大圆劣弧长度
    		distance = DEF_R * Math.acos(distance);
    		return distance;
    	}
    
    	/** 示例 */
    	double mLat1 = 39.90923; // point1纬度
    	double mLon1 = 116.357428; // point1经度
    	double mLat2 = 39.90923;// point2纬度
    	double mLon2 = 116.397428;// point2经度
    	double distance = GetShortDistance(mLon1, mLat1, mLon2, mLat2);


    48,Unable to execute dex: Java heap space Java heap space

    修改eclipse目录下面额eclipse.ini文件 
    把第一行添加 
    -vm
    C:\Program Files\Java\jdk1.6.0_24\bin\javaw.exe (你jdk的目录)

    修改
    -Xms128m
    -Xmx512m
    修改
    --launcher.XXMaxPermSize
    512m


    49,如何判断后台的service是否在运行?

    	public boolean isServiceRunning() {
    		ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    
    		ArrayList<ActivityManager.RunningServiceInfo> servicelist = (ArrayList<RunningServiceInfo>) manager
    				.getRunningServices(30);
    		if (servicelist.size() <= 0) {
    			return false;
    		}
    		for (int i = 0; i < servicelist.size(); i++) {
    			if (servicelist.get(i).service.getClassName().equals(
    					"com.dbjtech.find.UploadService")) {//我自己的服务
    				return true;
    			}
    
    		}
    
    		return false;
    
    	}

    50,android:process=":remote"有啥用?

    android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。


    51,sdk manager更新失败,显示Download interrupted: read timed out


    解决办法:

    sdk manager左上角选tools,再选options,将下面的force https......勾选上,重启sdk manager再试一下,应该可以成功。

    52,eclipse中shift+ctrl+(Format)偶尔失效

    其实是和别的软件的快捷键产生了冲突,具体可以看看最近安装了什么软件,看一下其热键。

    在"Window"->"Preferences"->"General"->"Keys"中可以看到所有快捷键,看看你所用的快捷键是否被修改了,要是修改了的话点击"Restore Defaults"即可,或是把format的热键改成别的。

    【注意】搜狗输入法是最喜欢使用shift+ctrl+字母或数字作为快捷键的,建议打开输入法设置属性--按键-快捷按键,把相关没用的全部取消了。


    53,eclipse里找不到AVDManager 或Android SDK Manager的图标(已安装ADT插件)

    1,查看当前的ADT是否是最新版本的,不是的话建议升级为最新版-help-install new software ,add https://dl-ssl.google.com/android/eclipse/

    2,ADT没问题的话,打开Window-Customize Perspective,切换到Command Groups Availability 勾选上Android相关的选项,这个标签页就是配置工具栏要显示的功能列表,shortcuts标签页是设置比如NEW或show view时所需要显示的功能。



    54,再按一次退出程序的实现方法

    private long exittime;(全局)
    		if (keyCode == KeyEvent.KEYCODE_BACK) {
    			if ((System.currentTimeMillis() - exittime) > 2000) {
    				Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
    				exittime = System.currentTimeMillis();
    
    			} else {
    				finish();
    			}
    			return true;
    		}

    55,if (null == name)将null写在前面有什么说道?
    在java里面,它们是一样的。但是为什么把name==null写成是null==name,具体点来说,是在C语言里面引申出来的。
    在C语言里面,为了防止少敲一个等号,编程人员仍然能在编译的时候找到错误。因为if(name=null)是在编译的时候,不会出现错误,而if(null=name)是会编译出错。

    故而,null==name,是在C语言的编程习惯引入进来的。当然了,在java里面,if(name=null)是会出现编译错误的,现在就不用担心这个了。但是,良好的编程习惯,还是写成null==name的好。http://bbs.csdn.net/topics/360174215

    56,Only the original thread that created a view hierarchy can touch its views.

    android中相关的view和控件不是线程安全的,我们必须单独做处理。我直接在button的onclick事件里进行了for循环,循环里直接进行了:

    mHandler.removeCallbacks(runnable);

    mHandler.post(runnable);

    所有更新UI相关的操作,如果在子线程里进行,需要使用handler机制,在handler内更新。

    57,Only the original thread that created a view hierarchy can touch its views


    android中相关的view和控件不是线程安全的,我们必须单独做处理。简而言之,在子线程里进行了UI更新的相关操作,所以要使用Handler机制。


    58,手机号正则表达式"^1[3|4|5|8]\\d{9}$"

    ^ 首字母( 表示匹配一行的开始,既这个验证从^之后开始,第一位数就是1 )

     1  必须是1
    [3-8] 第二个数字为3-8之间的(如果想匹配移动手机号,便可以从这里修改[3|4|5|8])
    \\d表示数字(+\\d表示正整数)
    {9}表示9个,就是9个数字(后面的9位每位都是从0-9之间的数字)
    $ 结尾(匹配结束)

    59,java.lang.IllegalStateException: Content has been consumed
    这个问题是在使用HttpClient时遇到的,主要原因是多次调用了:
     reply = EntityUtils.toString(response.getEntity()); 
    httpEntity.getContent()只能读取一次,多次读取的话就会出现这个Exception了。

    60,Listview如何选中某一行item?(当前item自动滚动)
    1,即可直接选择到指定的 item 并置顶
    listView.setSelection(index);

    2,尝试获取每个item的高度,然后根据指定的个数,使用:
    listView.scrollTo(0, index * heightPerItem);
     每个 item 高度的计算有很多种方法,最简单的就是看你的布局如何实现的,直接写入数值即可如果是不确定的高度,那就只有等实例化之后才能 getHeigth 也可以获取。
     高度的计算需要待 listView 加载完毕后才获取其实际的高度,否则会得到 0。还有就是用 measure 方法:
     ListAdapter listAdapter = listView.getAdapter();  
        int totalHeight = 0; 
        for (int i = 0; i < listAdapter.getCount(); i++) { 
            View listItem = listAdapter.getView(i, null, listView); 
            listItem.measure(0, 0); 
            totalHeight += listItem.getMeasuredHeight(); 
        } 
        ViewGroup.LayoutParams params = listView.getLayoutParams(); 
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() – 1)); 
        ((MarginLayoutParams)params).setMargins(10, 10, 10, 10);
        listView.setLayoutParams(params); 
    还有子ListView的每个Item必须是LinearLayout,不能是其他的,因为其他的Layout(如RelativeLayout)没有重写onMeasure(),所以会在onMeasure()时抛出异常。
    


    61,使用代码为textview设置drawableLeft

    在xml中设置了 DrawableLeft、但我想在代码中实时改变drawable,有什么方法可以使用代码为textview设置drawableLeft呢? 
    方法一:
    public void  setCompoundDrawables  (Drawable left, Drawable top, Drawable right, Drawable bottom);
    Drawable drawable= getResources().getDrawable(R.drawable.drawable);
    
    drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());<span style="font-family: Tahoma;">//必须要setBounds,否则不会显示.</span>
    tv.setCompoundDrawables(drawable,null,null,null);

    方法二:
    public void setCompoundDrawablesWithIntrinsicBounds (Drawable left,Drawable top, Drawable right, Drawable bottom);

    android:drawableLeft和layout:weight同时使用时如何居中?

    android:drawableLeft设置的图片就是居左,但是注意,如果这个组件设置了layout:weight权重,那么图片无法和文字一起居中,文字属性可以通过android:gravity设置居中,想要android:drawableLeft设置的图片和文字一样居中,只能通过另外的方法来实现,因为drawableLeft的作用就是在组件左侧设置图片,如果你的组件宽度足够大,它照样一定会是在最左侧,否则居中的话,就不能是drawLeft了。


    62,Android强行关闭Activity(结束进程)的几个方法:
    一、结束一个活动Activity
      要主动的结束一个活动Activity,使用finish方法,而且这个方法最后会调用Activity的生命周期函数onDestroy方法,结束当前的Activity,从任务栈中弹出当前的Activity,激活下一个Activity。当然其他的finish系列方法,我们不在这里做详细讨论,有兴趣的同学可以自己查阅一下SDK 的文档。
    二、强制结束当前的进程
      强行结束当前进程有两个方法。
      1、killProcess(int pid)              例子:android.os.Process.killProcess(android.os.Process.myPid());
    这个方法使用是有条件的:
    a、将被杀掉的进程 和 当前进程 处于同一个包或者应用程序中;
    b、将被杀掉的进程 是由当前应用程序所创建的附加进程;
    c、将被杀掉的进程 和 当前进程 共享了普通用户的UID。(这里的普通用户,是相对于Root权限的用户来说的)
      2、System.exit(int code)             例子:System.exit(0);
      该方法只能用于结束当前进程自身,在程序遇到异常,无法正常执行时,可以通过这个方法强制退出。
      需要注意的是,这两个方法,会导致进程非正常退出,就是说,进程退出时不会去执行onPause、onStop和onDestroy方法,那么进程很有可能错过了保存数据的机会。因此,这两个方法最好使用在出现异常的时候!
    三、结束另一个进程
      要通过一个进程去结束另一个进程。在之前的SDK版本中,一直使用方法restartPackage(packageName)方法,但是在Android的开发文档中介绍说,这个函数会导致一些问题( the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc.),所以建议大家使用一个新的方法: 
      void killBackgroundProcesses(String packageName)
      由于这个方法没有返回值,所以我们也不知道我们的目标进程是否真的退出了。但是,我目前只发现了这个可以结束另一个进程的方法。
    四、退出到主屏幕
      这个方法,也是退出当前进程的一个方法。如果我们在进程中创建了很多的Activity,但是又不想关闭时去退出不在任务栈顶的Activity,那么就可以直接使用这个方法了。

    63,通过adb命令获取Android手机的IP地址
     先执行命令"adb shell netcfg" 
    再执行命令 “adb shell ifconfig rmnet0”
    64,通过adb命令安卓apk到devices
    在cmd命令下,输入:
    adb devices  (用于显示当前所有连接的设备)
    adb install e:/test.apk (install后跟目标路径)
    adb shell rm data/app/test.apk  (卸载)
    在有多个设备(模拟器)时,需要制定设备号,adb devices 可以显示当前设备的序列号,在adb指令后加上参数-s<serialNumber> 比如 -s emulator-5554 ,就可以指定adb指令的目标
    65,通过adb shell命令打开指定应用程序
          $ adb shell
          $ am start -n {包(package)名}/{包名}.{活动(activity)名称} 
    adb shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n breakan.test/breakan.test.TestActivity
    或简单点:
    adb shell am start -n breakan.test/breakan.test.TestActivity
    其中"breakan.test/breakan.test.TestActivity"中的"breakan.test"是程序的包名,"TestActivity"是程序Activity类的类名。
    比如:


    66,真机调试eclipse在file explorer中展不开data文件夹

    这个需要真机已经进行root过了,然后在手机上装上R.E 管理器(或类似软件),将/data/data的权限修改为可读可写可执行,然后,就可以在eclipse中展开了。


    67,如何把android textView字体大小固定写死,而不随系统设置字体大小的改变而改变?

    sp是字体的单位,dp一般是宽,高等的单位,但是不同的机器有不同的密度,hdpi,mdpi,ldpi,xhdpi,在这些密度下,以sp、dp为单位,那么最终都会转换成px单位下的值,所以,用px为单位就是固定值。


    68,EditText默认时不弹出软键盘的方法 

    方法一:

    在 AndroidMainfest.xml中选择哪个activity,设置windowSoftInputMode属性为 adjustUnspecified|stateHidden

       < activity android:name=".Main"
          android:label="@string/app_name"
          android:windowSoftInputMode="adjustUnspecified|stateHidden"
          android:configChanges="orientation|keyboardHidden">
      < intent-filter>
      < action android:name="android.intent.action.MAIN" />
      < category android:name="android.intent.category.LAUNCHER" />
      < /intent-filter>
      < /activity>

    方法二:

    让 EditText失去焦点,使用EditText的clearFocus方法

    例如:
            EditText edit=(EditText)findViewById(R.id.edit);
      edit.clearFocus();

    方法三:

    强制隐藏Android输入法窗口

        EditText edit=(EditText)findViewById(R.id.edit);
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(edit.getWindowToken(),0);

    展开全文
  • android 面试题

    千次阅读 2016-09-29 21:32:17
    1.常用的存储方式有哪些? (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持读取...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 SharedPreference:
  • android安卓源码海量项目合集打包-1

    万次阅读 2019-06-11 16:16:24
    下载地址 最后更新共计113个分类5177套源码29.2 GB。 卷 新加卷 的文件夹 PATH 列表 卷序列号为 00000200 5E7A:7F30 F:. ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签的灵活运用.rar ...
  • android+面试题

    千次阅读 2017-10-11 20:18:08
    1.常用的存储方式有哪些?(概率50%) (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 SharedPref
  • 经常听到别人说“世界那么大,我想去看看”。在有机会走出国门之前,还是先把祖国走一圈吧。都知道中国地广人不稀,旅游资源非常丰富,古文化遗址、抗战遗址、山川、河流等等,在选择...
  • 安卓200道面试题

    千次阅读 2017-12-15 09:49:08
    200道面试题 1.常用的存储方式有哪些?(概率50%) (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 S
  • 本文初始研究对象是承载平安在征信行业布局的前海征信,但细挖之后,发现征信业务只是平安集团很小的一块数据应用方向,更多的方向是将数据根据不同场景形成针对性的风险防控、营销画像优化这类产品,帮助自身业务及...
  • Android基础知识总结

    千次阅读 2018-06-11 12:21:34
    ⦁ Android开发环境的搭配1. 启动电脑加速器:A. 重启电脑,按住F12((台式机)),...如果把【Disabled】改为了[Enabled]按键盘上的【Esc】退到:都点[Yes]D.笔记本电脑:重启电脑,按住F10(hp电脑,不同型号的电脑不...
  • 7.13科技新闻2

    千次阅读 2013-07-13 06:28:14
    关于百科产品的五条建议 郭静 发表于 2013-07-12 11:08:04 | 标签: 百科 搜狗 分享到 ...搜狗百科在右侧添加了词条的相关微博内容,加入了相关新闻以及人物关系等内容,其余的内容和360
  • Android面试题

    2017-12-01 15:51:55
    1.常用的存储方式有哪些?(概率50%) (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持读取不...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 Sh
  • 书籍介绍:《移动WEB前端高级开发实践》这本书的内容涵盖了移动Web前端开发中的各个关键技术环节。分别从HTML5、CSS3、JavaScript的ECMAScript5和ECMAScript6版本、移动端常用布局方案、MV*类新时代框架、预编译技术...
  • 200道面试题

    2017-10-23 15:09:01
    1.常用的存储方式有哪些?(概率50%) (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持读取...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 Sh
  • 地图的数据采集处理、服务搭建发布、前端交互构建,要全讲下来其实挺复杂,这里仅仅简单介绍一下,并罗列一些资料,如果有兴趣,可以按图索骥,深入了解。 1.OGC OGC即为Open Geospatial Consortium,开放地理...
  • 200面试题

    2017-10-27 19:02:21
    1.常用的存储方式有哪些?(概率50%) (五种,说出哪五种,五种存储方式什么情况下用。)注意sharepreferes对象支持读取...Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。 Sh
  • 本文转载自:...amp;mid=2650617111&amp;idx=1&amp;sn=3120d94c0fc61eec3bbc1689fb062767&amp;chksm=87b39afbb0c413ed3f182b77ea5ad212612deb9cf25a2e4de3d38957ccf73f54...
1 2 3
收藏数 41
精华内容 16
关键字:

webapi轨迹占用内存 高德地图