TuStar's Blog

天行健,君子以自强不息;地势坤,君子以厚德载物。


  • 首页

  • 归档

  • 标签

阅读与生活

发表于 2017-04-05 | 阅读次数

阅读量调查

国家 人均阅读量(本)
以色列 64
俄罗斯 55
美国 50
德国 47
日本 40
法国 20
韩国 11
中国 4.58

  以上数据摘自网络,仅供参考。从上面的数据可以看出,我们的国人的阅读量人均很低。当然,我们国家的人口基数大,在一定程度上拉低了平均数字。但看看身边的我们,我们的阅读量又是多少呢?

如何阅读

  该部分内容摘自《HOW to READ A BOOK》(《如何阅读一本书》)根据阅读的层次,可以分为基础、检视、分析、主题阅读。

基础阅读

  一切阅读的基础,当我们读完小学三年级后,我们就已经学会了许多汉子和查字典,已经可读懂一些简单的文章。

检视阅读

  1. 浏览(分析阅读的第一步,找到主题并分类)
  2. 粗浅的阅读(分析阅读的第二步,总结书中的主要内容)

分析阅读

  1. 第一阶段: 这本书的主题是什么?(整理内容大纲)
    • 找到本书的主题或分类
    • 用一句话概括本书内容
    • 列出全书纲要及部分纲要
    • 找出作者提取的和未解决的问题
  2. 第二阶段:这本书到底在说什么?详细内容是什么?(诠释大纲内容)
    • 找出关键字,与作者达成思想上一致
    • 抓住关键句,找出主旨
    • 理清作者的论述思路,重新架构文章结构,找到作者主张
    • 确定文章解决了什么问题、未解决什么问题,未解决的有多少是作者自己认为解决不了的

主题阅读

  • 找到跟主题相关的细节
  • 带引作者与你达成共识(面对不同作者的关键字,由自己建立共识,让作者与我达成共识)
  • 理清问题(把作者的主旨变成自己的主旨)
  • 界定议题(根据不同作者的对问题的观点,就产生了这一主题的争议,即议题)
  • 分析阅读

分析思考

  如今,我们的阅读资讯,除了传统的书籍、报纸、杂志外;我们可以从电脑端、移动端获取我们的信息。在这浩如烟海的信息流中,哪些是我们索需要的,这个答案要因人而异。关于新闻信息,很多App软件(网易新闻、今日头条、快讯、腾讯新闻等),我们可以通过类别标签过滤自己感兴趣的内容。其实,这些应用有些会通过大数据分析你的个人喜好,在推荐栏里面推荐你感兴趣的内容。有时,会导致我们花费大量的时间看一些垃圾信息。个人还是比较喜欢通过标签过滤信息,比如财经、科技、手机、热点之类的。
  关于碎片时间(通常碎片时间就是指没有安排任何工作,未被计划的时间。因为零散、无规律,所以被叫做碎片时间),如果我们加以利用,一年下来,我们可以从中得到很多资讯和阅读量的提升。个人通常在等车,坐地铁或者公交时,通过微信阅读一些公众号的技术和其他类型的文章。一年下来,平均每天至少一篇技术文章,其他类型文章十篇左右,累积下来就至少可达四千左右的文章阅读数量。
  对于分析阅读和主题阅读,我们需要一整段的时间,碎片时间是无法让我们集中精力去分析问题,解决问题。对于我们技术开发或者项目带队,在确定好需求后,我们前期需要去调研技术实现方案。有时,我们需要去实践某些方案样例,充分对比各个方案的优缺点。在得出合理的方案评价时,我们得去阅读技术文档以及博客。在读技术类书籍,比如《Java编程思想》,如果只是监视阅读(快速阅读)的话,往往技术层面的知识只停留在知道。一旦需要现场实战时,我们还得去翻阅资料,搞得连最基础的用法都不会。这时我们,可以深入地去学习,可以照着书上的例子抄写一遍,加深记忆,并且在机器上实战。之后通过做些习题,巩固自己的学习成果。好像有点回到学生时代,做课堂和课后作业。对于优秀开源项目源码的阅读,我们可以参照一些大神的分析博客,加上自己的理解以及实际项目中的应用,我们可以深入理解开发者的项目架构和设计模式。 
  阅读,会在潜移默化的改变着阅读者。《小窗幽记》中有一句胸藏文墨怀若谷,腹有诗书气自华。三毛在自己的文笔里写过——读书多了,容颜自然改变,许多时候,自己可能以为许多看过的书籍都成过眼烟云,不复记忆,其实它们仍是潜在的,在气质里、在谈吐上、在胸襟的无涯,当然也可能显露在生活和文字中。

摘记

林肯控制情绪的故事

读书的意义

读书的意义

不读书的人,
看到的只是别人画给他看的美好世界;
读了书之后,
你认识了黑暗和丑陋;
只有读了更多的书之后,
你就站在了巨人的肩上,
看到了希望和光明。

惰性生根

惰性生根

没有行动,懒惰就会生根发芽!没有梦想,堕落就会生根发芽!时间越长,根就越来越深!到时候想站起来就会是件很困难的事。
拒绝拖延,拒绝懒惰!想要,就立即行动。

参考资料

  • 世界读书日
  • 看全世界人均年阅读量TOP2是如何读书的
  • 不阅读的中国人
  • HOW to READ A BOOK——让你的阅读更高效
  • how to read a book总结(怎样读书精华概要)
  • 寒门再难出贵子
  • 论寒门与贵子
  • 【三毛】读书多了,容颜自然改变
  • 五行相生相克

安卓签名笔记

发表于 2016-05-06 | 阅读次数

安卓jarsigner和zipalign

jarsinger

在Terminal中输入

1
jarsigner -verbose -keystore abc.keystore -signedjar signed.apk unsign.apk abc

接着输入密码

