Awesome Projects

Catalogue
  1. 1. Introduction
    1. 1.1. About
    2. 1.2. Contribute
  2. 2. Menu
    1. 2.1. TECH
    2. 2.2. NON-TECH

Introduction

About

Contribute

SkySeraph

Menu


TECH

Menu Desc.
Android Awesome Androids
iOS Awesome iOSs
AI Awesome AIs
Front-End Awesome Front-Ends
HardWare Awesome HardWares
Tech-All Awesome Techs All

NON-TECH

Menu Desc.
Web Awesome Web Links
Interview Awesome interviews
Soft Awesome Softs
EBooks Awesome EBooks
Data Awesome Datas


By SkySeraph 10/01/2017


版权声明


SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( http://skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

微信扫码打赏SkySeraph

如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信

本文永久链接:http://skyseraph.com/2017/10/01/Tools/AwesomeProjects/

Comments

UiAutomator2.0升级填坑记

Catalogue
  1. 1. 啰嗦
  2. 2. 重大特性
  3. 3. 基础使用
  4. 4. 采坑记
  5. 5. REFS
  6. 6. 后记

啰嗦

Google Android Developers 在2015年3月就发布了UiAutomator 2.0版本(下文简称U2),而公司的核心产品中用到还是UiAutomator老版本(下文简称U1),业界用U2的也不是很多,虽然有诸多问题和不便(如高版本OS中不支持Remote Debug等),但大家似乎在苟延残喘中麻木了。 公司以前也有专家做过研究和探索,毕竟老项目是万级别的,涉及诸多算法和复杂业务逻辑,遇到几个问题最终不了了之。于是乎,又到了我手里了。

重大特性

1. 基于 Instrumentation,使用Instrumentation test runner即可运行UiAutomator,反之,也即在基于Instrumentation的test中也能使用UiAutomator; 可以获取应用Context,可以使用Android服务及接口。

2. 基于 Junit4,测试用例无需继承于任何父类,方法名不限,使用Annotation进行; U1需要继承UiAutomatorTestCase,测试方法需要以test开头.

3. 与U1的Maven或Ant构建方式不同,U2采用Gradle进行构建; U2输出为APK,Android工程,而U1为Java工程,输出jar包。

4. 新增UiObject2UntilByBySelector等接口, 详细请参考官方文档
其中,U2必须明确EditText框才能向里面输入文字,U1直接指定父类也可以在子类中输入文字。

5. Log日志输出变更。U1可以使用System.out.print输出流回显至执行端,而U2输出到Logcat。

6. 命令运行差异。

adb shell uiautomator runtest xx.jar -c package.name.ClassName
adb shell am instrument -w -r -e class com.xx.xx com.xx.xx.test/ android.support.test.runner.AndroidJUnitRunner

代码中运行:
Runtime.getRuntime().exec(“*“)
device.executeShellCommand(“*
“)

命令格式:instrument [options] component,详细命令格式介绍参考官方文档

基础使用

  • 新建Android Studio工程。

  • gradle中添加依赖。

androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2’{
exclude group: ‘com.android.support’, module: ‘support-annotations’
})
androidTestCompile ‘com.android.support.test:runner:0.5’
androidTestCompile ‘com.android.support.test:rules:0.5’
androidTestCompile ‘com.android.support.test.uiautomator:uiautomator-v18:2.1.2’
androidTestCompile ‘com.android.support:support-annotations:25.3.1’

如需要依赖jar包

androidTestCompile fileTree(dir: 'libs', include: ['*.jar']) 
  • androidTest目录下添加测试用例。

