人是习惯的产物

摘自《Rework》

人是习惯的产物.所以人会对改变作出消极的反应。他们习惯于用特定的方式来使用某物,任何改变都会打乱事物的自然顺序。所以他们会回到原处。他们会抱怨。他们会要求你将其恢复到事物的本来面目。

但是这不意味着你就要这么做。有时候你需要为你所相信的东西提前下决定,就算它一开始不受欢迎。

人们常常在给一次公平的机会改变之前就作出反应。有时最先出来的负面反应要比正面的回应多。所以你会听到诸如“这是我见过的最烂的东西”的话,这不是。这只是一次小小的改变。得了吧!

同时,记住,负面反应几乎比正面反应更大声,更激烈。事实上,在大多数顾客都因为改变而高兴的时候,你却只能听见负面的声音。确保你不会愚蠢到收回必要却有争议的决定。

所以当人们抱怨时,让它沸一阵子。让他们知道你在听。告诉他们你明白他们所说的话,明白他们的不满。但是要向他们解释你会任由事情发展一阵子看看发生了什么。你可能会发现人们最终会适应。一旦他们习惯了,他们最后会喜欢这个改变胜过旧的方式。

Continue reading ↦

灵感易逝

《Rework》结语

我们每个人都有想法。想法是不朽的。他们会永远存在。

不会永远存在的是灵感。灵感就像新鲜的水果或者牛奶:它有保质期。

如果你想做什么,现在就去做。你不能把它搁在架子上等两个月再抽时间去做。你不能说稍后再做。稍后你就没有那么激动了。

如果你在星期五时灵感来了,就下决心在周末就投入这个项目。如果你灵感涌动,两个星期的工作你只要24个小时就能完成。灵感此时成了时间机器。

灵感是神奇的东西,是生产力的倍增器,激励因素。但是它不会等你。灵感是现在的事。如果灵感找上了你,你也要抓住它,然后投入工作。

Continue reading ↦

我的网盘们

以下所有内容都是基于我使用过的各个网盘的免费服务,没有用过收费的,所以不做评价。

最近各大网盘都在T级冲锋,其实对我们来说只是一个数字而已,对大多数人来说实际意义不大。

所有网盘网页版比较欠缺的一点是:文件夹上传,多文件打包下载。百度云,有上传文件夹需要插件支持,所以Linux下别想了。国内大公司网盘都存在的问题:没有Linux类客户端。。

个人强烈推荐使用Dropbox!!!

Dropbox

国外著名跨平台网盘,应该算是网盘始祖级别的吧

目前用途:

  1. 公司内部协作使用
  2. 个人文档同步(Yunio升级3.0以后,彻底转入Dropbox)

不足:

  1. 初始免费空间比较小,只有2GB,免费空间最大目前可到19G。个人文档存储应该是够了
  2. 客户端同步有点屎,得重启才能获得团队中别人的更新,又是墙的原因。解决方法可以参考:解决Dropbox无法实时更新的问题

这里有一篇文章:为什么Dropbox如此的受欢迎。Dropbox只做了该做的事情,简单直接好用。而国内网盘现在功能五花八门,让人眼花缭乱的。我需要的就是一个同步网盘,同步本地文件夹到服务器和其他设备。

每邀请一个好友开通,自己和开通的好友均可得到500MB永久免费空间,最多可获得16GB。邀请链接:http://db.tt/ZzVeBSUY,点击注册你和我同时增加500MB空间,也就是你注册的初始空间2.5G(ps:可能需要翻墙。。)

Continue reading ↦

龙门镖局

标题党啦,误入莫怪。。。主要是发现龙门镖局的缩写和我的博客域名是一致的:lmbj,所以兴起发一文。 去朋友那边玩,他正在看这个,就看了几集。对我来说纯属看着打发时间,逗逗乐子。没看全,也不好评价,就说一点吧,这剧拍的太现代了,还有那么现代的枪。。 再次道歉,误入莫怪~~


小米手机AlarmManager失效的问题

问题描述

当我们需要周期性执行某操作时,就会用到AlarmManager,但是在小米的手机上(严格的说应该是小米Rom)执行周期太短的话,一旦系统休眠,AlarmManager就会失效。搜索结果来看,这个问题很普遍。发现是周期不能短于5分钟,否则不会唤醒系统。

解决方案

这个问题主要是因为我们大多数人使用了type=AlarmManager.RTC_WAKEUP,希望系统休眠后到达指定时间唤醒设备执行操作,而且周期短于5分钟。小米Rom的考虑节能省电,一旦系统休眠,不会频繁唤醒系统。

Continue reading ↦

个人知识管理

每个人都应该有自己的知识仓库 最开始是我的一个大学老师说:你们每个人都应该有自己的代码仓库。当时的语境来说是指代码仓库,其实每个人都应该有自己的知识仓库。 收集癖 在有仓库意识之前其实已经在在做这样的事情了,只不过收集的工具软件和一些方法技巧,癖好很重那种。。对于有收集癖的我来说,个人知识仓库刚好是满足癖好啦 胡扯 以前喜欢把学到的东西以及遇到的问题一股脑的贴在博客里,不过有多少人写过,遇到的问题显得自己多么愚蠢。总之写了很多东西。现在想想还是挺替以前的自己欣慰的,真敢写啊。。 现在积累的东西也不少,感觉可以写的东西也蛮多。要么觉得很多人已经写了,没什么技术含量;要么觉得得沉淀思考下,写出别人能看懂的内容。总之,现在是怕前怕后。 解决办法: 关于很多人写过的,力争写出点深刻的,对别人有帮助的东西,如果是照搬别人的,不如不写(放在知识仓库里吧)。而对于很多想写的东西最终没有写成的,对自己要严格一些,多思考沉淀,然后润色发布,润色也是必须的技能,写出人类能看懂的文章。 可以写完立刻发布,然后以后有新想法,或者觉得哪里不好了再随时更新,就像写程序似的。 如何建立知识仓库 适合自己的方法或者工具,工欲善其事,必先利其器嘛。 坚持更新,原始积累,可以是不加思考的保存 定期整理,思考知识管理知识的过程 沉淀升华,写出有自己见解或者有意义的东西,然后发布博客 工具只是在外的管理,知识的固化,而大脑对知识的管理才是最终目的。所以一定要有整理沉淀的过程,才能真正称为自己的知识。当然有些东西只要在脑子里有个索引,便于查找就够了。 关于工具,在开始找适合自己的时候可以尝试,但为了后期工具的切换和便捷,一定要保证几个基本点: 可以很方便的导入导出 注意文档编码 最好管理工具能够跨平台