1
abc

详情参照jarsinger

输出一堆内容后可以看到已签名好的signed.apk

zipalign

在Terminal中输入

1
zipalign -f -v 4 signed.apk zipsigned.apk

输出一堆内容后看到已经对齐好的zipsigned.apk

详情参照zipalign

备注

必须是先jarsigner后zipalign

Android内存分析

发表于 2016-04-18 | 阅读次数

说明

  • GC_FOR_MALLOC

    发生在堆被占满不能进行内存分配时,在分配新对象之前必须进行内存回收

  • GC_CONCURRENT

    发生在(可能是部分的)垃圾可够回收时,通常有很多对象可以回收

  • GC_EXTERNAL_ALLOC

    在Android3.0 (Honeycomb)以前,释放通过外部内存(externel memory, 通过JNI代码中malloc分配得到的内存)时产 生。Android3.0和更高版本中不再有这种类型的内存分配了。

  • GC_EXPLICIT

    显示调用System.gc产生的垃圾收集

  • GC_HPROF_DUMP_HEAP

    发生在创建HPROF文件时

实例分析

08-07 17:45:40.373: D/dalvikvm(5783): GC_CONCURRENT freed 2349K, 65% free 3246K/9551K, external 4703K/5261K, paused 2ms+2ms, total 5ms

  • freed 2349K

    说明释放了多少内存.

  • 65% free 3246K/9551K

    65%表示目前可分配内存占比例,3426K表示当前活动对象所占内存,9551K表示堆大小

  • external 4703K/5261K

    indicates external memory allocation, how much external memory the app has allocated and the soft limit of allocation.说明外部内存的分配,已经分配了多少以及能够分配的上限。

  • paused 2ms+2ms

    第一个时间值表示markrootset的时间,第二个时间值表示第二次mark的时间。如果触发原因不是GC_CONCURRENT,这一 行为单个时间值,表示垃圾收集的耗时时间。

  • total 5ms

    GC总耗时

命令行查看数据

  • adb shell
  • ps | grep xxx.xxx 获取pid
  • dumpsys meminfo

参考资料

  • Android内存泄漏分析及调试

中国农历转公历

发表于 2015-10-29 | 阅读次数

术语解释

农历:也称夏历、汉历、旧历、阴历,以下统称为农历
公历:也称阳历、新历,现在国际上通用的就是这种,由于它来源于西方,是辛亥革命时期才传到我国

资料收集

  1. 经过整理的150年内的农历数据(1901-2050)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private static final int[] sLunarInfoArray = {
    0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1910
    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1920
    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1930
    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1940
    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1950
    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, // 1960
    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1970
    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, // 1980
    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1990
    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, // 2000
    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2010
    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2020
    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2030
    0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2040
    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2050
    };
  2. 数据分析
    xxxx | xxxx | xxxx | xxxx | xxxx
    —– | —— | —— | ——
    20-17 | 16-12 | 12-9 | 8-5 | 4-1

    • 1-4: 表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
    • 5-16:为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
      注意:从1月到12月对应的是第16位到第5位。
    • 17-20: 表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
      1
      2
      3
      4
      5
      6
      7
      8
      举个例子:
      1980年的数据是: 0x095b0
      二进制:0000 1001 0101 1011 0000
      表示1980年没有闰月,从1月到12月的天数依次为:30、29、29、30、29、30、29、30、30、29、30、30。
      1982年的数据是:0x0a974
      0000 1010 1010 0111 0100
      表示1982年的4月为闰月,即有第二个4月,且是闰小月。
      从1月到13月的天数依次为:30、29、30、29、29(闰月)、30、29、30、29、29、30、30、30。
  3. 经过整理的150年内的农历正月初一(春节)与公历1月1日(元旦)的天数偏移量数据(1901-2050)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private static final int[] sSolarLunarOffsetTable = {
    49, 38, 28, 46, 34, 24, 43, 32, 21, 40, // 1910
    29, 48, 36, 25, 44, 34, 22, 41, 31, 50, // 1920
    38, 27, 46, 35, 23, 43, 32, 22, 40, 29, // 1930
    47, 36, 25, 44, 34, 23, 41, 30, 49, 38, // 1940
    26, 45, 35, 24, 43, 32, 21, 40, 28, 47, // 1950
    36, 26, 44, 33, 23, 42, 30, 48, 38, 27, // 1960
    45, 35, 24, 43, 32, 20, 39, 29, 47, 36, // 1970
    26, 45, 33, 22, 41, 30, 48, 37, 27, 46, // 1980
    35, 24, 43, 32, 50, 39, 28, 47, 36, 26, // 1990
    45, 34, 22, 40, 30, 49, 37, 27, 46, 35, // 2000
    23, 42, 31, 21, 39, 28, 48, 37, 25, 44, // 2010
    33, 22, 40, 30, 49, 38, 27, 46, 35, 24, // 2020
    42, 31, 21, 40, 28, 47, 36, 25, 43, 33, // 2030
    22, 41, 30, 49, 38, 27, 45, 34, 23, 42, // 2040
    31, 21, 40, 29, 47, 36, 25, 44, 32, 22 // 2050
    };

参考资料

  • lunar农历
  • 算法系列之二十:计算中国农历(一)
  • 算法系列之二十:计算中国农历(二)

Ubuntu高效开发终端打造

发表于 2015-09-23 | 阅读次数

安装oh-my-zsh

1
2
3
4
5
6
7
sudo apt-get install zsh git
sudo shutdown -r now
zsh --version
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.zshrc ~/.zshrc.orig
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
chsh -s /bin/zsh

安装autojump

1
2
3
4
5
6
git clone git://github.com/joelthelion/autojump.git ~/.autojump
cd .autojump
python install.py
在~/.zshrc或者~/.bash_profile中配置
[[ -s $HOME/.autojump/etc/profile.d/autojump.sh ]] && source $HOME/.autojump/etc/profile.d/autojump.sh
autoload -U compinit && compinit -u

