自己电脑上的dev环境好久没有更新,更新了最新的genymotion后,adb不能连接到虚拟机,花费了些时间,记录如下:
1.执行adb提示adb server is out of date
,尝试修改genymotion的adb路径为~/Library/Android/sdk
,执行adb kill-server
,adb start-server
后问题依旧
2.求助google,发现需要将adb
update to 1.0.32
from 1.0.31
.
3.直接执行~/Library/Android/sdk/platform-tools/adb version
打印版本为1.0.35,adb version
为1.0.31,看来是两个可执行文件,并且版本不一致
4.$ which adb
找到adb的位置,将~/Library/Android/sdk/platform-tools/adb
覆盖
jitpack
几个project之前都是通过jitpack来打包发布的,今天突然发现通过compile 'com.github.tcking.PhotoHelper:1.2'
不能获取到PhotoHelper发布的文件,gradle 提示找不到文件:
1 | https://jitpack.io/com/github/tcking/PhotoHelper/library/1.2/library-1.2.jar |
经多尝试,发现aar的文件路径为1
https://jitpack.io/com/github/tcking/PhotoHelper/1.2/PhotoHelper-1.2.aar
但实际上https://jitpack.io/com/github/tcking/PhotoHelper 目录下已经没有library目录,
compile ijkplayer with openssl
with openssl
1. Change config/module.sh with module-lite.sh
1 | $ cd config |
2. init openssl
1 | $ cd .. |
3. compile openssl
1 | $ cd android/contrib |
4. init android
1 | $ cd ../.. |
5. compile ffmpeg (x86_64 need yasm: $ brew install yasm)
1 | $ cd android/contrib |
6. compile ijk
1 | $ cd .. |
7. copy so files
1 | cp ijkplayer/ijkplayer-armv5/src/main/libs ijkplayer-java/src/main/jniLibs |
blog whith hexo
虽然写的少,但是看到好的东西就长了草,了解了下hexo,觉得比Jekyll要便捷多了,至少hexo这个单词比Jekyll好拼写,以下是搭建和迁移过程:
搭建
安装nodejs和git (hexo基于nodejs)
1.通过nvm安装nodejs(nvm是node的版本管理,可以安装和切换不同版本的nodejs)
1 | $ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash |
2.通过brew安装git: brew install git
安装hexo
1 | $ npm install -g hexo-cli |
建站
1 | $ mkdir blog |
修改配置说明
编辑_config.yml填写Site和URL部分,theme修改为next
选择模板
1 | $ git clone https://github.com/iissnan/hexo-theme-next themes/next |
编辑_config.yml,theme修改为next
安装hexo server(用于本地浏览)
1 | $ npm install hexo-server --save |
安装部署工具(用于将静态文件push到github等)
1 | $ npm install hexo-deployer-git --save |
编辑_config.yml:1
deploy:
type: git
repo: git@github.com:tcking/tcking.github.io.git
branch: master
message:
迁移(from Jekyll)
1.将原目录_posts中的md文件拷贝到source/_posts目录中
2.编辑_config.yml,new_post_name的值修改为 :year-:month-:day-:title.md
写作流程
创建blog
1
2
3$ cd blog
$ hexo server
$ hexo new "myblog" //then edit the new file浏览localhost:4000
- Press Ctrl+C to stop
$ hexo generate
//生成html$ hexo deploy
//push到github
年中总结&所想
先说问题:
从春节到年中,发布的版本不多,真正更新到用户手上的新功能更少,但是这种状态下的版本发布也不能做到从容应对,需要加班,这暴露我们些问题。
1.自测能力弱
经过自己的测试后,测试team总能再发现些低级的bug,总结下原因,首先测试方法不对,自测现在是盲测,在脑子里没有设计好覆盖变动逻辑的测试场景,测试覆盖不全面。其次是心态不对,就像考试完后不想再检查,急于交卷。目前我们也在改进这块,提升测试环节在开发流程中得重要性,在新版本计划时,在asana中先创建测试任务,记录要测试的场景,在后继的开发过程中不断补充完善,测试任务分配到人;必做三类测试“升级”,“全新”和“登出再登录”;落实好code review。
2.team之间协同低效
对业务的整体流程不清楚,还有只关心自己的一亩三分地的思想造成了这些问题,同一个逻辑范围上的数据因为不同的人负责,接口也被切分开来。wiki不知道怎么用,要查一个api,首先要想想它属于哪个模块,是人脉?还是电商?还是其他,每个team放的地方,格式都不一样,还有没更新的,就像大海捞针。每个人都应要有主人翁精神,这些问题除了做好自己的工作,能做的不多。
再说需要坚持的:
1.坚持做code review
code review是今年春节后作为每次版本发布的一个任务,team的每个人都必须对git上checkout下来的代码review一遍,这样的好处有很多,首先是熟悉了别人的代码和逻辑,更重要的是能提前发现逻辑问题和性能问题,还能重构优化代码,我统计了下除了赶时间写功能赶发布做的比较粗糙,其他时间code review我们都做的比较好,每次review后几乎都能对代码做一些改进。
2.用好工具,多分享
从ADT转向android studio,所有任务上asana,这些工具真得很好用,我们也开了好几次分享小会,提升技能,提升工作效率,更是种快乐。
从局内人看JF:
看到的还是问题,而且还很严重,协同低效的不仅仅是各team,更是个JF内部各系统之间调用问题,各系统之间直接调用,缺乏一个以事件驱动连接各系统的框架。
从局外人看JF:
提一个我认为可以改进的地方。收取10%手续费?平台照样收,但可以换个说法。平台连接得是发包商和开发者,缺少任何一方都不行,但是这两方却有不同的特点,发包方发包是一种“刚性”需求,发包商目标不是发包而是为了解决自己的问题,可能通过其他商业公司,上JF平台等来满足自己的需求,至于谁来接包则是一个选择过程,他总会想办法满足自己的需求,所以类似于“刚性”;开发者接包,是“改善型”需求,开发者只有觉得价钱合适才会去选择接包,不合适宁愿闲着(鉴于实际情况,有能力的接包者基本上没有什么闲得时间),所以愿意接包得比例应该不是很大。另外在从人的心理来分析,接包人接到100块的单,实际收到的是90块,从这样看平台10%的手续费就是从开发者身上扣除,会给开发者造成抵触。何不在需求市场的报价就是接包者净得?就好比之前看到一个故事,一家自助餐厅对严重浪费食物的客人罚款10元,结果有客人抵触,后来改为就餐价格上涨10元,对没有浪费的客人奖励10元,客人们都能接受;很多人买东西只买降价了多少,对原来是多少可能并不在意,这是种普遍心理现象,接包者接到90得包和接到100得包其实感觉是差不太多的,但是从100里面再扣除10快,虽然收入都是90块,但是给人的心理感受是不一样。发包商是公司,开发者是个人,开发者是传统意义上的弱者,保护弱者符合一般认知,所以平台应该采用在线上迎合开发者,线下迎合发包商这样的策略。
让android开发更轻松些
android开发是件体力活,我们都需要花大量的时间去堆砌跟业务无关的代码,例如拍照,获取照片,处理照片大小,各线程之间的交互等,这些问题都有优秀的方案来解决,Giraffe是将这些优秀的东西集合和组织起来,成为一个快速搭建android app的脚手架,让“卓码”将更多的精力放到业务的处理上。
照片来自vectorstock
依赖关系
原则上app/libs下不放置任何jar包,所有的第三方jar统一放到:commonlib中,其他module则在依赖commonlib
配置
约定优于配置,giraffe在启动的时候会去加载
assets/config.properties
中的配置,配置采用PlaceHolderProperties支持placeHolder,例如:images=${app_home}/images
model分隔不同环境的配置
配置项model用于指定当前的配置的环境是什么,例如dev,test或production,其他的配置项通过model前缀来区别不同环境的配置,例如:
dev.openAPIServer=http://dev.myhost.com #表示dev的配置
production.openAPIServer=http://wwww.myhost.com #表示生产的环境配置
而这些配置项可以写在一个文件中,通过修改mode来快速切换配置日志配置
日志参考sl4j的思想,支持参数化,例如:Log.e(“get user detail error:{}”,userId,exception)
日志记录采用Microlog,支持选择输出到logcat或文件,日志记录格式可配置
%P 日志级别 %t 当前线程名称 %d 当前时间 %m 日志消息 %T Throwable对象
基础组件
1.日志
支持参数化(只有在日志打印的时候字符串才进行拼接,性能更好)1
2Log.d("hello {},hello {}","world","giraffe");
Log.e("parameter a={},b={},c={}","a","b","c",exception);2.DAO
DAO采用greenDAO,修改module dao下的DAOGenerator
,再运行DAOGenerator的main方法在模块app下生产对应的POJO和DAO文件- 获取DAO对象,
DBManager.getInstance(“tc”).getDaoSession().getXDAO()
, DBManager根据数据库名称(一般以用户来区别)来创建或打开数据库并获取DAO对象 - 数据库结构和数据的升级,需要编写实现逻辑并注册到升级管理器,DBManager在打开数据库的时候将根据版本号一次执行升级:
- 编写实现了DBUpgrader接口的实现类,完成数据库的升级逻辑
- 修改
DBUpgradeManager.registerUpgraders
方法,将第一步的实现类注册到升级管理器
- 获取DAO对象,
3.DeviceManager 获取设备相关的信息,例如网络状态,类型,IMEI,屏幕像素,分辨率,px和dp的相互转换等。
警惕教条主义
产品设计在遇到投资人或者老板等这些重量级用户的需求时,一般都会不遗余力的去满足,更有可能会把重量级用户的观点当成指导思想,结果是当时大家都很happy,投资人高兴了,下面的人跟着高兴。但是这样真的是对的吗?
这些重量级用户的阅历,经验比一般的用户都丰富,也更具指导意义,但是产品设计仍然需要分析,挖掘其真正的需求,首先任何用户在提出意见的时候可能只局限在他当时思考的范围内,没有把整个系统结合起来考虑。用户说要往东,他真正想做的可能是去美国,所以我们需要加工分析这些原始的需求,不要以屁股决定脑袋这类思想为教条,虽然这是一种现实和无奈,但我们心里需有明镜。
错用synchronized引起的ANR
合并代码后,app在登录后的一段时间偶尔会出现UI卡顿,多次尝试后发现在网络不佳的情况下更容易出现。
打开app的StrictMode开关,记录网络,磁盘的读写情况,通过日志并没有发现问题所在,在主线程中除记录了日志和读取几次数据库外并没有额外的操作。
如果有系统的anr日志就好定位了,从这个思路出发,想办法弄一个anr出来,在一台机器上弄个热点,app链接上之后,登录完成后的瞬间拔掉机器的网线,此时app的wifi链接正常,但是所有的请求都会阻塞一段时间,此办法简单有效,app出现了anr,抓取系统的anr日志:
1 | localhost:~ tc$ adb pull /data/anr/traces.txt /Users/tc/work/tmp |
在日志的前面几行就发现主线程在等待一个锁
waiting to lock <0x423e5780> … held by tid=41 (pool-1-thread-4)0x423e5780>
通过日志还原anr的过程:worker线程首先调用了m对象上的方法B,应为是synchronized方法,因此获取了m对象上的锁,一直等待网络请求完成。之后主线程也调用了m对象上的方法A,A也是synchronized的,这是它获取不到锁,一直等待B调用完成。
问题的原因是两个不相干的业务方法,使用了同一个锁来同步,就是当前实例对象,因为synchronized使用this来进行同步,所以在使用synchronized要特别注意,在已有类中添加synchronized方法时更需要注意搜索此类中是否已存在并判断是否符合业务逻辑,如果是多人协作的类,尽量使用本方法才使用的对象进行同步,另外编码的时候还需要考虑业务场景,有些并发可能只是我们自己的想象而已,在业务中是不存在的也就不需要进行同步。
在jf
历程
加入一年多,当时在做r1,领导找到我说要做移动端,安卓和ios都要做,问我想不想负责安卓移动,不过目前就我一人团队要自己找,我犹豫了一会答应了,当时的主要想的有些什么困难,自己不会,没人。这些困难都能克服,不懂可以学,没人可以招,而且我自己比较认同jf的理念想,也想转移动互联方面,这是个机会,也就没多想了
刚开始的压力是最大的,要做出一个东西给领导看,自己要学,还要招人,面试,有段时间晚上失眠,想工作上的事情。
不一样
心态的不一样,到jf是自己想把整个事情做好,当做自己的事业去做,而不是任务,看事情,做事情想的更远。
节奏不一样,相比之前更快更敏捷,原来在r1主要面向传统行业,采用瀑布模型,新的东西要经历调研,设计,评审的逐步过程,一次夸一大步,现在是小步快跑,快速试错,快速调整
技能不一样,更靠近前沿,我们用到了大量的来源代码,也准备把我们自己认为有价值的东西开源出来,也使用了些新的工具,包括代码层面和协作方面的,例如我们team使用了assana,能大大提高协作效率,我们也多次推荐给兄弟team用,这些都是在快节奏中倒逼出来的,逼着自己去提高效率。
如何看jf
以复用人的方式复用代码,我觉得jf找到了行业的痛点,很认同这个观点,而且公司很多业务到放到jf中完成,这就给了jf一个初速度,可以走的更快,可以说成功是必然,失败是偶然,整体思路是对的,jf目前更要专注细节,开发和改进更易用,高性能的系统来支撑jf的运转
脏的不只是空气,更是人心
新闻和朋友圈都是《穹顶之下》的消息,认真的看了两遍,发现要clean的不仅仅是呼吸的空气,还有这幼稚的体制;
震撼,里面的数据让人震撼,3亿吨煤,20亿给一亏损钢铁企业的补助,油老大的垄断和自负;
无奈,神奇的相关部门的每个人都心知肚明,就算有志之人,又能奈何,所有一切服务于财政,所谓的法律就是个笑话;
感动,这样一个调查记录来自个人,更重要的是唤醒了更多的人。
思考,法律没有尊严,太多的例外,体制是根源,请还给公民真正的选举权。