Launcher3 的布局和结构

于 2014年03月21日 发布在 android开发 43 条评论 »

(系列文章点这里)

首先你需要去 这里 下载下Launcher3的源码。这个是我从android源码里面拿出来的,修改删掉了一些东西,方便在eclipse上运行,你可以直接在手机上运行,有了代码和apk再来看说明,心理会很踏实的。

Launcher3其实最主要的是一个Activity,基本上所有的操作都集中在这个Activity上,在Launcher.java 当中,setContentView的参数是R.layout.launcher,我们暂时只研究下桌面竖屏的情况,相关源码在res/layout-port/launcher.xml。

请左手拿着你运行着launcher3的手机,右手打开launcher.xml,布局的最外面是一个FrameLayout,紧紧地包围了一个叫DragLayer的ViewGroup,他继承自FrameLayout,主要功能就是处理拖拽事件,当你在拖拽一个图标的时候,就是一个view放到了DragLayer里面,跟随你的手在移动。

下面在你的手机屏幕上左右滑,有好几屏,这个能滑的东西叫做Workspace,在布局文件里面可以看到的,Workspace能算是Launcher3代码里代码量前三的吧,他的父类的父类是PagedView,一个用来处理左右滑动的ViewGroup。那么Workspace里面可以滑动的单独一屏叫什么呢? 布局文件里面似乎没有写,其实是CellLayout,他负责的是图标和小部件的显示和整齐摆放。

接下来看你在滑动屏幕的时候看见下方有个指示器,告诉你桌面现在有几屏,当前是在哪一屏上。这个东西叫做PageIndicator,从名字就可以看出意义了。还有最下面的4个固定不动的图标,和中间一个Button显示所有应用,这整个叫做Hotseat,用来放置比较常用的应用,比如拨号,短信,相机等等。
阅读全文 »

如何用Discourse搭建一个论坛

于 2014年03月21日 发布在 linux应用 4 条评论 »

Discourse是基于ruby on rails,Ember.js, PostgreSQL 和Redis的开源论坛,是由StackOverflow的联合创始人Jeff Atwood发起的,目的是成为下一代论坛,改变传统论坛的格局,成为论坛界的wordpress。

先说下我的使用感受吧,在try.discourse.org上可以体验的,首先是界面比较清爽,主体是白色的,很简洁。其次是摒弃了“板块”的概念,所有的帖子集中显示,用滚轮一直往下滑好了。然后是发帖和回复都十分方便,直接在当前页都可以完成,内容的编辑支持Markdown和BBCode,编辑的时候还可以在右侧直接预览,插入图片很方便,在网上看到一张图片之后可以右键复制图片,直接Ctrl+V就可以在编辑器内插入图片了,Discourse会自动完成复制并且上传到服务器上。

之前很早就用过Discuz!,但是这个论坛在国内用的实在是太普遍了,很多论坛的长的都是一个样子的。我感觉他最大的缺点是帖子中的每个回复都占用的很大的空间,在回复内容普遍很短的情况下,我每看一行回复都要滚动半个屏幕,这个最不能忍(哦对,还有坑爹的签名图片  = =)。Discourse做的比较合我胃口,一个回复的高度只有Discuz!的三分之一左右。

来说说安装吧,首先你要有个VPS或者云主机,可以使用阿里云,linode或者digitalocean等等,推荐内存是1G。

我安装的时候参照的是这篇文档 ,这个地方是以digital ocean为例来说明的,其他主机都大同小异。部署的时候需要用到docker,这个是个比较火的容器引擎,目前我还没有完全理解容器引擎到底指的是什么,“他可以打包引用和其依赖到linux上,实现虚拟化”,就当是个虚拟机好了恩。我选的是系统是Ubuntu 12.04.3 x64 LTS,按照文档上的教程升级了内核,我没有验证这一步是否是必要的,但是感觉虚拟化可能需要升级内核的东西,做了也无妨。

接下来是clone官方的docker镜像,修改配置文件app.yml,配置文件里面有几个需要注意的事情。ssh-key要设置,就是你从~/.ssh/id_rsa.pub拷贝到github上的那个东西,否则你没办法通过./launcher ssh app进入你的“虚拟机”。还有需要填写的是email地址和网站的host。邮箱相关的内容可能需要稍微折腾一点,我直接用的是mailgun的服务,maildraill貌似不让天朝的同学用,囧。。app.xml中邮箱配置的内容怎么填,mailgun里面都写的很清楚了,而且也说明了怎么在域名服务商那里添加邮件相关的记录。如果你嫌邮箱配置麻烦的话,就先略过吧。