安装rvm

1
2
3
4
5
6
7
8
9
curl -L https://get.rvm.io | bash -s stable
出错了则执行
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
接着继续
curl -L https://get.rvm.io | bash -s stable
最后运行下面命令,让配置生效
source /home/tustar/.rvm/scripts/rvm
在~/.zshrc或者~/.bash_profile中配置
export PATH="$PATH:$HOME/.rvm/bin"

安装ruby

1
rvm install ruby

安装rubygems

1
2
3
4
5
6
7
8
9
sudo-get install gem
查看当前使用的源地址
gem sources
删除默认的源地址
gem sources -r url地址
添加淘宝的源地址
gem sources -a http://ruby.taobao.org/
更新源的缓存
gem sources -u

安装repo

1
2
3
4
5
mkdir ~/.repo
curl "http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo" > ~/.repo/repo
在~/.zshrc或者~/.bash_profile中配置
#Repo
export PATH="$PATH:$HOME/.repo/repo"

安装gradle

1
2
3
4
5
6
sudo apt-get remove gradle
下载地址为 http://www.gradle.org/downloads
sudo unzip gradle-2.6-all.zip -d ~/.gradle
在~/.zshrc或者~/.bash_profile中配置
#Gradle
export PATH="$PATH:$HOME/.gradle/gradle-2.7/bin"

安装nodejs

1
2
3
4
5
6
从官网下载https://nodejs.org/en/压缩包node-v4.1.1-linux-x64.tar.gz
tar -xzvf node-v4.1.1-linux-x64.tar.gz
mv node-v4.1.1-linux-x64 ~/.node
在~/.zshrc或者~/.bash_profile中配置
#NodeJS
export PATH="$PATH:$HOME/.node/bin"

安装jekyll

1
2
3
gem install therubyracer
gem install jekyll-sitemap
gem install jekyll

安装sqlite3

1
2
3
4
5
终端安装命令工具
sudo apt-get install sqlite3
图形界面软件
sudo apt-get install sqlitebrowser
sudo apt-get install sqliteman

安装其他命令行

1
2
3
sudo apt-get install ant
sudo apt-get install python
sudo apt-get tree

参考资料

  • ubuntu 14.04下配置on my zsh
  • 如何修改Ruby的gem源(gem sources)
  • Ubuntu之安装Gradle
  • Ubuntu下Sublime Text 3解决无法输入中文的方法
  • unbutu下安装repo并下载源码

Ubuntu常用软件

发表于 2015-09-19 | 阅读次数

终端软件大全

  • oh-my-sh
  • brew
  • git
  • ruby
  • tree
  • python
  • ant
  • repo
  • gradle
  • meld

Android开发软件

  • Android Studio
  • Eclipse

编辑器

  • Sublime
  • Atom

版本管理

  • SourceTree

项目管理

  • Trello
  • Tower

工具相关的文章

  • My development stack
  • Android dev tools
  • Ubuntu常用软件推荐

Android开发总结与设计师交互

发表于 2014-07-16 | 阅读次数

Google安卓设计指南英文版

Google安卓设计指南中文版

布局

  • margin/padding/border知识

  • Google推荐布局间隔

  • Android布局

  • 布局完了之后,可以站在用户的角度看自己的设计

  • 页面元素,先加后减,突出想要突出的内容,弱化不想突出的内容或者砍掉

专业术语

  • 参考资料

    支持不同屏幕英文版

    支持不同屏幕中文版

    Android手机分辨率基础知识

  • Screen size(屏幕尺寸)
    实际的物理尺寸,也就是屏幕的对角线尺寸。
    为简单起见,Android把所有的实际此存分成四个普遍的组:小,正常,大,巨大

  • Screen density(屏幕密度)屏幕一个物理区域上像素点的总数,通常被称作dpi(每英寸的像素点数)。例如,一个低密度屏幕比正常密度和高密度屏幕在给定的物理屏幕区域上的像素点更少。为简单起见,Android把所有的实际此存分成四个普遍的组:小,正常,大,巨大。

  • Resolution(分辨率)

    一个屏幕的总的物理像素点。当为多屏幕提供支持时,应用程序不直接用像素工作;我们只应该关心应用程序运行设备的屏幕尺寸和密度,然后指定是哪个组的尺寸和哪个组的密度。

  • Density-independent pixel (dp)(逻辑密度单位)

    当你设计UI界面的时候你应该用虚拟的像素单位来表示布局的尺寸和位置。当屏幕密度是160dpi是这个逻辑密度单位等于一个物理像素,同时160dpi作为基线密度被系统认为是中等密度屏幕,当必要时系统在运行时显示的处理基于当前屏幕的实际密度的dp单位的任何缩放,dp单位和屏幕像素转换公式是px=dp*(dpi/160)。例如在一个240dpi的屏幕,1dp等于1.5像素,当你设计你应用程序ui时你应该总是用dp单位来处理不同的屏幕密度

