Appuim源码剖析(Bootstrap)

Catalogue
  1. 1. About
    1. 1.1. Appuim
    2. 1.2. 相关概念
  2. 2. Appuim 架构
  3. 3. Bootstrap源码剖析
    1. 3.1. 源码结构
    2. 3.2. 启动时序
    3. 3.3. 类关系图
    4. 3.4. 源码分析
  4. 4. Refs
  5. 5. 后记

About

Appuim

Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用。

这里有很关键一点,跨平台。更多了解Appuim多平台支持相关信息,参考官方platform-support

相关概念

  • C/S 架构
    Appium 的核心是一个 web 服务器,它提供了一套 REST 的接口,接收客户端的连接,监听到命令,接着在移动设备上执行这些命令,然后将执行结果放在 HTTP 响应中返还给客户端。
  • Session机制
    Appuim的自动化测试是在一个 session 的上下文中运行,可以理解成Appuim会话。
    每一次当Appium server成功启动后,客户端的测试库(client library)会要求与Server创建一个会话(session)。
    会话的作用是为了确保能区别不同的客户端请求与不同的被测应用,每个特定的会话都有一个特定的sessionId参数。每次测试开始时,客户端将初始化一个session会话,虽然不同的语言初始化的方式不同,但是他们都要发送POST/session请求到服务器端,这些请求里面都会带有一个对象:desired capabilities ,这个时候服务器端会启动自动化session然后返回一个session ID,以后的命令都会用这个seesion ID去匹配。

  • Appuim Client
    包含众多语言库(Java, Ruby, Python, PHP, JavaScript,C#等),都实现了 Appium 对 WebDriver 协议的扩展。

  • JSON wire protocol
    Appuim中非常重要的协议

Appuim 架构

Appuim基于Nodejs编写,基于HTTP协议,可以看成一个类似selenium webdriver的基于移动平台的webdriver,遵循RESTful设计风格web服务器,接受客户端的连接然后在手机设备上执行命令,最后通过HTTP的响应收集命令执行的结果。

如下为我整理的Appuim Android平台下架构原理图,iOS也类似,只是Bootstrap部分由Instruments替换,UiAutomator由UIAutomation替换。

如下两图参考testerhome PPT的Appuim Android和iOS平台下数据流程图。

其中,Android平台下,Android API 17+,底层调用android平台自带的UI测试框架Uiautomator;反之,调用的selendroid测试框架来完成。

Bootstrap源码剖析

源码结构

如下所示,Appuim Bootstrap部分源码结构,分UiWatchers、Bootstrap和UIAutomator三部分,非常清晰。

启动时序

Bootstrap入口类为Bootstrap.java,继承自UiAutomatorTestCase,然后开启Socket接收命令,时序如下。

类关系图

类关系如下图所示,很简单。

源码分析

Bootstrap整体分SocketServer部分,CommandHandler部分,Watchers部分和UiAutomator四部分。

  • SocketServer。完成PC Server端命令接收和解析,再通过CommandHandler的execute操作调用UiAutomator实现触控操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
client = server.accept();
Logger.debug("Client connected");
in = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream(), "UTF-8"));
while (keepListening) {
handleClientData();
}
in.close();
out.close();
client.close();
Logger.debug("Closed client connection");
} catch (final IOException e) {
throw new SocketServerException("Error when client was trying to connect");
}
  • CommandHandler,虚基类,功能类都集成自该类完成execute操作,通过HashMap映射,如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
private static HashMap<String, CommandHandler> map = new HashMap<String, CommandHandler>();
static {
map.put("waitForIdle", new WaitForIdle());
map.put("clear", new Clear());
map.put("orientation", new Orientation());
map.put("swipe", new Swipe());
map.put("flick", new Flick());
map.put("drag", new Drag());
map.put("pinch", new Pinch());
map.put("click", new Click());
map.put("touchLongClick", new TouchLongClick());
map.put("touchDown", new TouchDown());
map.put("touchUp", new TouchUp());
map.put("touchMove", new TouchMove());
map.put("getText", new GetText());
map.put("setText", new SetText());
map.put("getName", new GetName());
map.put("getAttribute", new GetAttribute());
map.put("getDeviceSize", new GetDeviceSize());
map.put("scrollTo", new ScrollTo());
map.put("find", new Find());
map.put("getLocation", new GetLocation());
map.put("getSize", new GetSize());
map.put("wake", new Wake());
map.put("pressBack", new PressBack());
map.put("pressKeyCode", new PressKeyCode());
map.put("longPressKeyCode", new LongPressKeyCode());
map.put("takeScreenshot", new TakeScreenshot());
map.put("updateStrings", new UpdateStrings());
map.put("getDataDir", new GetDataDir());
map.put("performMultiPointerGesture", new MultiPointerGesture());
map.put("openNotification", new OpenNotification());
map.put("source", new Source());
map.put("compressedLayoutHierarchy", new CompressedLayoutHierarchy());
map.put("configurator", new ConfiguratorHandler());
}