QQ的诡异bug

标题党一次~~,也不能完全算是QQ的bug。

bug初现

一打开qq,首页没问题,每当进入二级页面,就会退出程序;开始以为是qq异常了,重试结果依旧;连接电脑打印log,没有发现任何异常信息。

卸载了一个权限管理的app,卸载qq重新安装都无法解决;想着只能晚些卸载了,安装旧版qq试试了。

bug再现

晚上睡觉前打开微信查看完公众帐号的信息,然后点击设置里的一些选项,同样进入二级页面,返回后微信的表现是每次都像刚刚打开时一样,”微信“tab是打开的。想到qq的bug,对比可以发现微信的表现还是不错的,至少保证程序正常了,只是”逻辑异常“。再想到开发中的app返回首页时的异常,好像记起了什么。。

bug再见

前几天手机没有锁屏放入口袋,等再拿出来的时候,屏幕闪烁,然后显示各种参数。手机的好多开发人员选项被“自动”打开了:

  1. 屏幕闪烁:显示屏幕更新-屏幕上的区域更新时闪烁相应区域
  2. 显示参数:显示CPU使用情况-屏幕叠加层显示当前CPU使用情况

当时关闭这2个选项以后,一切“看起来”正常了。而以上这种bug应该就是由于一个开发人员选项造成的:

开发人员选项–不保留活动–用户离开即销毁每个活动。

页面一旦离开就销毁了,关闭此选项,问题解决。

Continue reading ↦

View Tag相关

View的tag方法可以让View附带很多信息,方便使用。最常用的一个例子:在Adapter中我们经常用到View的setTag()和getTag()方法,从而使用ViewHolder来提高效率。

问题1:当我们需要添加多个tag时该怎么做呢?

View还有一个setTag(int key, final Object tag)方法,想添加多少tag都行。

问题2:直接调用方法View.setTag(1,"msg"),出现异常:

java.lang.IllegalArgumentException: The key must be an application-specific resource id.

异常信息的意思是说:key必须是特定的资源id。

最直接的方法就是在资源文件中添加一条记录:

<item type="id" name="tag_first"></item>

可以添加到res/values/strings.xml或者res/values/ids.xml中,然后调用View.setTag(R.id.tag_first,"msg")即可。

知道解决方法了,再来找一下原因。以下是View中相关源码:

Continue reading ↦

Android数据库事务处理

在数据库开发中,事务处理是非常重要的。

首先Android数据库操作(特别是写操作)是非常慢的,将所有操作打包成一个事务能大大提高处理速度。

其次是保证数据的一致性,一个事务中的所有操作可以看作一个原子操作,成功或者失败。如果全部成功,则事务提交完成;而事务内部如果有失败操作,整个事务操作会回滚,从而保证数据的一致性。

Android中事务的调用:

try {
	db.beginTransaction();
      	//在这里执行多个数据库操作
      	//执行过程中可能会抛出异常
        	db.setTransactionSuccessful();
      	//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作
    } catch (Exception e){

    } finally {
	//当所有操作执行完成后结束一个事务
	db.endTransaction();
    }

有2点需要注意的是:

  1. 一定要调用db.setTransactionSuccessful();事务才会成功提交完成
  2. 事务是可以嵌套的

以上2点也是自己开发中犯错了才觉察到的:没有调用db.setTransactionSuccessful();发现数据没有插入;想当然的认为事务不可以嵌套。而Android的源码中也很清楚的说明了这2点,所以究其根本原因是对事务处理不够熟悉,对Android中事务的处理不熟悉。在此记录警示自己!

以下贴出Android中相关连的源代码,来自android.database.sqlite.SQLiteDatabase:

Continue reading ↦

LayoutInflater丢失View的LayoutParams

View view = inflater.inflate(R.layout.item, null);

在使用类似以上方法获取view时会遇到的一个问题就是布局文件中定义的LayoutParams被忽略了。以下三个stackoverflow问题就是这样:

http://stackoverflow.com/questions/5288435/layout-params-of-loaded-view-are-ignored

http://stackoverflow.com/questions/5026926/making-sense-of-layoutinflater

http://stackoverflow.com/questions/2738670/layoutinflater-ignoring-parameters

都说这样使用就可以了:

View view = inflater.inflate( R.layout.item /* resource id */, parent /* parent */,false /*attachToRoot*/);

至此问题已经解决了,但是三个问题都没有提到为什么要这样调用才行。

感兴趣的我们到源码里来找答案,LayoutInflater的inflate方法,最后都是调用的同一个方法:

public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

原因自然在这个方法里,大概意思就是只有ViewGroup root不为空才会读取View的LayoutParams。attachToRoot = true的时候,会把View添加到root中。而大多情况不希望被addView到root中,自然要赋值为flase,这样就是上面的解决方案了。

可以参看LayoutInflater的inflate方法相关的源码:

Continue reading ↦