图标

  • 应用图标尺寸

    | 分辨率 | 尺寸 (单位:像素) |
    | ———— |:————-:|
    | ldpi | 3636 |
    | mdpi | 48
    48 |
    | hdpi | 7272 |
    | xhdpi | 96
    96 |
    | xxhdpi | 144144 |
    | web | 512
    512 |

  • 设计技巧

    • 图标设计技巧英文版,中文版的可以到Google安卓设计指南中文版中查找

    • 若应用图标是圆角的,切记圆角部分是透明背景

    • 存储图片时,建议采用RGB565编码,减少图片尺寸

    • 图片命名及格式

    • 未特殊说明,图片一律采用png格式

    • 命名规范

      • 按钮 _n(normal)正常, _p(pressed)按下, _d(disable)不可点击命名

        1
        2
        3
        4
        fresh_ic_tab_home_n.png
        fresh_ic_tab_home_p.png
        fresh_ic_navi_back_n.png
        fresh_ic_navi_back_p.png
      • 图标名字前缀

        | Asset Type |Prefix | Example |
        | ————— |:——————:|:—————–:|
        | Icons |ic_ | ic_star.png |
        | Launcher |ic_launcher | ic_launcher_calendar.png |
        | Menu |ic_menu | ic_menu_archive.png |
        | Status bar |ic_stat_notify | ic_stat_notify_msg.png |
        | Tab icons |ic_tab | ic_tab_recent.png |
        | Dialog icons |ic_dialog | ic_dialog_info.png |

字体

  • Android手机默认字体

  • 第三方字体,宋体…

文字

  • 书写格式 Google推荐书写格式

  • 大小

    • 12sp 14sp 18sp …
    • Google推荐尺寸

截图

  • 若图片为纯色,只需告诉开发者颜色参数

  • 若图片有重复部分,采用draw9patch加工图片
    Draw9patch的使用

补充

  • 多看看大公司的UI设计

  • 参考一些优秀网站的分享网站的UI设计

  • 设计师相互交流

手机端推送平台调研

发表于 2014-06-30 | 阅读次数

国内推送平台

百度云推送

  • 百度云官网
  • 免费
  • 平台支持 Android, iOS
  • 评价

    云推送全面支持iOS、Android平台。百度云推送服务支持推送三种类型的消息:通知、透传消息及富媒体,支持单条最大4K的消息推送,其基础的消息推送服务永久免费。而且它支持向所有用户或根据标签分类向特定用户群体推送消息。开发者可自定义内容、后续行为、样式模板等。

    百度推送的送达率有很大的问题,并且后台统计提供的实在是太简陋,综合下来到达率甚至不到50%,而且完全没有技术客服,反馈一个问题通常需要等很久才有回复。

极光推送

  • 极光官网
  • 量大收费
  • 平台支持 Android, iOS, Windows Phone
  • 评价

    极光推送支持iOS、Android两个平台,其SDK的嵌入比较容易,目前支持Portal上推送,也支持API调用。开发者可以推送自定义的消息内容。JPush SDK把内容完全转给开发者应用程序,由开发者应用程序去处理自定义消息。同时,极光推送能以图表的形式直观呈现推送效果,比如推送到达数、用户点击等。目前,去哪儿网、保卫萝卜、虾米网、中国电信等公司都采用了极光推送的服务。

    刚开始免费,量级较大就会收费,据说他们内部有优先级策略,免费的话消息延时的会非常厉害。

个推推送

  • 个推官网
  • 量大收费
  • 平台支持 Android, iOS
  • 评价

    个推,中国最成功的SaaS服务商之一,为移动开发者提供推送服务,可以帮助开发者在应用推送功能上节省开发成本,并保证用户推送质量、节省用户流量,而且支持富文本。个推目前已经与新浪、百度、淘宝等互联网巨头合作,快捷酒店管家、唱吧、啪啪、应用汇等应用也引进了个推的推送服务。另外,个推还提供增量更新服务。应用接入个推SDK后,当开发者在个推后台提交新版本时,个推自动向用户推送一条信息,通知用户下载更新。而且用户下载新版本时,只下载差量部分,无需下载整个安装包。

    刚开始免费,量级较大就会收费,据说他们内部有优先级策略,免费的话消息延时的会非常厉害。

小米推送

  • 小米官网
  • 免费
  • 平台支持 Android, iOS
  • 评价

    小米的push做得优势很明显,和ios的有类似之处,关闭程序等于停掉进程,其他第三方推送都不能送达到。而小米推送走的系统级长连接,由心跳保证连接一直存在,所以只要用户联网,就送达得到。

    小米推送服务支持所有Android平台,在MIUI上属于系统服务框架,共享系统级长连接.

友盟推送

  • 友盟官网
  • 免费
  • 平台支持 Android, iOS
  • 评价

    很多朋友用过反馈效果很一般

聚能推

  • 聚能推官网
  • 平台支持 Android, iOS
  • 评价

    今年6月,聚能推上线单机企业版,将推送技术打包独立给开发者。聚能推面向iOS、Android平台,支持群推、在线推、离线推等多种推送方式。同时,开发者在使用聚能推的推送服务时,可以对每一个应用自定义多达128个标签。根据标签开发者可以更加精准地将信息推送到用户的手机中。企业级用户的所有数据均存储在客户自己的服务器,免除了数据存储在第三方服务商而产生的数据泄漏问题。

华为Push

  • 华为Push官网
  • 免费
  • 平台支持 Android, iOS
  • 评价

    华为Push除了支持通知栏消息、富媒体消息,还支持透传消息,以透传方式将自定义的内容发送给应用。开发者的应用自主解析自定义的内容,并触发相关动作。利用此功能让开发者可实现IP呼叫、好友邀请等功能,完全自由发挥。

    另外,华为Push可根据地理位置触发推送消息。开发者在地图上划定区域,消息会自动推送到进去该区域的用户手机上。

腾讯信鸽

  • 信鸽官网
  • 免费
  • 平台支持 Android, iOS
  • 评价

    有朋友觉得比较小众

其他推送

  • 盛大云推送
  • 应用中自己实现推送功能(内涵段子,今日头条)

国外推送平台

Urban Airship

  • Urban Airship官网
  • 平台支持 Android, iOS
  • 评价

    Urban Airship底层用的是APNs,restful style api/JSON封装数据,对开发者比较友好。开发者每月有100万条的免费额度,不过在100万条的额度用完后,你会发现,相对于其竞争对手Parse来说,Urban Airship的价格稍贵。Parse为0.07美元/千条,而Urban Airship是0.001美元/条。