具体映射通过AndroidCommandExecutor中的execute实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public AndroidCommandResult execute(final AndroidCommand command) {
try {
Logger.debug("Got command action: " + command.action());
if (map.containsKey(command.action())) {
return map.get(command.action()).execute(command);
} else {
return new AndroidCommandResult(WDStatus.UNKNOWN_COMMAND,
"Unknown command: " + command.action());
}
} catch (final JSONException e) {
Logger.error("Could not decode action/params of command");
return new AndroidCommandResult(WDStatus.JSON_DECODER_ERROR,
"Could not decode action/params of command, please check format!");
}
}
  • Watchers,Android ANR 和 Crash,如下代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void registerAnrAndCrashWatchers() {
UiDevice.getInstance().registerWatcher("ANR", new UiWatcher() {
@Override
public boolean checkForCondition() {
UiObject window = new UiObject(new UiSelector()
.className("com.android.server.am.AppNotRespondingDialog"));
String errorText = null;
if (window.exists()) {
try {
errorText = window.getText();
} catch (UiObjectNotFoundException e) {
Log.e(LOG_TAG, "dialog gone?", e);
}
onAnrDetected(errorText);
postHandler();
return true; // triggered
}
return false; // no trigger
}
});
  • UiAutomator,通过UiAutomator执行触控操作。

Refs

后记

本文首发于skyseraph.com“Appuim源码剖析(Bootstrap)”/)
同步发表/转载 cnBlogs / CSDN / …



By SkySeraph-2017
Comments

那些年出过书的博主

Catalogue
  1. 1. 技术
    1. 1.1. 综合
    2. 1.2. 移动开发(Android/iOS)
    3. 1.3. PC/Web/后台
    4. 1.4. 游戏
    5. 1.5. AI/CV
  2. 2. 管理
  3. 3. 经历
  4. 4. 其它
  5. 5. 后记

技术

综合

黄博文

1. 站点:cnBlogs-无敌北瓜

2. 译作:《面向对象的思考过程(第四版)》2016.机械工程出版社

3. 其它: Work in ThoughtWorks

蒋鑫

1. 站点:ossxp

2. 著作:《Git权威指南》 2011.机械工业出版社华章公司

3. 作者: 蒋鑫,国内顶尖的版本控制专家和咨询顾问之一,2015年12月加入华为技术有限公司。

李运华

1. 站点:CSDN-华仔-技术博客

2. 著作:《面向对象葵花宝典:思想、技巧与实践》 2015.电子工业出版社

3. 作者: 李运华,阿里资深技术专家

范钢

1. 站点:cnBlogs-充满诗意的联盟

2. 著作:《大话重构》 2014.4 人民邮电出版社

移动开发(Android/iOS)

邓凡平

1. 站点:csdn-Innost的专栏

2. 著作:
《深入理解Android:Wi-Fi、NFC和GPS卷》 2014.机械工业出版社
《深入理解Android : 卷II》 2014.机械工业出版社
《深入理解Android : 卷I》 2014.机械工业出版社

3. 其它:

罗升阳

1. 站点:csdn-老罗的Android之旅

2. 著作:《Android系统源代码情景分析》 2012.电子工业出版社

3. 作者: 1984年生,浙大学士(2007界),上交大硕士(2010界)

林学森

1. 站点:csdn-林学森的Android专栏

2. 著作:《深入理解Android内核设计思想》 2014.5 人民邮电出版社

3. 作者: 香港中文大学硕士, 华为技术专家

王巍

1. 站点:onevcat

2. 著作:
《函数式 Swift》
《Core Data》
《Swift 进阶》

3. 作者: iOS/Unity 开发者,现居日本,就职LINE

包建强

1. 站点:cnBlogs-Jianqiang’s Mobile Dev Blog

2. 著作:
《App研发录:架构设计、Crash分析和竞品技术分析》 2015.机械工业出版社
《.NET探秘MSIL权威指南》译 2009.人民邮电出版社

3. 作者: 毕业于复旦数学系,微软2008年MVP

郭霖

1. 站点:csdn-郭霖的专栏

2. 著作:《第一行代码》 2016.人民邮电出版社

3. 其它:

徐宜生

1. 站点:csdn-eclipse_xu

2. 著作:
《Android群英传》 2015.9 电子工业出版社
《Android群英传:神兵利器》 2016.9 电子工业出版社

3. 作者: CSDN认证专家,职于上海沪江网

任玉刚

1. 站点:csdn-任玉刚

2. 著作:《Android开发艺术探索》 2015.9 电子工业出版社

3. 其它:

PC/Web/后台

王福强

  1. 站点:阿福-瞎子摸象的践行者

  2. 著作:
    《SpringBoot揭秘:快速构建微服务体系》 2016.机械工业出版社
    《Spring揭秘》 2009.人民邮电出版社
    《Real World Scala》

  3. 其它:

徐涛

  1. 站点:cnBlogs-汤姆大叔

  2. 著/译作:
    《深入理解Bootstrap》 2014.5. 机械工业出版社
    译《JavaScript编程精解》 2012.10. 机械工业出版社华章公司
    译《JavaScript设计模式》 2013.人民邮电出版社
    译《Backbone.js应用程序开发》 2014.9 人民邮电出版社

  3. 其它:

曾健生

1. 站点:csdn-曾健生的专栏

2. 著作:《App后台开发运维和架构实践》 2016. 电子工业出版社

3. 其它:

游戏

宜雨松

1. 站点:雨松MONO

2. 著作:《Unity 3D游戏开发》 2014.人民邮电出版社

3. 作者:CSDN博客专家

陈嘉栋

1. 站点:cnBlogs-慕容小匹夫

2. 著作:《Unity 3D脚本编程》 2016.9 电子工业出版社

3. 作者: 光宇在线客户端高级开发工程师

AI/CV

赵永科

1. 站点:csdn-卜居

2. 著作:《深度学习:21天实战Caffe)》 2016.电子工业出版社

3. 其它: Work in 阿里云


管理

todo

经历


池建强

1. 站点:MacTalk-池建强的随想录

2. 著作:《MacTalk·人生元编程》

3. 其它:

其它

老杰

1. 站点:oldj’s blog

2. 著作:电子书 “代码英雄传”

3. 其它:

后记

本文首发于skyseraph.com“那些年写过书的博主”
同步发表/转载 cnBlogs / CSDN / 伯乐在线



By SkySeraph-2017
Comments

而立之年,未开始的创业路

Catalogue
  1. 1. 题记
  2. 2. A君
  3. 3. 聊聊周围
    1. 3.1. B君
    2. 3.2. C君
    3. 3.3. D君
  4. 4. 这两年的一面之缘
    1. 4.1. E君
    2. 4.2. F君
    3. 4.3. G君
    4. 4.4. H君
    5. 4.5.
  5. 5. 回到自己
  6. 6. 到你了
  7. 7. 后记

题记

“现代人不是渴望成功,而是渴望马上成功。”

前几天同一个创客类培训机构合伙人就合作事宜巴拉吧啦,一句话刺激到了小小的心脏,加上90后创业者的遍地开花🌼,似乎些许浮躁,香菇难受,辗转反侧,诸多思考,有了此文。

A君

先从这位创业者(简称A君)说起吧。
A,一位87年小伙,13年研究生毕业后校招进鹅厂,14年深圳宝安2w- 买了房解决了第一个生存问题,15年在一个老板给的200w启动资金下,与几个同事还有以前的同学一起创业,路演获取前海梦工厂创意园办公基地免费入驻…
他想让我加入他们培训体系中某个领域所谓的“权威人士”, 录制线上视频并兼线下培训高级讲师,与我之前合作过的几家大型线上/线下培训机构不同,聊天中他一味的强调他们平台多么多么N,可以将我包装成这个领域绝对的权威,签署排他协议,可以通过他们平台获得很好的声誉,还可以在它们的专栏中出售自己书籍/作品,当报名学员比较多时组织线下培训,培训费用以某个比例分成巴拉巴拉…说白了,没有实际利益,大饼的方式加上我个人时间确实差不多饱和,所以当场直接婉拒了。
然后继续聊他们的创业,讨论了一些关于创业的观点,巴拉巴拉,然后谈到我自己时,我说我的创业路一定会前行,但现在想先满足或者说解决部分生活上的财务自由再开始…他给我一句话刺到了我,“创业的话,真的不年轻了…”,然后提到他们公司现在招聘的都是90后,93/94年小伙子,有冲劲,技术也不错,Github上开源项目star也众多…面试时问 “大家技术都不错,相比别人,我们为什么要录用你而不是别人?”,”年轻资本,熬夜资本…” 这样的答复A自己都笑了,确实很现实,创业公司不多一份付出也不现实(说的有点委婉了),熬夜我们肯定熬不过他们年轻人,这是他们的资本,就如现在邀请我作为他们讲师也一样,这个领域让这群90后去啃,给一定的时间也完全不会有问题,他希望可以找一个既有地位的人来负责比较好(真厉害又被绕进去了)…后面还聊了很多,交换了微信和名片,嘱咐不要急着给答复回去权衡思考下,同他们一起把这件事有意义的事干一干…巴拉巴拉,又一大堆,这些都不重要了,我的思维还停留在他前面的那句话,“创业的话,真的不年轻了…”,是的,打算创业,30,而立之年,创业还未真正开始,慌?盲?迟? 创业,真的想清楚了?

聊聊周围

B君