@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class XXTest {
public Bundle bundle;
public UiDevice device;
private Instrumentation instrumentation;

@BeforeClass
public static void beforeClass() {

}

@Before
public void before() {
    // Initialize UiDevice instance
    instrumentation = InstrumentationRegistry.getInstrumentation();
    device = UiDevice.getInstance(instrumentation);
    bundle = InstrumentationRegistry.getArguments();
    assertThat(device, notNullValue());
}

@After
public void after() {
    L.i(TAG + "After");
}

@AfterClass
public static void afterClass() {
    L.i(TAG + "AfterClass");
}

public Bundle getParams() {
    return bundle;
}

}

采坑记

  • 编译错误.
    这个应该说是官方故意坑爹吧,U2的包名结构发生了变化,所以需要将之前所有用到的U1相关API包名进行替换,具体为
    com.android.uiautomator.core. -> android.support.test.uiautomator.

  • 反射相关.
    这个有点坑爹,还是U2包名结构问题(原项目很多地方用到了反射获取U1相关类/方法等),除非对原业务非常熟悉,否则只有遇到问题分析时才会发现此坑,读者以后如果遇到这种类似包结构变化的问题,先不管三七二十一,全局搜索相关字段全局了解再说。当然,如果用到了混淆,也要对应修改。

  • UiAutomatorTestCase相关.
    问题:去除所有测试类中的extend UiAutomatorTestCase后异常。因为原项目依赖于UiAutomatorTestCase中的getPara API来获取U1命令传参。
    方案:修改成U2的InstrumentationRegistry.getArguments方式。

  • 日志相关.
    问题:原项目中业务逻辑依赖System.out.println日志输出结果,而U2中System.out.println不会回显到终端显示,直接影响之前业务逻辑的执行。
    方案:使用Instrumentation.sentStatus自定义状态。

  • 属性文件.
    描述:这个有点意思,原项目为Java工程,有很多属性配置在properties属性文件中,大概有20来个properties文件。而对属性文件的读取是在一个common的公共jar包中,采取的是Thread.currentThread().getContextClassLoader().getResourceAsStream方式。
    问题:①属性配置文件无法打包进apk中 ②读取方式问题
    解决:
    方法1: 将属性配置文件全部放入assets目录,然后通过Context().getAssets().open方式读取;而原先的jar中的公共类,抽离出来作为业务类。
    方法2: 通过gradle自定义打包,将所有属性配置文件打包进apk中,建议。

  • xml配置文件.
    问题:原工程用到了RPC框架,有xml配置文件,存在与上述properties类似问题。
    解决:gradle自定义打包。

  • 权限问题.
    问题:Android M+对权限进行了升级,本工程需要用到文件存储权限,仅在Manifest中声明WRITE_EXTERNAL_STORAGE权限还不够。
    解决

方法1:

@Before  
public void grantPermission() {  
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
        getInstrumentation().getUiAutomation().executeShellCommand("pm grant "+getTargetContext().getPackageName()+"android.permission.WRITE_EXTERNAL_STORAGE");  
    }
}

方法2:通过Rule

@Rule
public final PermissionsRule permissionsRule = new PermissionsRule(
new String[]{  
Manifest.permission.READ_EXTERNAL_STORAGE,
   Manifest.permission.WRITE_EXTERNAL_STORAGE});
  • NoClassDefFoundError问题.

问题:在Android 4.4手机出现NoClassDefFoundError问题,Instrumentation消息为

INSTRUMENTATION_RESULT: longMsg=java.lang.NoClassDefFoundError: org.junit.runner.manipulation.Filter$1 

解决: MultiDex手动拆包A
①gradle文件中添加multiDexKeepProguard

defaultConfig {
    multiDexEnabled true
    multiDexKeepProguard file('multidex.pro')
}

②multidex文件中添加