Appoxee

  • Appoxee
  • 平台支持 Android, iOS
  • 评价

    Appoxee的一系列工具可以利用Push信息,唤醒用户、交叉推广其他应用。Appoxee创新的推送通知管理功能可帮助开发者自动调度并根据特殊参数推送通知,如推送富文本信息,或根据用户的时区推送通知等。

    Appoxee采用阶段性定价,用户量在25万以内普通客户可以免费使用,Silver级别客户在可以享受数据分析、标签API等更多功能的同时,需要每月缴纳500美元。如果开发者需要更精细的推送服务、后台管理与数据分析服务,还可议价。

亚马逊推送

  • 亚马逊推送官网
  • 量大收费
  • 平台支持 Android, iOS
  • 评价

    8月14日,Amazon宣布推出移动设备消息推送服务“Amazon SNS Mobile Push”。Amazon曾在2010年推出消息推送服务,但仅局限于通过SMS或邮件通知收件人。现在该业务已经支持iOS、Android、Kindle Fire等移动平台。

    开发者每个月使用Amazon的推送服务推送的前100万次信息是免费的,之后以“百万次”为单位进行收费,根据通知方式不同,收费为0.06至2.00美元间不等。

push.io

  • push.io官网
  • 平台支持 Android, iOS

GCM(Google Cloud Messaging)

  • GCM官网
  • 平台支持 Android
  • 评价

    谷歌原生推送。

Pubnub

  • Pubnub官网

Pusher

  • Pusher官网

参考资料链接

  • Android 哪个推送平台比较靠谱?
  • 你将选哪个:云推送?极光推送?
  • 留住你的用户:8款第三方移动推送服务
  • 推送服务

Android开发总结编码规范与注意事项

发表于 2014-06-24 | 阅读次数

资源文件

  1. res/资源文件名

    • 项目名缩写_(不用于第三方集成,可缺省)组件名称_模块名称(模块简单,可缺省).xml
    • fresh_activity(item,dialog)_splash.xml

      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
      38
      39
      40
      41
      // fresh 项目名称简写,若不提供给其他项目使用,项目名称可省略
      anim
      fresh_alpha_in.xml
      fresh_alpha_in.xml
      ...
      // n为normal的简写, p为pressed的简写, d为disable的简写
      drawable
      fresh_shape_btn_n.xml
      fresh_shape_btn_p.xml
      fresh_shape_btn_d.xml
      fresh_selector_btn.xml
      fresh_selector_tab_home.xml
      fresh_selector_navi_back.xml
      // 图片命名
      fresh_ic_tab_home_n.png
      fresh_ic_tab_home_p.png
      fresh_ic_navi_back_n.png
      fresh_ic_navi_back_p.png
      ...
      图片命名参考图片命名链接
      layout
      fresh_activity_spalsh.xml
      fresh_fragment_article_detail.xml
      fresh_item_product_list.xml
      fresh_item_product_grid.xml
      fresh_navi_bar.xml
      fresh_item_tab.xml
      ...
      values
      fresh_strings.xml
      fresh_ids.xml
      fresh_bool.xml
      fresh_public.xml
      ...

      图片命名参考

  2. ID名称

    • 模块名称_组件名称
    • splash_imageview_logo
    • ID名称尽量不要相同,重构时,会导致改一个名称,导致很多资源文件的ID同时发生改变

      layout:fresh_activity_setting.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@color/fresh_color_bg" >
      <include
      android:id="@+id/setting_navi_bar"
      layout="@layout/fresh_navibar" />
      <ImageView
      android:id="@+id/setting_icon"
      android:layout_width="80dp"
      android:layout_height="80dp"
      android:layout_below="@+id/includeTitle"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="15dp"
      android:contentDescription="@string/fresh_app_name"
      android:src="@drawable/fresh_ic_launcher" />
      </RelativeLayout>

      values:fresh_strings.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <resources>
      <!-- 应用名称 -->
      <string name="fresh_app_name">Fresh</string>
      <!-- 常用 -->
      <string name="fresh_ok">确定</string>/Users/Tu/Dropbox/GitHub/Study/Android开发总结(二) 与设计师交互.md
      <string name="fresh_cancel">取消</string>
      <string name="fresh_send">发送</string>
      </resources>
  3. 公用布局部分的layout单独写成一个布局文件

    1
    2
    3
    4
    5
    6
    fresh_navibar.xml
    // 使用include的方式调用
    <include
    android:id="@+id/setting_navi_bar"
    layout="@layout/fresh_navibar" />
  4. 一些布局文件若不需要马上显示的,可以采用ViewStub来延迟加载
    一些布局文件可以用merge来减少父布局,提升UI加载刷新速度

  5. 应用图标尺寸
    | 分辨率 | 尺寸 (单位:像素) |
    | ———— |:————-:|
    | ldpi | 3636 |
    | mdpi | 48
    48 |
    | hdpi | 7272 |
    | xhdpi | 96
    96 |
    | xxhdpi | 144144 |
    | web | 512
    512 |

  6. 屏幕分辨率适配,目前Android Studio的预览效果非常不错
    友盟指数

  7. 修改布局文件layout和values时,需要改全不同分辨率和语言版本,我曾经犯过很多次这样的错误

类文件

Google Java Style

