闭包,编程思考

闭包,编程思考 缘由:经常会文章里看到闭包,对闭包有种感念,但有时候会绕进去。正好加上,android端的构建使用了gradle,gradle脚本基本上都是由闭包构成和撰写的,便研究了一番。更加巧合的是,参与iOS问题讨论的时候,发现了Block这种编写方式,越发觉得这些都是速途同归的玩意。 摘要: 闭包定义 解读闭包 闭包的意义 不同语言对于闭包的另类实现 思考 闭包定义 Wiki上闭包的解读(很精彩)) 闭包的定义: closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions. 可以给个中文版本的: 闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。 解读闭包 好吧好吧,无论是英文还是中文,读起来感觉都特别的绕口,理解起来就更绕口了。 还是直接暴力点吧,直接来代码吧: function startAt(x) function incrementBy(y) return x + y return incrementBy variable closure1 = startAt(1) variable closure2 = startAt(5) 这是基于python的闭包的写法。 (在我的接触中,python语言是较为简单的,入门比较低,即便没有入门,看代码也不是困难,所以拿python举例,当然,建议大家都学学这个语言,一般一个星期写简单的程序就没问题了) (python中,缩进代表 {} 符号) 解读: startAt是一个函数,或者叫方法。它的返回值也是一个函数,或者叫,它返回一个函数类型的值。 那么有意思的来了: closure1(3) = 4 closure2(3) = 8 那么,startAt到底是什么? 解释它之前,先解释一下变量closure1 和变量 closure2 closure1 = 1 + 参数 closure2 = 5 + 参数 //所以 closure2(3) = 5 + 3 = 8 可以发觉,startAt是定义了一种加法。但属于它的变量x却离开了startAt一直和closure1和closure2存在,赶紧回去看一下刚才最初的定义。 下面是我最喜欢的一段对于闭包的解读: Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function’s lexical environment (i.e., the set of available variables) at the time when the closure was created. Read On →

【Android】使用Gradle进行配置

【Android】使用Gradle进行配置(记录) 摘要 介绍 需求 配置工程 概念介绍 直接推荐几篇文章入门。 深入理解Android的Gradle Gradle 用户手册(含部分翻译) ADT已经不在继续更新了。自然而然的,Android Studio成了新贵。虽说还是有一些别的IDE和别的方式去编写和构建Android,但由于谷歌的维护和升级,AS成了绝大多数Android开发者的选择。对于小团队来说(本人就是在小小小团队),AS + GRADLE 成了现阶段主流。 这是记录,所以概念型的东西就不做介绍了。 需求 由于团队本身有好多服务器(*开发,灰度,线上*),再加上有很多三方的引用(如:我们团队IM引用了环信),另外还有一些日志系统的调控等,再加上长时间不同人员对代码开发,导致这些配置非常混乱,散落于不同的类,还有一些在AndroidManifies.xml等文件中,所以导致导报经常会出现一些莫名其妙的错误。 需求:实现 > 能合理地配置这些,并使用配置文件进行统一管理 >的需求。 目标如下: 只需更改一处(一行)就能实现不同需求打包的切换!(最重要) 简单 不影响Studio相关联的gradle文件(build.gradle一旦改变,就会导致重新编译),但又可以及时更改相关配置。 配置工程 配置BuildConfig BuildConfig 这个类是工程自动构建生成的。可以具体看一下这个类。 /** * Automatically generated file. DO NOT MODIFY */ package ****; public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "**.builddemo"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = ""; public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0"; } 注释说:这个类是自动生成的,别动,动了也没什么用~~~ 然后可以看到,这里DEBUG,APPLICATION_ID,BUILD_TYPE,FLAVOR,VERSION_CODE,VERSION_NAME这些常量,这些常量有的是我们在AndroidManifest.xml中配置的,有些是我们在module下的build.grade中配置的(当然,这些其实全部可以在build.gradle中进行配置) 就像这个样子: android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "**.builddemo" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard- rules.pro' } } productFlavors { } } 由于工程中需要versionCode参数,所以BuildConfig便提供了很大的便利。 Tip: defaultConfig{} 这个闭包就是配置工程参数的,也就是直接对应BuildConfig的 既然如此,如果能给BuildConfig配置自定义的参数,那么需求就解决了一半了! 显然,Android团队也肯定会留下一些自定义的API,保证大家能 “ 随便乱搞”。 下面是自定义API写法和使用 defaultConfig { ... Read On →

关于苹果证书

关于苹果证书

Read On →

CocoaLumberjack的集成和学习

CocoaLumberjack的集成和学习

Read On →

Android自动构建