最后执行./launcher bootstrap app和./launcher start app就可以让网站运行了。后续的折腾就是测试邮件是否配置成功,添加github,facebook,twitter的第三方登录功能了。如果你访问的时候出现了502错误,请检查你的内存是否只有512MB,内存小的话很容易出现这样的问题,出现这个问题的时候我一直搞不清楚哪里有问题,一直怀疑是配置错误,后来升级了内存之后就完全正常了。

还有一些缺点,由于网站很依赖javascript,SEO会比较差。其次中文本地化还不够完全,给官方提交什么的貌似比较麻烦。刚开始用,缺点应该还有很多没发现,不过看提交记录貌似挺频繁的,希望能越来越好。

我搭建了个论坛,域名是  http://android.hacking.today , 不过目前还不知道怎么搞。。当你搭建论坛的时候一定要想清楚到底该怎么搞,毕竟内容才是重点,用什么样的论坛不是最重要的。。

android触摸事件处理流程

于 2014年03月15日 发布在 android开发 14 条评论 »

(系列文章点这里)

最近在工作中,经常需要处理触摸事件,但是有时候会出现一些奇怪的bug,比如有时候会检测不到ACTION_MOVE和ACTION_UP,我决定下决心写个测试的小程序,来研究一个触摸事件从上往下是怎么传递和处理的。

先说下大概的流程吧,这个应该在很多博客中都有讲解:当一个事件来临的时候,会先传递给最外层的ViewGroup(比如LinearLayout,FrameLayout),如果这个ViewGroup没有去拦截这个事件的话,才会给传递给下层的ViewGroup或者View。如果被拦截掉的话,它会自己去处理这个事件,这个ViewGroup内的View将无法得知上层发生了什么。

ViewGroup的拦截事件的函数为

public boolean onInterceptTouchEvent(MotionEvent ev)

onInterceptTouchEvent的参数ev就是一个触摸事件,可以从ev获取到事件的坐标,类型,当前屏幕上点的个数等等。通常我们在继承ViewGroup的时候都会重写这个方法,判断目前需不需要拦截,即返回true还是false。返回true的时候表明事件不再往下传了,否则就往下传。那返回true的时候怎么处理呢?
阅读全文 »

在技术方面,我真是什么都想学

于 2014年03月3日 发布在 吐槽 10 条评论 »

我发现我现在对各种技术都非常感兴趣,记得之前在学校的时候,大部分时间实在搞算法,用的c、c++等,对于java有着很强烈的抵触情绪,工作了之后,我的工作内容是android开发,用的是java语言,后来感觉还行,用的时间长了就发现他没有我当初想象的那么恶心。

下班或者周末的时候我有时候会逛逛coursera,业余时间完成了Andrew Ng的机器学习课程,前两天又完成了一门android课程。年初的时候,我又迷上了codeschool,上面的课程质量非常不错,看了很多javascript的课程(尤其讲解jQuery的course),一下子让我对前端开发又有了兴趣,大二时候搞这些时候真是头疼死了。最近又看了ruby on rails的视频,大概清楚了rails开发到底是什么样子的,跃跃欲试想搞点东西出来。无聊之中在kindle下了objective-c的书,看完发现iOS开发也挺有意思的。哎,,不知道我下一个喜欢的是什么东西。

到这里肯定有人要说,搞东西要专一,学这么多东西肯定都是附在表面的。我也知道,不过工作的内容真的是让我整天提不起兴趣,每天回去之后要敲一两个小时非工作代码心情才能舒缓过来。加之互联网的世界这么精彩,只蜷缩于一个小的舒适区里真的不方便拓宽眼界。

其实我设想我将来一定会成为一个独立开发者,这样必定需要很强的全栈技能,现在多学一点万一以后用上呢。目前我的困惑是,如何用我所学的技能做出一个产品出来,脑子里现在有些小点子,不过需要很长的时间来实现。

如果按照现在这样一直996的节奏,我会被云OS操得不轻的,好累。

 

几个在线教育网站的使用感受

于 2014年01月12日 发布在 算法&&ACM 2 条评论 »

最近经常使用的在线教育站点有Coursera,CodeSchoolCodeCademy