谷歌Java编码规范中文版

  • 命名规范

    • 类名采用驼峰命名法
      • 变量名,不要用匈牙利命名法,采用首字符小写的驼峰命名法
    • 方法名,要能够说明此方法的用途
  • 数组中,若索引是有特殊含义,建议使用常量

    1
    2
    3
    4
    5
    6
    7
    8
    public static final int INDEX_ID = 0;
    public static final int INDEX_NAME = 1;
    String[] person = new String[]();
    ...
    String name = person[INDEX_NAME];
    // 对比
    String name = person[1];
  • Model属性适当的加入注释

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Tactic {
    private static final long serialVersionUID = 1L;
    private int id;
    private String action;
    private String value;
    private int notice_type;
    private boolean isReaded = false;
    private Integer[] advertisement_ids;
    ...
    }

    字段action是什么意思,由英文翻译过来为动作,而真正的用途策略,并且不同的值代表不同策略,建议改成枚举类型(Enum)

    1
    2
    3
    4
    5
    6
    7
    public class Order extends FreshObject {
    private int pay_type = PayType.HDFK.value;// 付款方式1:货到付款2:已汇款
    private float total;// 订单总金额
    ...
    }
  • 适当加入空行,增加代码的可阅读性

  • 一些常用的常量,可以集中定义到一个Interface中

    1
    2
    3
    4
    5
    public interface CommonDefine {
    public static final int MIN_EXPAND_COUNT = 3;
    public static final int PER_PAGE = 10;
    }
  • 编完代码后,格式化代码

    1
    2
    Eclipse: Shift+Command+F (MAC OS)
    Android Studio: Option+Command+L(MAC OS)
  • 谨慎使用三元运算符(?:)嵌套 , 太多降低代码阅读性,建议拆分从if..else,建议尽量不要嵌套三元运算符

    1
    2
    3
    4
    5
    6
    7
    @Override
    public int getCount() {
    return currentViewType == ViewType.LIST ? (products != null ? products
    .size() : 0)
    : (products != null ? (products.size() % 2 == 0 ? products
    .size() / 2 : (products.size() / 2 + 1)) : 0);
    }

    这样的代码,可阅读性非常差。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Override
    public int getCount() {
    if (currentViewType == ViewType.LIST) {
    return products != null ? products
    .size() : 0;
    } else {
    if (products != null) {
    return products.size() % 2 == 0 ? products
    .size() / 2 : (products.size() / 2 + 1);
    } else {
    return 0;
    }
    }
    }

    可阅读性强

  • startActivityForResult所需的RequestCode统一管理

    1
    2
    3
    4
    public interface RequestCode {
    public static final int TopicCreateActivity = 0x00002;
    }
  • Intent的action,putExtra的key统一管理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public interface IntentExtra {
    // 自定义, com.xxx.xxx为项目包名
    public static final String TAG = "com.xxx.xxx.intent.extra.TAG";
    // Android系统的
    public static final String EXTRA_TEXT = "android.intent.extra.TEXT";
    ...
    }
    1
    2
    3
    4
    5
    6
    7
    public interface IntentAction {
    // 自定义, com.xxx.xxx为项目包名
    public static final String MAIN = "com.xxx.xxx.intent.action.MAIN";
    // Android系统的
    public static final String ACTION_MAIN = "android.intent.action.MAIN";
    }
  • SharedPreferences的Key统一管理

    1
    2
    3
    4
    5
    public interface PrefKey {
    public static final String PRODUCT = "product";
    ...
    }
  • Log输出

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    public class WelcomeActivity {
    private static final String TAG = WelcomeActivity.class.getSimpleName(); // 建议
    // private static final String TAG = “WelcomeActivity”; //
    // 不建议,一旦重命名类名,类名不会自动改变,一不注意会影响后期调试
    @Override
    public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "onCreate :: savedInstanceState = " + savedInstanceState);
    // 因为是信息级别,所以比较喜欢用Log.i, 输出内容是参照C#中Log输出编写,具体格式为:方法名 + “ :: ”(::左右有空格) +
    // 变量名 + “ = ”(左右有空格) + 变量
    super.onCreate(savedInstanceState);
    }
    @Override
    protected void onResume() {
    Log.i(TAG, "onResume ::");
    super.onResume();
    }
    /**
    * Add shortcut to launcher (多写注释和描述方法,易于代码维护和阅读,具体格式可以参考Java的文档规范)
    */
    private void addShortcut() {
    Log.i(TAG, "addShortcut ::");
    // 信息级别的输出,所以喜欢用Log.i
    Intent intent = new Intent(
    "com.android.launcher.action.INSTALL_SHORTCUT");
    intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
    getString(R.string.app_name));
    intent.putExtra("duplicate", false);
    ComponentName componentName = new ComponentName(getPackageName(),
    getPackageName() + "." + getLocalClassName());
    Log.d(TAG, "addShortcut :: componentName = " + componentName);
    // 调试级别的输出,所以用Log.d
    intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
    Intent.ACTION_MAIN).setComponent(componentName));
    ShortcutIconResource iconResource = Intent.ShortcutIconResource
    .fromContext(context, R.drawable.ic_launcher);
    intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
    sendBroadcast(intent);
    }
    /**
    * Judge have the shortcut on launcher or not
    * (多写注释和描述方法,易于代码维护和阅读,具体格式可以参考Java的文档规范)
    *
    * @return ...
    */
    private boolean hasShortcut() {
    Log.i(TAG, "hasShortcut ::");
    String url;
    if (Build.VERSION.SDK_INT < 8) {
    url = "content://com.android.launcher.settings/favorites?notify=true";
    } else {
    url = "content://com.android.launcher2.settings/favorites?notify=true";
    }
    Cursor cursor = null;
    try {
    ContentResolver resolver = getContentResolver();
    cursor = resolver.query(Uri.parse(url), new String[] { "title" },
    "title=?", new String[] { getString(R.string.app_name) },
    null);
    if (cursor != null && cursor.getCount() > 0) {
    cursor.close();
    return true;
    }
    } catch (Exception e) {
    Log.e(TAG, "hasShortcut :: Exception => Error: " + e.getMessage());
    // 错误级别的输出,所以用Log.e
    e.printStackTrace();
    // 输出错误栈堆里的信息,方便调试
    } finally {
    if (cursor != null && !cursor.isClosed()) {
    cursor.close();
    }
    }
    return false;
    }
    /**
    * Get the section tags like 'Hot tag' or 'search history'
    * (多写注释和描述方法,易于代码维护和阅读,具体格式可以参考Java的文档规范)
    *
    * @param groups
    * @return
    */
    private List<String> getGroups(String[] groups) {
    Log.i(TAG, "getGroups :: groups = " + groups);
    // 信息级别的输出,所以用Log.i
    if (groups == null || groups.isEmpty()) {
    Log.w(TAG, "getGroups :: groups is null or empty");
    // 警告级别的输出,所以用Log.w
    }
    // 参数检查,有助于减少出错和提升性能
    List<String> list = new ArrayList<String>();
    for (String string : groups) {
    list.add(string);
    }
    return list;
    }
    /*
    * 这里的代码是多余的,应该改为用List<String> list = Arrays.asList(groups);若系统帮助类提供某些方法,
    * 我们就没必要花时间去写一些重复的东西,这是自己以前的老代码,贴出了是为了提醒自己。
    */
    // 至于verbose、assert怎么用,用得比较少,欢迎大家共同探讨。后期会从网上收集补全这方面的内容。
    }
  • 多用系统自带的工具类和第三方工具类,没必要自己去重复造轮子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    TextUtils
    URLEncodedUtils
    URIUtils
    Utils
    DateUtils
    DatabaseUtils
    Time
    Arrays
    Collections
    ...

    更多原生工具类

    第三方优秀工具类

  • 多关注一些第三方开源库,可以从中学习到如何编写框架,使用别人写好的框架,减少开发工作。

    Android优秀的开源库