B君,大学同学,14年离职后同三个同事创立了一家停车场相关公司,自己负责技术,其它三个负责资金和市场,股份平均(创业禁忌)。他们四人每人每月6k生活补贴,其它所有资金都作为储备资金,风风火火的干了一年,团队也从四人做到了十来个,月账面流水也从几万到几十万。
15年,B选择退出,以股份比例分到了一大笔钱。自己注册了另外一家公司,还是做原来的产品,跑华强北购买元器件,找PCB板商画板贴片再招人包装,然后跑市场积累客户,一年多下来,毛收入做到了200w。
现在的他,每天就是进货出货,跑跑市场谈谈主要客户,自由时间大把大把的,每天打打球陪陪小孩,从来没有10点前起过床,也经常找我聊聊是否有其它扩展门路,结合互联网如何来做巴拉巴拉…
说说他这个产品吧,很简单的一个小硬件产品,停车远距离刷卡,读头+卡片,主要赚取卡片插差价。14年15年很多次跟我聊天,说心里话,我压根就看不起这样的产品,这样的所谓“创业”,我跟他聊天灌输的思想一定是高大上的,一定是平台级的,一定是结合互联网,一定是大大的XX。现在,我会发现,错了,我有很多很多很好ideal,我有很好的互联网思维,我拥有技术,但创业或许是个伪命题,只是一个概念,那时的我纯粹的认为创业真的只是一种情怀,是为了情怀,从来没考虑过商业化的思想,突然感觉好像错了,创业,谈情怀之前先谈利益,赚到钱了能盈利才是企业,才是创业,才是中国现社会追从的成功人生。 是么?

C君

C君,同校师兄,08年毕业来到深圳,从SCM到DSP到ARM,从普通工程师到现在某企业(中小企业,100多号人)总技术负责人,拥有企业的股份。他没有所谓的创业,但却能实现100w+的年收入,当然,单纯工作工资肯定没这么多,他在很早时通过别人介绍认识了他现在做的这个行业中某位台湾老板,当时完全不计较得失没日没夜的给他绘图做板开发,最终成为了长期合作伙伴维持并到现在,他们的产品在台北市拥有近乎1/3的市场…是的,他以工作和兼职的方式也在深圳立足下来,农村出生,今年(2016年喔)在深圳南山刚换了第二套房。 每次跟他爬塘朗山,聊天中会发现他是那种慢性子,做事有条不紊,绝不会去追求冒险。我不止一次问他为什么不创立一家公司,招一点人把事做大,他每次都笑一笑说道,成立公司又能怎么样呢?能赚的更多么? 当时不理解,觉得太势利,目光看不远,只在乎短期利益,现在想想,其实也不然,雄浑大志之前一定也要脚踏实地,现在大多数互联网创业者,用所谓的互联网思维去创业,成天谈的就是融资圈钱甚至上市,通过融资去圈用户,然后再考虑如何盈利,是的动辄几百万甚至上千万融资(独角兽类公司毕竟是少数,我们需要那样的实例和憧憬,但短期还是先从产品做起),自身也华丽转身,转身之后呢?我希望的创业也是就酱紫的?

D君

D君,初中同学,未读大学,职高毕业就来到了南广州,从事会展相关设计工作,前面和行业一个朋友一起成立了一家会展相关公司,承办国内外中小型会展设计与布展,目前公司十多个人,一部分是设计师,公司每年也有好几百w的毛收入。我们聚的不是很多,寥寥几次都是记忆深刻,总是带着我出入一些作为码农不太可能涉入的场合,such as夜总会、酒吧、棋牌室等,一群人聊的除了生意就是女人…这也是身边的一个创业者,有可以自己赖以生存的小公司,用他自己的话说反正比打工强。

是的,上面介绍的都是身边的熟人朋友,做的事并不是纯互联网,或实业或者硬件相关,或许他们观点不太正确,甚至有点out,有点跟不上或者脱离我们现在吹的天花乱坠的互联网+的时代,但是,他们至少在他的那领域暂时可以说是成功的,获取了财富,获得了自己想要的,还有自由之身。当然,我周边也有一些互联网创业朋友,天天谈创业,谈融资,天天吹,很多都处在或惆怅融资或惆怅产品阶段,对此不评价…

这两年的一面之缘

这两年有太多创业者找我聊天,有过太多一面之缘,微信上有近乎150+个创业者信息,或创始人或CEO或CTO或合伙人或投资者。看了很多项目,聊了很多项目,也更加发现项目本身真的不那么重要,创业也真的想象中的那么高大上,简单聊聊几个。

E君