先说下Coursera,这个应该是知名度最高的,覆盖了很多学科。教课的形式跟大学差不多,一般是每周放出几段视频(每段十几二十分钟)和课后作业,课后作业各种形式的都有:问答的,提交程序代码在线测评的,同学之间相互测评的等等。今年以来,Coursera对中文的支持提高了很多,第一次访问Coursera的界面都是中文的比较友好,另外中文教学课程也逐渐丰富,典型的比如国立台湾大学的《機器學習基石》、《機率》,上交的《数学之旅》、《社会与法》,北大的《计算概论A》、《人群与网络》等等等等。当完成一项课程合格之后,大多数会提供一份Statement of Accomplishment, 就是pdf版的证书。Coursera还有一项收费服务Signature Track,提交作业时会有让用户打一段文字并会拍摄头像识别是不是本人,如果成功完成课程会有学校官方认可的证书发放,可以放到简历或者LinkedIn上。不过在国内这种环境下貌似意义不大,唯一有意义的是催促你按时完成课程,毕竟一份Signature Track要四五十刀,不过了就可惜了。在Coursera上混了一年多,只完完整整学完了两门课,一门是创始人Andrew Ng的《Machine Learning》,另一门是仅有四周的《Computing for Data Analysis》,主要原因是太贪了,有时候同时进行十几门,哪能学好呢。我现在老实了,在一个时间段只学习一门课程,现在正在跟的是UIUC的Android课程,并且注册了Signature Track,希望能认真完成,然后再去找其他感兴趣的东西。

推荐课程:
阅读全文 »

Android 4.4 Launcher3桌面源码分析

于 2013年12月22日 发布在 android开发 5 条评论 »

由于工作的原因,对Android的桌面有了一些了解。之前一段时间对桌面的构成十分模糊,最近看代码该代码发现渐渐有了感觉,所以准备写一系列分析安卓桌面的文章。

市面上有很多桌面产品,比如91桌面,go桌面,小米桌面等等,虽说千差万别,但都完成了桌面的基本任务,比如说组织图标,拖动图标,滑动页面,显示小工具等等功能。桌面跟其他Android App很大的不同是,他只有一个Activity,但是这个Activity却十分复杂,用几个自定义View把Android的触摸事件的处理玩儿的眼花缭乱,没有长时间的折腾是很难熟悉的。
阅读全文 »

又是一年校招时

于 2013年10月10日 发布在 吐槽, 算法&&ACM 27 条评论 »

这两天刷微博,发现去年关注的很多校园招聘的账号又开始浮出水面了,各个公司都开始造势,吸引优秀的应届毕业生。与此同时,千千万万蛋子们浏览心仪公司的招聘页面,计划着行程,希望能找到个好工作。想起去年这个时候,我在郑州、武汉和西安之间折腾了几个月,为工作奔波,中间还生了场小病,不过还好,结局是美好的,从实习到现在已经工作了半年了,感觉还算可以,最近工作不是很忙,详细回忆下我找工作的历程。

找工作的构想是从大三区域赛结束之后开始的,那时,北京站凑合拿了个铜牌倒数第一,成都站打铁(实在是弱爆了),不过好歹有个牌牌能为简历加点分。当时没有项目经验,都在学校里面闷头学算法了,想学点实际可以用到的,当时跟同学谈论了一下linux系统编程的东东,后来就打算以这个为切入点,那时的确感觉挺高端的,况且大型的互联公司都会用到这些东西,所以暑假就将所有时间投入到了这个上面。我看的入门书是《linux程序设计》,过年时候除了年前年后的几天,基本上泡在图书馆,把书上重要章节的代码都敲了敲,这样,才算是对linux编程有了一定了解。
阅读全文 »

最长上升子序列nlogn算法

于 2013年08月22日 发布在 算法&&ACM 6 条评论 »

以前搞算法的时候看到过这个算法,但是没有仔细钻研过,似懂非懂,这两天看了看,总算是搞明白了。

问题的背景我就不多说了,相信通过搜索引擎来到这里的都是为了寻求简单易懂的nlogn的答案。

这个算法dp的状态有点诡异:

dp[i] = 长度为i+1的上升子序列中末尾元素的最小值(没有某个长度的上升自序列的话相应位置是无穷大)

初看有点不太明白,为什么是末尾的最小值呢?为什么可以求出最长的公共子序列呢?为什么可以到nlogn呢?别急,我慢慢说。

首先,当这个算法执行完毕的时候,dp数组中的每一个都符合我们定义的状态,每个长度的上升子序列末尾最小值都有了。那么我们看看含有末尾最小值的最大的位置是什么就能找到问题的解了。

其次,我们怎么去进行状态的推算和更新?其实,这个算法已经是优化过的算法,搞的人都不清楚他要干啥了。这个算法的原始版本其实还有一维(详见PSS),如果我们知道N个元素组成的dp数组,那么如果这时候又来了一个元素怎么办?dp数组能很快更新么?必须是可以的。只要新来的元素比dp数组中的某个位置j上的元素大就可以了,那么新来的元素就可以更新dp[j]了,具体是if(dp[j-1]<new)     dp[j] = min(dp[j],new),奉上代码:

for( int i = 0; i < n; i++ ){// index for arrays
    for( int j = 0; j < n; j++ )// index for dp
        if( j == 0 || (dp[j-1] < a[i] && a[i] < dp[j] ) )
            dp[j] = a[i];
}

上面简单的代码有个奇特的性质,就是每次循环完dp是单调递增的(除了无穷大),为什么呢,假如dp[3]>dp[5],长度为5的上升子序列的最后一位最小值竟然比长度为3的末尾最小值小,那我们拿长度为5的上升自序列的后面三个数更新dp[3]不就行了?

最后还有个性质,从上面代码的if语句中可以看出,因为dp是递增的,所以a[i]最多也就更新一次。不妨用二分找出更新的位置,然后复杂度就降到nlogn,你说优美不?

贴上《挑战程序设计竞赛》,65页的代码,大家好好品味

int dp[MAX_N];

void solve{
    fill( dp, dp + n, INF );
    for( int i = 0; i < n; i++ )
        *lower_bound( dp, dp + n, a[i] ) = a[i];
    printf("%d\n", lower_bound(dp,dp+n,INF) - dp );
}

什么?没看懂?再看一遍吧。。

PS:以上代码未经验证
PSS:原始算法什么的是我想出来的,为了使思维过程更清晰一点,具体有没有就不知道了
PSSS:有人知道最长不下降自序列可以用nlogn的算法解么?

HTTP协议漫谈:概述

于 2012年09月15日 发布在 linux应用 6 条评论 »

自从学习linux编程以来,一直对与服务器的工作原理十分感兴趣,想写一个,然而暑假由于各种原因耽搁了下来,前几天是课程设计,大概两周时间,我就趁这个时间,简单实现了一下。又恰逢《HTTP权威指南》出版,入手了一本,大概翻了一遍,对于HTTP的细节了解了很多,收获还是很大的。我简单总结一下,巩固知识&&方便以后查看。

HTTP,超文本传输协议,是使用非常广泛的网络协议,我们平时上网看新闻,刷微博都要依靠下面的http协议来传递信息。要传递信息,首先需要客户端发起连接,客户端和服务器建立链接之后,发送HTTP请求报文,服务器接受请求之后返回给客户端一个响应报文。请求和响应都是固定文本格式的,在协议中有明确的定义,之后会详解。HTTP底层是通过TCP进行通讯的,不过我们不必关心TCP的具体细节,只需要知道他提供可靠连接,并且在请求和响应完成后关闭连接(持久链接中有多次请求和响应)。

HTTP的请求可以有好几种,最常见的是GET请求(还有POST,HEAD等),他会向服务器请求资源(即“get”资源),同时会给一个资源的地址,这些东西放在请求报文的开头第一行,我们把这一行称为起始行。

GET /index.html HTTP/1.1\r\n

阅读全文 »

编程珠玑 第四章 习题解答

于 2012年07月8日 发布在 算法&&ACM 4 条评论 »

1.为了保证范围不超过范围,我们需要在初始化的时候,让变量不超出范围。这样每次循环得到的新的范围是慢慢缩小的,不会越界。

2.迭代的二分查找。

int bs( int *a, int l, int r, int v ){
	while( l <= r ){
		if( a[l] == v ) return l;
		int mid = (l+r)/2;
		if( a[mid] < v ) l = mid+1;
		if( a[mid] == v )r = mid;
		if( a[mid] > v ) r = mid-1;
	}
	return -1;
}

这个二分可以返回所需要查询的元素第一次出现的位置,如果不存在,则返回-1.在每个循环内,我们假定元素第一次出现的范围是闭区间[l,r]内,当循环体内语句执行完之后,我们得到了一个新的区间。新的区间的范围是一直在收敛的(不会存在r,l执行完循环之后大小没有变化。),所以程序可以终止,得到正确结果。

3.将2的二分程序改写成递归的形式。

int bss( int *a, int l, int r, int v ){
	if( l > r ) return -1;
	if( a[l] == v ) return l;
	int mid = (l+r)/2;
	if( a[mid] < v ) return bss( a, mid+1, r, v );
	if( a[mid] == v )return bss( a, l, mid, v );
	if( a[mid] > v ) return bss( a, l, mid-1, v );
}

阅读全文 »

第 3 页,共 10 页12345...10...最旧 »