Mac常用软件大全

发表于 2014-02-08 | 阅读次数

转载说明

本篇文章内容来自道士, 欢迎大家访问他的博客脱线道士维克多,
不定期会有更新

记录说明

大家使用同款软件的好处就是,遇到问题至少有同事帮忙搞定。且能互相交流高阶用法。大家都用的迅雷,QQ 之类的软件没收录。

对于我已经废弃不再使用的软件,并不是软件不好,可能是因为我在工作中已经其他替代品了。

说明

  • ★ 正在使用, 星越多代表越常用
  • ☆ 曾经使用,但已经废弃
  • ♣ 关注的软件

工具列表

阅读和学习

阅读当然是为了学习,目前还却一个电子书管理和笔记类的软件,一直没有碰过 Evernote 。平时的流程:

  1. Feedly 订阅新闻源,然后每天早上利用 Reeder 快速浏览,有好的题目直接 star。(10分钟)
  2. 中午把 star 的 item 详细过一遍,值得细读的放入 Pocket,网站类的链接放入 RainDrop。(30分钟)
  3. 中午图片类的素材直接放入 InBoard 存储。(10分钟)
  4. 晚上细读 Pocket 文章需要做笔记或整理的加星,其余删除或放入 RainDrop。
  5. 周末阅读 Pocket 文章,将代码类的整理放入 Gist。
  6. 周末阅读 Pocket 文章,做笔记,然后删除 Pocket 的 Star。
  7. 最后文章以链接形式积累在 RainDrop 中,笔记积累在 github blog,图片积累在 InBoard。
名称 功能简述
Reeder 2 ★★★★★ RSS 同步阅读工具,可以利用 feedly 订阅新闻然后配合阅读
Pocket ★★★★★ 稍后阅读,RSS 中发现的好文章又没时间看,可以选择收藏之后有空再仔细研读
RainDrop ★★★★★ 书签管理,也可完成素材收集和稍后阅读的功能
MindNode Pro ★ 思维导图
Skitch ★ 标注图片工具
Highlights ♣ 标注 PDF 工具

写作

名称 功能简述
Marked ★ Markdown preview 软件,很少用到
Notes ★ 随手需要记录一些临时用的东西就打开它

日常工具

名称 功能简述
Alfred 2 ★★★★★ 效率软件
Dropbox ★★★★★ 同步各种配置文件
iStat Menus ★★★★★ 监控状态栏
iTerm ★★★★★ 命令行增强
Timing ★★★★★ 程序占用时间追踪工具,可以查看你都把时间花在哪些程序上了
Moom ★★★★ 窗口大小管理
NeteaseMusic ★★★★ 网易云音乐
Boom 1 ★★★★ 2 和 1 没啥变化,换了个皮再收一次钱
GithubPulse ★★★★ 提醒每天坚持 github 上的项目
YoudaoDict ★★★★ 有道词典
1Password 5 ★★★ 密码管理
AirMail ★★★ 邮件收发工具,2 和 1 没啥变化,换了个皮再收一次钱
GoAgentX ★★★ 翻山过海来看你
Proxycap ★★★ 指定 APP 走 socks5 代理
Noizio ★★★ 工作时间的白噪音
BitTorrent Sync ★★ 共享文件
Coffee Break ★★ 番茄工作法
Hocus Focus ★★ 自动隐藏光标
AppCleaner ★★ 删除软件
DictUnifier ★ 快速转换星际译王的词典并自动添加到系统中
Photo2Text ★ 图片转文字
OhMyStar ★ 管理 Github 上面收藏的项目
cDock ★ 美化 Dock
SPlayerX ★ 播放视频
LiteIcon ★ 替换图标
Cog ★ 高品质音乐播放器
爱壁纸HD ★ 壁纸
fluid ★ 把网页转换成 Mac APP
Spillo ♣ 书签管理
Keka ♣ 解压工具

开发工具

仍然缺一个好的代码片段管理软件。