Android自动构建发布实践 首先声明。 这主要不是讲教程,这是集成过程中遇到的坑! 这主要不是讲教程,这是集成过程中遇到的坑! 这主要不是讲教程,这是集成过程中遇到的坑! 重要的事情说三遍。 集成工具 jenkins (CI) Git and GitLab(GitHub同理) Gradle (build 工具) fir (发布工具) 工具简单介绍一下, jenkins是现在比较主流的CI,也正是因此,上面的插件丰富,涵盖面也很广,更为重要的是,非常容易安装和配置,自然是首选。 Git 版本管理工具,就不用了讲解了。jenkins同时支持svn。(还是建议大家早点转到git上)公司现在的版本管理使用的是gitlab,类似github(github的迷你版)。 Gradle是现任Android构建,很是强大。至于grade配置,网上教程很多也很杂乱,建议大家跟随谷歌原版[Gradle 用户指南]() 这里再推荐一篇,个人认为对Gradle解读很到位的一篇文章。[深入理解gradle]() 开始集成 安装jenkins。 如果你是mac或者Linux,可以直接通过shell安装(推荐 ) $ brew install jenkins 如果没有brew,先安装Homebrew $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 如果没有ruby… 请自行google。 启动 Jenkins $ jenkins 访问 Jenkins 请在浏览器输入地址: http://localhost:8080/ 使用安装包安装后会自动打开,如果端口冲突那么请修改端口 defaults write /Library/Preferences/org.jenkins-ci httpPort xxxx jenkins最基本的安装就完成了。然后,可以在浏览器输入地址查看一下。看到这样的画面,基本安装就完成了。 截图里包含两个,一个是通过web端浏览器访问得到的界面。另一个是shell的日志。 jenkins到此结束。开始使用jenkins,Android的构建之旅吧。 jenkins的插件安装 两种方式。这里以安装Git插件为例。 通过查询安装。 通过自行下载*.hpi , 然后通过高级安装。 选择系统管理,然后选择管理插件。 查询安装。 在插件管理界面,选择可选插件,然后在右边过滤器里筛选Git或GIT plugin 然后选择立刻安装。 自行下载*.hpi , 然后通过高级安装 然后选择上传。 遇到的坑 可以说刚开始我是一只使用第一种方法来安装插件的。结果失败率非常高。如果不自备梯子,失败率会更高! 折腾了很长时间,而且搞得自己心里憔悴。 所以建议大家通过自己去jenkins的官网或镜像来下载hpi文件自行安装需要的插件。 还有,自备梯子是一种好习惯。 需要安装的插件 Git Gitlab Gitlab Hook (我一直安装不成功,所以自动push event 构建也还未成功) Gradle fir (官网有详尽的下载和安装教程) 到此为止,所有的环境都准备好了。终于可以开动了! 自动化构建实例 jenkins中新建一个项目,命名后,选择 构建一个自由风格的软件项目。 项目名称。跳过 描述。跳过 … 各种跳过,直接进入源码管理。 源码管理 这里选的是Git,当然如果你只有现实svn的话,那就是你还没安装Git的插件,具体安装请看上文。 记住选择构建的分支。(这里是一个只含一个界面调试的项目,所以我直接用了master。建议,创建一个deploy发布或者debug这样的分支,确保每次构建都是可控的。) 注意到Credentials,这是身份验证。这里直接写了none,也就是说,没有直接验证身份。难道说,我的项目没加任何限制??? 当然,不是啦。Git的项目,无论是Github还是自己搭建的Gitlab,大多数都是通过ssh验证的。 可以点击Credentials 后面的Add 。 这样保证jenkins部署的机器的ssh私钥在服务上。 构建触发器 这就是传说中的自动构建。直接上图讲解。 这里有三种事件触发构建。 Build periodically 。 即定时触发,这里我写的是H 10 * * *,指的就是每天10点触发构建,也就是说,每天10天无论有没有新的代码部署,都会进行构建。 H 10 * * * 分 小时 天 月 年 // 五位分别指向轮询事件,这里H 和 0 差不多意思,就是不顾及 分,每天10天构建。 // * 指忽视 Build when a change is pushed to GitLab. Read On →

日出

日出,让你的脚步停一下

Read On →

感想 我该如何成长