E君,一家传统行业的老板,有过行业多次创业经验,15年辞职到现在的公司任执行总裁,创始人是拥有多个摄影基地,拥有雄厚资本,一起创立的公司天使轮就2000w的融资,租赁了比较豪华奢侈有讲究的office,每次过去都是会在他们奢侈办公室喝茶聊项目,然后晚上入驻酒店。我给他们做了几个月的技术负责人,虽然一直要求我去全职入职做他们的技术总监/CTO,综合考虑后最终还是婉拒了。谈谈这个公司吧,才开始技术(双端App+服务端+Web页+公众号 全平台)是外包的,我加入的时候外包已经开始了,我跟进时发现外包公司技术很low,有点忽悠的感觉,招聘应届生来写不熟悉的代码。后面为了进度(定在某个时间需要新闻发布会,准备A轮融资),采取了一方面外包开发继续,一方面组建自己的技术团队,然后再通过自己技术团队逐步将外包可用代码和需求迭代过来,整个过程还是挺艰辛的,最终产品稍许delay后基本按期凑合发布了(发布前一晚还在熬夜赶业务调整需求,没法留出时间做任何性能或质量上的测试等等)。其实按道理说这是一个很不错的经历,团队是我自己组建的,各方面都还不错,但中间过程中我逐渐发现,总监E和Boss都是传统行业人,都不懂技术而且都不太重视技术,他们眼里技术只是为了完成他们这个App或者某个功能,很多时候沟通起来真费劲甚至有些可笑,我的那只团队成员中间近乎3个月没怎么休息过(有一个月全月都在工作,团队成员都单独找我私聊,我用各种理由把E说服后,后面才好些),每天加班赶需求改需求,纵然我给他们挡了很多,给E立了很多项目规范,建立需求池,培训敏捷迭代开发…但,很多都只是暂时的,很难建立一套真正的互联网化敏捷化的项目过程,甚至都很难以项目的方式推进…整个过程下来逐渐发现其实这不是自己想要的创业,想要的事业,想要的一起奋斗的团队,加入后也不会有太大改观,领导的思维很重要,有些固有思维几乎是不可该改变的,确实,纵然,资金+资源这块是E公司最大的优势(这也是我见了几十家创业公司中资源和资本最充足的),但拼凑的团队以及太多传统行业的束缚以及对技术的不重视,会觉得这家企业不会走很长远,不会做的足够大,这是我当时的判断。现在这家公司线下还是做的火热火热的(整合和合作了众多线下一线品牌加盟商),几个月了线上却还只有几千的用户量,日活也少的可怜,比起我自己做的一些App都少很多。是的,创业,团队和资源同样重要,创始人的思维更重要,有什么的思维注定了可以你的团队,你的企业,你的事业可以走多远,所以,创业者的思维,你准备好了么?

F君

F君,一家3D打印平台的CEO/创始人,她在这个行业一直做了近20年,对整个相关联的实体了解颇深(3D打印商等),也正好赶上习大大的一带一路政策,所以就夫妻一起在14年底注册了这家公司来做这样一个平台,深受当地政府的厚重(跟我聊天时将她与市长的微信聊天记录给我看,展览时国家部级领导人参观交流的照片等),政府免费提供了一层楼给其办公,公司人员就十来个,融了两次资(私人老板),第一次200w,10%的股份;第二次200w,5%的股份。 我们见了两次面,一次是她来我上班的地方,咖啡馆里简单聊了两个小时,第二次是在15年底,她公司的城市,我们聊了一整天,上午在其办公室,中午餐馆,下午办公室园区,一直再聊。个人直觉对这样一个行业,领域是非常的看好和认同,CEO眼光也不错,内心希望加入(回家后还跟媳妇商量了好久),但最终没有去成,败在现实利益面前。我们后面邮件往来了很多次主要是沟通待遇利益问题,CTO职位,她最终能给的股份期权非常有限,而且受限很大(不是一次性给),而工资就很少了,基本就是万把块钱的基本生活费,考虑到当时自己的情况,纠结了好久最后选择了放弃。这是自己现在回想会觉得有丝许后悔的为数不多一件事,其实,那时的我也不懂什么创业不创业,仅仅是凭自己的直觉,认为这件事可以为之,认可这样一个领域和产品,却败给了现实的自己。 现在的我反思,总结出创业最最重要的一点,是你必须认可这样一件事,这样才能全身心有激情的去当作自己的事业奋斗,但,同时,创业之路是有风险的,不可能考虑太多现实物质基础的,这样,你真的准备好了么?

G君

G君,应该是一位富二代,从他第二次深夜里开着加长版大奔(恕我浅薄,第一次在深圳见到)来我住的地方判断的(当时车上还坐着一位美女,然后犹豫找不着停车位就让她在车上等着,我俩找了个小店深聊到凌晨1点多)。他从事的是银行放贷这一块的,手里有很多资源,已经有好几家公司,他想做一个放贷相关的金融平台,然后提到马云,然后巴拉巴拉…后面又跟我聊了很多金融相关的东东,包括谈到很多现实的问题,例如在深圳没房,他说保证我明年不出一分钱拥有一套房,具体如何通过资本运作获得跟我详细讲了,听的我云里雾里…是的,他是玩资本的,而且玩了很多年了,国内外资本兼备,对金融完全陌生的我对他有些感到害怕(实话说长这么大还没具体说害怕过某个人)和胆怯…他要求我立即辞职,第二天就去他高大上办公室开始干起,具体他要做的事我都事晕的没有思考的余地,针对马上辞职这个观点,我试着辩解说这不太可能,他马上说提供高额补贴,巴拉巴拉…感觉在他面前我完全没有任何话语权,这是我长这么大从来没有遇到的事…我当时只好回复说要回去同媳妇商量下再决定,当然最后还是没去。 后面和一些朋友聊到这事,他们都说我的抉择是正确的,至少我认为,对于创业,至少要在你熟悉的领域进行,完全陌生的领域,虽然你只需要负责技术,但这不应该叫创业,所以,创业,这个领域你熟悉么?
(ps,现在朋友圈看到G经常晒各种照片,非常成功,各种投资,上月还看到其参加第十一届中国中小企业企业家创新发展大会中拿奖…只能说是一枚有魄力有资本有资源的领导者,服…只是资本的世界现在的我真的不懂~)