名称 功能简述
Dash ★★★★★ 全语言文档手册速查
Sublime Text ★★★★★ Editor,每天用它写代码
Anvil ★★★★ Anvil is a beautiful menubar app for managing local websites
Sequel Pro ★★★★ Mysql 库管理软件
SourceTree ★★★ Git 工具
Kaleidoscope ★★★ 精美强大的 Diff 对比工具,可配合 SourceTree 使用
CodeRunner 2 ★★★ 各编程语言快速测试集成环境,需要去官方下载 2 然后在 MAS 购买 1 才能得到授权
Graphviz ★★ 代码画流程图
CodeBox ★ 代码收集管理
MacVim ★ Editor
BugHub ★ 管理 Github Issues 的工具
Cleaner ★ 清理 svn, git 项目垃圾文件
Datum LE ★ Sqlite 库管理软件
Vagrant ♣ 虚拟机确实需要一个,一直没动手
Patterns ♣ 正则工具,现在用的是网络服务
Echo for Mac ♣ API 测试工具
RESTed ♣ API 测试工具
TrackRecord ♣ 帮你完成重复工作,就像按键精灵
Charles ♣ 抓包代理调试工具

前端工具

名称 功能简述
xScope ★★★ 8合一标尺神器,据说都用来配合 sketch
LiveReload ★ 调试工具:浏览器自刷新、前端代码编译等
Duo ★ 测试网页的响应式设计
ImageOptim ★ 缩小图片体积
GluePrint ★ 小工具用来确保前端像素级别还原设计
Macaw ♣ 值得关注的一款前端开发工具
brackets ♣ 值得关注的一款前端开发工具
WebCode ♣ 画矢量图,导出SVG或者HTML、CSS、JavaScript

设计工具

名称 功能简述
Sketch 3 ★★★★★ 图像处理设计工具,获2012苹果设计大奖
zepline ★★★★★ 配合 sektch 使用
Pixelmator ★★★ Photoshop 的简化版,简单好用
Spectrum ★★★ 配色软件
Sip ★★★ 小巧的取色软件
ImageAlpha ★ 小巧的图片透明度处理
Inboard ★ 图片素材收集工具
Fonts ★ 字体预览
Ember ♣ 图片素材收集工具
framer ♣ Invent, design and experiment with interaction

命令行工具

名称 功能简述
brew Mac 下的包管理器
rvm Ruby 版本管理器
oh my zsh 命令行增强
cask 利用 brew 安装软件

废弃工具列表

废弃写作工具

名称 功能简述
Mou ☆ Markdown 编辑器,经常死机
MWeb ☆ Markdown 编辑器,厚脸求了一个兑换码,发现也不太好用
haroopress ☆ Markdown 编辑器,卡出翔了

废弃日常工具

名称 功能简述
Manico ☆ 图便宜买了,用了几天发现没啥用
Shimo ☆ 科学上网,因为不再使用 VPN 所以不再使用了
Proxifier ☆ 单App,规则代理工具,价格不菲所以改用免费的 Proxycap 了
Clyppan ☆ 管理剪贴板,改用 Alfred 来管理剪切板
One ☆ 改用 Reeder
Vitamin-R 2 ☆ 买了之后发现没有应用场景
Eggscellent ☆ 不能强制打断工作的番茄工具
Blackmagic Disk Speed Test ☆ N年使用一次的测硬盘读写速度的工具
AppZapper ☆ 感觉删除的不干净,还遗留一些配置文件,仍然保留了一枚 2.x 的序列号
QIM ☆ 购买的第一个付费软件,是输入法,不更新了,而且 Mac 下面的输入法各家也都不错了
Dropzone 3 ☆ 常驻状态栏的文件管理器,感觉功能不是很实用

废弃开发工具

名称 功能简述
Atom ☆ 作为一款编辑器,经常崩溃而且性能再调整几年才能用
Versions ☆ SVN 工具
Navicat Premium ☆ 全数据库管理软件,很好也很贵
0xED ☆ 2进制文件编辑器
Robomongo ☆ mongodb 数据库管理
PlistEdit Pro ☆ Plist 编辑器
shuttle ☆ A simple SSH shortcut menu
AliyunOSS ☆ 阿里云管理工具,作者不更新,已经不工作了
Tower ☆ git 工具,曾经想买但是不支持 workflow 就放弃了
codebugapp ☆ PHP 调试工具,虽然它是最好的语言,可是我不会
Gistify ☆ 作为一款 gists 的客户端足够小巧,不喜欢界面
gisto ☆ gists 的客户端不喜欢界面

废弃前端工具

名称 功能简述
Coda ☆ Editor
Xpressive ☆ CSS 前端开发工具
ProCSSor ☆ CSS 处理工具
CodeKit ☆ 自动编译前端文件,自动刷新浏览器,还能对图片优化

废弃设计工具

名称 功能简述
ColorSchemer ☆ 色彩工具,价格不便宜
OmniGraffle ☆ 很棒的专业绘图制表工具,但是对我来说没啥用
PaintCode ☆ 设计软件,生成的图标可以直接在iOS中使用的源码
FontExplorer X Pro ☆ 字体管理,价格不菲而且经常崩溃
Img2icns ☆ Img 转换成 Icon
Briefs ☆ UE 软件,不好用还不如在线服务
Antetype ☆ 界面设计工具,改用 Sketch

工具相关的文章

  • My development stack
  • Brett Terpstra 的 2014 年度最佳 Mac 软件推荐
  • Mac web developer apps
  • Mac Menu Bars
  • 收集&推荐优秀的 Apps (Mac OS & iOS)
  • 使用系统自带的词典程序快速取词翻译
  • 星际译王词库
  • Best of Sublime Text 3: Features, Plugins, and Settings
  • 各种 theme 大全
  • iTerm2新手应知特色功能
  • iterm2:Mac_os下开源免费的并支持Zmodem(sz_rz)的ssh客户端手把手教程
tustar

tustar

10 日志
18 标签
© 2017 tustar
由 Hexo 强力驱动
主题 - NexT.Pisces