-keep class android.support.multidex.** {*;}
-keep public class org.junit.runner.** {*;}
  • 系统签名问题.
    描述:此问题是后续测试中才发现的,原来的稳定性/兼容性测试上的性能指标参数大部分显示为空,极其诡异,后面花了很大功夫进行分析发现,很多指标会出现会出现类似Permission Denial : cannot dump 错误,获取不到任何数据。因为原工程需要获取电池、CPU、内存等等几十项性能参数指标,很大一部分是通过sh读取系统文件等方式获取的,通过Runtime.getRuntime().exec 或者 ProcessBuilder.start方式, 比如通过dump中的dump battery获取电池信息,因为dumpsys涉及android:protectionLevel=”signatureOrSystem”,需要权限 ,需要声明android:sharedUserId=”android.uid.system”,需要系统签名….
    解决
    系统签名(无奈之举).
    采用device.executeShellCommand,注意只支持API 21+.

REFS

后记

本文首发于skyseraph.com“UiAutomator2.0升级填坑记”
同步发表/转载 cnBlogs / CSDN / TesterHome



By SkySeraph-2017

版权声明


SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( http://skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

微信扫码打赏SkySeraph

如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信

本文永久链接:http://skyseraph.com/2017/06/04/Android/UiAutomator2.0升级填坑记/

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
    6. 1.6. 其它
  2. 2. 管理
  3. 3. 其它
  4. 4. 后记

  • 古人说,著书立说,纵然而今的现实,书籍本身质量存在一定的局限,但不可否认,一本书从构思,撰写到最终交稿出版,需要一定的沉淀,同时时间的代价是非常大的,而所谓的稿酬其实是几乎是可忽略的。
  • 一直认为的技术书有两种,一种是入门级别的,例如Android/iOS/Swift/.. XX,XX天学会XX等等,就如Google I/O 2017最新宣布Android Studio 3.0完全支持Kotlin,出版社老师就联系我是不是写一本Kotlin XX,我宛然拒绝了。。。另一种是经验或感悟相关的,需要作者一定的沉淀,有思考,有总结,有思考,这是笔者更青睐的一种方式,所以也是上面婉拒的原因之一。
  • 顺便将读者读过或了解过的一些从博客到出书相关书籍进行一个汇总,分享。

技术

综合

黄博文

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. 其它:

SkySeraph

1. 站点:SkySeraph

2. 著作:
《移动应用架构师之路》 2017.人民邮电出版社
《Android NFC 开发实战详解》 2014.人民邮电出版社

陈刚

  1. 站点:CSDN-Cwift的专栏

  2. 著作:
    《Swift 开发手册:技巧与实战》 2016.1 电子工业出版社

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 人民邮电出版社

鸟哥

  1. 站点:vdird

  2. 著作:
    《鸟哥的Linux私房菜》 2010.6 人民邮电出版社

  3. 其它:台湾成功大学环境工程系博士

黄峰达

  1. 站点:PHODAL

  2. 著作:
    《自己动手设计物联网》 2016.7 电子工业出版社
    《全栈应用开发:精益实践》 2017.5 电子工业出版社

  3. 其它:

汪建

  1. 站点:CSDN-wangyangzhizhou的专栏

  2. 著作:
    《Tomcat内核设计剖析》 2017.4 人民邮电出版社

曾健生

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 阿里云

其它

3. 其它:


管理

todo

其它


池建强

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

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

3. 其它:

老杰

1. 站点:oldj’s blog

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

3. 其它:

后记

本文首发于skyseraph.com“那些年,从博客到出书的博主”
同步发表/转载 cnBlogs / …



By SkySeraph-2017

版权声明


SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( http://skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

微信扫码打赏SkySeraph

如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信

本文永久链接:http://skyseraph.com/2017/05/27/SkySeraph/Sharing/那些年,从博客到出书的博主/

Comments

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

版权声明


SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( http://skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

微信扫码打赏SkySeraph

如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信

本文永久链接:http://skyseraph.com/2017/01/26/Android/Appuim源码剖析(Boottrap)/

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


版权声明


SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( http://skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

微信扫码打赏SkySeraph

如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信

本文永久链接:http://skyseraph.com/2016/10/31/SkySeraph/Life/而立之年,未开始的创业路/

Comments