H君

H君,没见过面但留有印象,外包做了一个智慧问答平台,纯互联网项目,他的思想一直说这个项目是他自己这辈子真正想要做的事,自己出资金找外包团队做,不考虑融资(至少暂时),只想好好的把这样一件事做好…巴拉巴拉,这样的聊天让我感觉有点异类,真的可以做到在自己资金并不是那么充裕的前提下出资来做一件情怀的事情或产品么,这值得尊重和记忆。 他也跟我沟通,说他CTO有两三个人选,感觉我面相上像,有一种领导者的感觉,所以选我(当时听了,挺舒服的,第一次听人这样夸我…),但我们都还一直没见过面哦,他也不急,说等外包产品完成并发布后我再介入…就这样,中间等到了两个多月,在这段时间里,我在他的那个产品相关的群里逐渐发现,其实,项目除外,他并不是我想象中的那样情怀,很多可能只是言语上的高大上,或者只是我还太嫩…,当然,至少我认为,对于创业,情怀的东西需要要,但只有情怀我觉得是干不好一件事情的,就如我之前提到的,做企业你必须要考虑盈利,不以营利为目的的企业都是耍流氓。

I君、J君,…

回到自己

创业是什么?

我认为的创业,只是一种信息的不对称下,风口面前,事物或东西的归属,或许是你,或许是他人,区别点在于,站在风口面前的你,对这种不对称信息的了解和熟知(Ideal),你的资本是否可以经得起风口风的力度(资源/技术/团队等)? (By SkySeraph 2016)

你真的需要创业么?

你需要创业么? 你真的需要创业么? 这里不想谈太多其它主观客观巴拉巴拉讨论,仅一点,你想通过创业获得什么? 财富? 地位? 情怀? 梦想? 或许是其中之一,但它们不矛盾,你冒着风险,一定抉择后艰辛旅程后这些都只是结果,仅是结果产物。 我更希望的创业是在一定的时机和阶段,做一件自己想要为之的事,把它做成,留一点东西在这个社会,让复杂的事加上你的用心变的简单,仅此而已。

知乎一句话比较直接的击中了现在很多打工人的心。 “认真读书,拿好成绩,上好大学,找好工作,去大公司。努力在公司奋斗30年,费劲力气往上爬,不乱花销,攒钱买房子,做投资。等到退休了,就是有钱人了。相信这个,并且为之付出200%的努力的,就是穷人思维”。 对比一下,前半段是我经历了经历着,似乎没得选择;后半段之前没有考虑过的,以后也不会这样考虑,不曾想过打工可以成为自己的事业,可以实现财富自由,当然,创业也未必,但有可能。为了这种可能,你觉得呢?

我的创业路

任正非,43岁,华为,87年;
马云,35岁,阿里,99年;
马化腾,27岁,腾讯,98年;

创业是一件水到渠成的事,是人人可以为之的事,所以,不着急,不忧虑,试着梳理自己的Ideal,择一其二慢慢实现,沉下心里做几件自己想做的事,相信该来的一切都会来临。
而立之年,你的创业元年。

到你了

你呢?

后记

本文首发于skyseraph.com“而立之年,未开始的创业路”
同步发表/转载 cnBlogs / CSDN / 伯乐在线

By SkySeraph 10/2016 SZ China

Comments

Jenkins Gitlab持续集成打包平台搭建

Catalogue
  1. 1. 相关概念
    1. 1.1. Jenkins
    2. 1.2. Gitlab
    3. 1.3. CI
    4. 1.4. OTA
    5. 1.5. pgyer
  2. 2. 流程结构
  3. 3. 平台搭建
    1. 3.1. Jenkins安装和启动
    2. 3.2. Jenkins插件安装
    3. 3.3. Jenkins系统设置
    4. 3.4. Jenkins Jobs配置
      1. 3.4.1. Jobs基础配置
      2. 3.4.2. Jobs源码库配置(Gitlab为例)
      3. 3.4.3. Jobs触发条件配置
      4. 3.4.4. Jobs构建方式/编译 配置
      5. 3.4.5. Jobs构建后处理
  4. 4. 后记
    1. 4.1. 签名和证书问题(iOS)
    2. 4.2. 邮件发送失败
    3. 4.3. Jenkins Https Support
  5. 5. Refs
  6. 6. 后记