感想-我该如何成长 我始终相信,优秀归根到底是自己的事儿,所以成长,归根到底,也是要靠自己。 ——飞鸟 几天前和一个朋友聊起学习,又被一阵吐槽。说是被老板压榨,没有时间学习,等等巴拉巴拉…又突然想起一个同事,总是感慨总是被公司的业务羁绊,向业务妥协。便有了这篇感慨。 然后,我很认真的问自己,我该如何成长? 想明白这个问题之前,应该先想明白另一个问题。 我到底想成为一个什么样子的人? 相信自己而不是相信依靠 有个同事说起这么一番话,我直接抄过来了。 在思路上, 技术大牛确实给了很多启发, 甚至可以说不是技术细节的启发, 对我来说都是颠覆性的想法, 这些思路靠自己研究, 并且又在业务迭代的压力下几乎是不可能的。 我其实很承认这句话的。尤其是和一些优秀和专研的人聊天,往往听完后,第一感觉就是听君一席话,胜读十年书啊。(当然,不仅仅局限技术大牛。) 可惜的是,倾听我准备好了,求教我也准备好了,该准备的都准备好了。正所谓万事俱备,只缺一个技术大牛。 好吧,有能指点的技术大牛是幸运的。但如果没有,其实也没那么糟糕。因为这个时代不仅不缺技术大牛,而且大牛们都还很喜欢分享。想想中国古代的老师傅们,总要留一手,不让本事全被徒弟学去了,而如今的大牛们,恨不得把自己的会的全都拿出来让你看看。(我一直庆幸自己能在这样一个时代里去拼搏。) 所以金山银山颜如玉神马的都有,只不过那些让你醍醐灌顶的指点都散落在网络上各处,只不过这次是需要你自己去找。 我想说的是,不要去依赖,如果非要依赖,也只能依赖自己,相信自己。 有捷径请走捷径,如果没有,请更加努力 不得不承认,有人带着学习或者成长,会比自己摸石过河要快很多,少犯错,少走路。我是一个捷径主义者,所以,那些所谓打基础啊,吃亏是福啊,这是一种锻炼啊之类的话,我都认为是扯淡。 聊点题外话,中学化学有一种推断ABCDEF是什么物质的题,大概是下面这个样子。每次做这种题,我都直接把出现最多的字母当成O,氧气。或者遇到无色透明液体,我直接就写成水。然后再一推断,一两分钟就能解决这个题。这个方法我从初三一路用到高考都不带失手的。捷径这么好用,为啥不用呢。 聊完题外。回来说说,如果真没有人带,需要自己摸黑,走一步算一步的时候,我只能说。请更加努力,请更加劳苦,虽没有捷径可走,但至少还可以多付出。 完美这个伪命题 从小在做生意的人堆里长大,所以听到被人说: 只是单纯而简单的钻研技术, 把每个模块每个函数写到自己觉得完美. 这样的话。我就很不舒服。在我心里大概有这么一个评级,不足,足够,优秀,完美。而我呢,是一个追求优秀,但忌惮完美的人。我潜意识里,完美等于巨大的物力,人力,财力,以及时间,一句话——高额成本!一旦遇到高额成本,我就会吓得慌。 也怪我太贪心,不够专注。或者猎奇心太重,总想着尝试新的技术,新的东西,新的领域。所以,在我看来去追求完美,真的太浪费了。不是有句名言这么说的 不追求完美,何尝不是一种放下。 刚开始学习JAVA的时候,对各种设计模式学习,那叫一个如此如醉,奉若神技。但随着时间慢慢过去,现在反倒觉得那么多设计模式,何尝不是一种累赘。一方面,写出的代码怎么看都觉得有那么点相似,另一方面,有一种变相的冗长。再后来,接触了javascript,python等后,(现在学习Go中),越发着发觉,所谓的设计模式,本质上是Java语言本身的内建不够啊。 想明白这点后,设计模式就再也不神秘了。好像又写的有点跑题了,回到完美这个梗。Java本身是有缺陷的,所以已阻止了完美的步伐,或者这样说:用Java写了一个完美的方法,模块。但这种完美却很脆弱。脆弱到,一不小心,被时代淘汰了。 时代太快了,快的让我不敢只专注于一项技巧与一种语言。

Android自定义属性使用

Android自定义属性使用以及注意事项 自定义控件和自定义属性是安卓开发过程中实现个性化的一个很好技巧,也是对sdk中UI部分的使用更加灵活的部分。这部分主要实现自定义属性,自定义控件的文档正在完善中。 如何实现: a) 在配置文件中声明。 虽说在value中哪个文件里都是一样(保证在resources标签下就行),但作为一个有志向的开发者,良好的文件管理习惯是必须的,so,在values中创建一个名为:attrs.xml来统一管理自定义属性。 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ImageTextView"> <attr name="select_src" format="reference" /> <attr name="normal_src" format="reference" /> <attr name="select_text_color" format="color" /> <attr name="normal_text_color" format="color" /> <attr name="image_text_padding" format="dimension"/> <attr name="android:textSize"/> <attr name="android:layout_gravity" /> <attr name="android:text" /> </declare-styleable> </resources> 自定义属性的声明是通过子标签declare-styleable声明了大的样式,具体的属性是通过attr来声明,声明包含属性名和格式(具体是属性值的格式,一般有reference,color,integer,float,dimension,boolean,string等,当然还有enum,如果是枚举的话要继续声明具体的枚举),如果对于自定义控件来说,某些属性就是已经android声明的属性,就可以在name后面直接写明使用android:声明的哪个属性(简单吧)。 b) 在自定义控件xml中使用 (主要是讲解自定义属性,所以这里的自定义控件较为简单,就是一个imageview + textview的组合) <com.android.lesdo.view.UpImageTextView //声明使用app来定义自定义属性名,当然这个命名是你确定的。 xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text = "Hello" android:textSize = "14sp" android:layout_marginRight="59dp" // 使用刚才已经在arrts里声明好的属性 app:select_src = "@drawable/searchuser_t_pressed" app:normal_src = "@drawable/searchuser_t_normal" app:select_text_color = Read On →

Android Transition 学习心得

开发,android,transtion

Read On →