相关概念

Jenkins

  • Jenkins,一个用Java编写的开源的持续集成工具,提供了软件开发的持续集成服务,可监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点。更多介绍参考维基介绍.

Gitlab

  • GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目,更多介绍参考维基介绍.

CI

  • 持续集成, 简称CI(continuous integration).
  • CI作为敏捷开发重要的一步,其目的在于让产品快速迭代的同时,尽可能保持高质量.
  • CI一种可以增加项目可见性,降低项目失败风险的开发实践。其每一次代码更新,都要通过自动化测试来检测代码和功能的正确性,只有通过自动测试的代码才能进行后续的交付和部署.
  • CI 是团队成员间(产研测)更好地协调工作,更好的适应敏捷迭代开发,自动完成减少人工干预,保证每个时间点上团队成员提交的代码都能成功集成的,可以很好的用于对Android/iOS项目的打包.

OTA

  • OTA(Over-the-Air Technology)空中下载技术,具体参考此文介绍.

pgyer

  • 蒲公英(pgyer)为移动开发者提供App免费测试分发应用的服务平台,支持iOS与Android,简单两步分发应用。类似的还有fir.im等.

流程结构

简单绘制了下Jenkins的一个流程,如下图:

IBM Developer上也有一个看似更复杂一点的图,如下图

持续交互流程图:

平台搭建

Jenkins安装和启动

官网https://jenkins.io/index.html
下载http://mirrors.jenkins-ci.org/war/latest/jenkins.war

安装:

  • 依赖于Java环境,首先安装和配置Java环境
  • 官网下载Jenkins,双击安装,如果是Mac电脑,会自动生成全局变量jenkins
  • 修改参数: jenkins + 相关参数,如
    jenkins –httpPort=8888 #更换端口号,当默认端口8080被占用,或指定特定端口时。

启动

  • 手动启动: java -jar jenkins.war
  • 后台启动(默认端口): nohup java -jar jenkins.war &
  • 后台启动(指定端口): nohup java -jar jenkins.war -httpPort=88 &
  • 后台启动(HTTPS): nohup java -jar jenkins.war -httpsPort=88 &
  • 浏览:http://localhost:8080/ , localhost可配置

Jenkins插件安装

插件安装

操作: Manage Jenkins -> Manage Plugins -> Available -> Search -> Click to install,如下图所示

实用插件

  • iOS专用:Xcode integration
  • Android专用:Gradle plugin
  • Gitlab插件:GitLab Plugin 和 Gitlab Hook Plugin
  • Git插件: Git plugin
  • GitBuckit插件: GitBuckit plugin
  • 签名证书管理插件: Credentials Plugin 和Keychains and Provisioning Profiles Management
  • FTP插件: Publish over FTP
  • 脚本插件: Post-Build Script Plug-in
  • 修改Build名称/描述(二维码): build-name-setter / description setter plugin
  • 获取仓库提交的commit log: Git Changelog Plugin
  • 自定义全局变量: Environment Injector Plugin
  • 自定义邮件插件: Email Extension Plugin
  • 获取当前登录用户信息: build-user-vars-plugin
  • 显示代码测试覆盖率报表: Cobertura Plugin
  • 来展示生成的单元测试报表,支持一切单测框架,如junit、nosetests等: Junit Plugin
  • 其它: GIT plugin / SSH Credentials Plugin

Jenkins系统设置

操作: Manage Jenkins -> Configure System

  • Jenkins内部shell UTF-8 编码设置,如下图所示

  • Jenkins Location和Email设置,如下图所示

  • E-mail Notification,设置如下如所示

Jenkis系统设置3

SMTP详细配置请参考 How to send Email at every build with Jenkins

Jenkins Jobs配置

Jobs基础配置

配置编译参数

例如,如果需要打包者自行选择打包类型,如需要编译Release/Debug/Test等不同版本的包,那需要配置Jobs的编译参数,配置方法如下图所示:

Jenkins编译设置-参数设置2

你还可以配置一些其它参数,例如:

Jenkins编译设置-参数设置3

配置完后,build界面中就会出现,如下如所示:

Jenkins编译设置-参数设置1

How to configure a single Jenkins job to make the release process from trunk or branches?

配置匿名用户权限

后面打包的应用发布时,如果懒得自己搭建服务器,就用Jenkins的,但发布出去的链接需要登录才能访问,这时候你可以设置匿名用户的访问权限,这样匿名用户可以下载访问你提供的应用链接了,非常取巧的方法,如下图:

Jenkins编译设置-参数设置4.png

Jobs源码库配置(Gitlab为例)

配置SSH

操作: Manage Jenkins -> Credentials -> Global credentials (unrestricted) -> Add Credentials

  1. 本机生成SSH:ssh-keygen -t rsa -C “Your email” , 生成过程中需设置密码,最终生成id_rsa和id_rsa.pub(公钥)
  2. 本机添加秘钥到SSH:ssh-add 文件名(需输入管理密码)
  3. Gitlab上添加公钥:复制id_rsa.pub里面的公钥添加到Gitlab
  4. Jenkins上配置密钥到SSH:复制id_rsa.pub里面的公钥添加到Jenkins(private key选项)

新建Job

在Jenkins中,所有的任务都是以”Job”为单位的。在进行操作前,你需要新建一个Job,Job新建比较简单,只需要在Jenkins管理的首页左侧,点击“New Job”,一般选择free-style software project,再输入Job的名字即可。

配置Gitlab

在新建的任务(Jobs)中,Gitlab源码配置如下图:需要输入git仓库和build分支,公钥使用上面配置SSH生成的公钥。

Jobs触发条件配置

Jenkins支持多种触发器配置,包括:

  • 定期进行构建(Build periodically),定时器使用示例如下:

    H(25-30) 18 1-5: 工作日下午6点25到30分之间进行build
    H 23 1-5:工作日每晚23:00至23:59之间的某一时刻进行build
    H(0-29)/15 :前半小时内每隔15分钟进行build(开始时间不确定)
    H/20 :每隔20分钟进行build(开始时间不确定)

  • 根据提交进行构建(Build when a change is pushed to GitHub)

  • 定期检测代码更新,如有更新则进行构建(Poll SCM)

Jobs构建方式/编译 配置

Jenkins支持多种编译配置方式,包括:

  • Xcode: iOS编译配置(安装Xcode integration插件)
  • Invoke Gradle script: Android编译配置(安装Gradle plugin插件)
  • Exceute Shell: 脚本方式

对于iOS应用的构建,如果选择Xcode方式构建,需要配置好开发者证书,具体参考后面签名和整数问题。
推荐使用Exceute Shell方式,简单有效。

Jobs构建后处理

Artifacts和邮件通知配置,参考下图

Jenkins项目设置-Archive-min

可借助Email Extension Plugin 插件进行详细配置,具体可参考此文

Jenkins项目设置-邮件-min

发布

当然,如果不想自己的应用发布到三方网站,只希望在自己的内网上托管,这样需要在自己内网上搭建服务器,服务器搭建方式有很多种,Mac上可以用自带的Apache服务,也可以用其它服务。

iOS的发布可能希望用到OTA,可参考此文 还有这篇一步一步实现无线安装iOS应用(内网OTA)

这里分享一个我写的shell脚本模板(已开源),可以用于iOS的plist文件自动创建以及OTA简单发布页面的自动创建,参考此链接获取源码, 欢迎Star.

自动生成一个简单HTML界面,如下图,点击Install即可安装:

Jenkis发布1

注意,这里iOS7.1以后限定必须要要用https,所以需要对jenkins设置下https,参考下面”后记” 中的Jenkins Https设置

Last Show

构建成功后最终的结果如下如所示:

后记

签名和证书问题(iOS)

邮件发送失败

  • 实际搭建过程中有遇到此问题,折腾了小会,还以为是公司邮箱地址为题,后面发现仅仅是一个小配置问题。
  • Extended E-mail Notification中也需要和E-mail Notification一样,点击Advanced,然后选择Use SMTP Authentication,配置同E-mail Notification的参数。

Jenkins Https Support

查询Jenkins Https相关命令:

1
java -jar jenkins.war --help | grep -i https

说明:下面以Mac为例.

KeyStore方式

  • 生成:
1
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass 密码 -dname "cn=WEB"
  • 使用:
1
java -jar jenkins.war --httpPort=-1 --httpsPort=8080 --httpsKeyStore=/目录/keystore.jks --httpsKeyStorePassword=密码
  • 注意: 第一次使用时需要将”WEB”证书导入,导入步骤为:Chrome导出证书 -> 安装证书 -> 设置证书”全部允许”, 图解步骤可参考下面实用参考中的第5篇文章.

Certificate方式

  • 生成:
1
2
3
4
5
sudo openssl genrsa -out server.key 2048
sudo openssl req -new -key server.key -out server.csr
sudo openssl genrsa -out ca.key 1024
sudo openssl req -new -x509 -days 365 -key ca.key -out ca.crt
sudo openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
  • 使用:

启动Jenkins:

1
java -jar jenkins.war --httpsPort=8088 --httpsCertificate=/path/server.crt --httpsPrivateKey=/path/server.key

  • 注意/说明:
    1 同上
    2 iOS手机需要导入cer证书(ca.crt)
    3 Common Name 填写IP地址或域名地址
    4 第5步骤如果提提示“I am unable to access the ./demoCA/newcerts directory” 错误,解决方法为:
    在当前操作目录,新建demoCA\newcerts2层文件夹
    然后再demoCA文件夹下新建一个空的index.txt文件
    再新建一个serial文件,没有后缀。里面填入01

实用参考

Refs

后记

本文首发于skyseraph.com“Jenkins Gitlab持续集成打包平台搭建”
同步发表/转载 cnBlogs / CSDN /



By SkySeraph-2016
Comments