2013年9月-忙,真忙,累,真累

9月甚是忙碌,太多事情、工作需要处理,以至于10月初的国庆节也没有办法腾出时间写一下9月的流水帐。

照顾家人是这个月的主题,工作和其他事情都暂时放一边了。没什么比家人的健康更重要的了,更好的工作,更高的报酬,也只是为了让家人过得更好一点而已。

因为以上的原因,工作耽误了,恰好公司又进入产品开发的繁忙期,所以国庆都是在照顾家人和工作中度过。压力稍大,幸好事情都在向好的方面发展,家人的身体在我的照顾下慢慢恢复,而工作任务的核心功能也完成了大体的框架,心情可以稍微放松。

9月在忙碌,焦虑,压抑中度过,感觉生活中的麻烦事总是一件一件接踵而来,而且一环扣一环,但好歹事情在一步一步的好转。最近总是在念叨一句话:“人无远虑,必有近忧”。也许,应该好好计划将来的生活,让生活更加有条理,更加顺利。

学习方面,对UML有了初步的认识,接下来就是深入理解。UML软件准备从 national rose 转向 enterprise architect,前者是一代经典,但是最新的版本停留在 2003 版,功能老旧,而且有些地方很不人性化,后者是现在的主流推荐的软件,功能强大,使用了一下,正向、逆向工程都甚是强大,要好好掌握。另外随着工作对 java 的接触越来越多,感觉要系统地学习一下 java 了,初步打算好好看看入门书籍,再看看 effective java 这本传说中的经典。

android.graphics.Path 的序列化

序列化 (Serialization) 的相关知识可以参考相关的百科,这里只要是学习 android.graphics.Path 的序列化。

工作中有需求要保存绘制的 paths, 这个时候就需要用到对象的序列化的功能,但是 Android 上没有对 Path 做序列化的工作,所以只能自己进行序列化了。

Path 类序列化的原理就是通过将 path 绘制的每一个点都保存下来,需要还原的时候就进行反序列化,再通过这些保存的点重新绘制 path。

实例1:

继承 android.graphics.Path 类,重写 moveTo, lineTo 等方法,记录下 path 绘制的每一点的坐标数据;反序列化的时候调用 “drawThisPath” 重绘 path。

相关代码:

public class CustomPath extends Path implements Serializable {

private static final long serialVersionUID = -5974912367682897467L;

private ArrayList<PathAction> actions = new ArrayList<CustomPath.PathAction>();

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    in.defaultReadObject();
    drawThisPath();
}

@Override
public void moveTo(float x, float y) {
    actions.add(new ActionMove(x, y));
    super.moveTo(x, y);
}

@Override
public void lineTo(float x, float y){
    actions.add(new ActionLine(x, y));
    super.lineTo(x, y);
}

private void drawThisPath(){
    for(PathAction p : actions){
        if(p.getType().equals(PathActionType.MOVE_TO)){
            super.moveTo(p.getX(), p.getY());
        } else if(p.getType().equals(PathActionType.LINE_TO)){
            super.lineTo(p.getX(), p.getY());
        }
    }
}

public interface PathAction {
    public enum PathActionType {LINE_TO,MOVE_TO};
    public PathActionType getType();
    public float getX();
    public float getY();
}

public class ActionMove implements PathAction, Serializable{
    private static final long serialVersionUID = -7198142191254133295L;

    private float x,y;

    public ActionMove(float x, float y){
        this.x = x;
        this.y = y;
    }

    @Override
    public PathActionType getType() {
        return PathActionType.MOVE_TO;
    }

    @Override
    public float getX() {
        return x;
    }

    @Override
    public float getY() {
        return y;
    }

}

public class ActionLine implements PathAction, Serializable{
    private static final long serialVersionUID = 8307137961494172589L;

    private float x,y;

    public ActionLine(float x, float y){
        this.x = x;
        this.y = y;
    }

    @Override
    public PathActionType getType() {
        return PathActionType.LINE_TO;
    }

    @Override
    public float getX() {
        return x;
    }

    @Override
    public float getY() {
        return y;
    }

}
}

实例2:

创建 PathInfo 类,方法 lineStart, lineMove, lineEnd 专门用来保存 path 绘制的每一个点的坐标数据;反序列化的时候重绘 path。原理跟实例1差不多。

源码下载

在 stackoverflow 回答问题,被外国友人吐槽语法

在 stackoverflow 上回答了一个关于 FileLock 在 Android 上的用法的问题,尽管我已经有所注意,而且只是简单的几句话,没想到还是出现了语法问题。被外国友人吐槽语法,无地自容啊。

语法知识都还给英语老师了。本来以为自己虽然是哑巴英语,但是好歹能读能写,现在写也成问题了。学习一门语言,周围环境真的很重要,平时学了多少单词,多少语法,实际上找个实践的机会都没有。工作生活都是用普通话,我现在讲广东话都有点生疏了。

不说了,上图纪念。好好学习英语,积极实践,错得越多,学得越多。

如图,红色是被修正的错误:

grammer-error

Android adb offline 的解决方案

之前在 Android adb 网络连接 中总结了一次 adb 的网络连接,而最近工作中遇到 Android 设备连接 adb 的时候出现 offline 的提示,无法正常连接上设备,这个情况应该如何解决呢?

这里总结一下解决方案:

  1. 重新插拔 USB 线
  2. 换一个 USB 口,有些 PC 的 USB 口不都是一样的;或者换一根 USB 线,低质量的 USB 线缆可能会引起这个问题
  3. 取消 adb 调试模式,再重新勾选
  4. 在 eclipse 的 DDMS 模式下点击 “reset adb”
  5. 在 PC 端重启 adb。adb kill-server 然后 adb start-server
  6. 重启 PC手机,不行的话再试几次
  7. 升级 android SDK,对于开发者来说,一般都是系统与 adb 工具版本不一致引起的。例如我的 Nexus 7 升级到 Android 4.3之后,只能通过升级 Android SDK 来解决这个问题
  8. 将xx手机助手之类的相关进程杀掉就正常了(感谢“梁c”的补充)。xx助手之类的也会将 adb 进程锁定,导致无法正常连接 adb.

如果这个能帮到你,请留言告诉我。

亚冠-恒大4-1逆转柏太阳神

4-1 的大胜,欢畅淋漓的大胜。

战报统计:
9月25日18点,2013年亚冠联赛半决赛首回合的焦点大战,在日本千叶县柏市太阳神球场展开争夺,广州恒大客场挑战柏太阳神。经过90分钟的激战,广州恒大在上半场落后的情况下,下半场实现绝地大反击,以4-1逆转获胜,几乎铁定进入决赛。第10分钟,瓦格纳诡异任意球直接破门;第23分钟,穆里奇门前混战击中立柱;第58分钟,穆里奇接孙祥传中怒射扳平;第67分钟,孔卡禁区外远射打入出世界波;第82分钟,孔卡角球直接得分;补时阶段,穆里奇梅开二度。双方次回合比赛于10月2日20点,在广州天河体育场进行。

继续阅读亚冠-恒大4-1逆转柏太阳神

Google Quickoffice 对 Android 和 iOS 用户免费, 提供多达 15GB 的免费存储空間

quickoffice-header 

Goolge 在2012年收购了 Quickoffice,随后在各个平台推出了折扣优惠。但是今天,Google 决定免费到底,集成了 Google Drive 的 Quickoffice 免费开发给所有的 Android 和 iOS 用户。

赶紧下载:Google Play 安装

Quickoffice 新版变化:

  • 现在起,只要您有 Google 帐户,就能免费使用 Quickoffice。
    新版的 Quickoffice 具有以下特色:
    – 支持手机和平板电脑
    – 与 Google Drive 的整合度更高 (提供多达 15GB 的免费存储空間)
    – 全新的应用程序图标

quickofficeandroid

Quickoffice 相比 Google Docs 有更好的文档编辑功能,并与微软的 Office 套件全兼容,包括 Word,Excel 和 Powerpoint。

据悉9月26日前登录 Google 帐号还可以获取额外的 10GB Google Drive 空间,两年的使用期限,有点 百度1T云盘 的感觉,不过不少用户(包括我自己)反映并没有收的额外的 10GB 空间。但是,15GB 空间已经够够够用了。

目前人们更多的是在电脑端编辑文档,手机端浏览文档。尽管手机用户并非迫切需要这样的一个工具去修改文档,但是这的确是一件好事,它给用户提供了便利。同时 Quickoffice 支持 PDF 的浏览,用户不再需要额外下载 PDF 应用了。对于那些需要对自己的文档随时随地编辑的商务人士来说,与 Google Drive 高度整合的 Quickoffice 是一个很有用的工具。

平板用户可能会更受益于新的用户界面。应用提供了更为直观的分栏设计,创建和编辑文档更加轻松。

唯一的问题是用户是否放心把所有的文档都交给 Google,如果你对这个应用有任何看法和任何隐私担忧,请在留言中告诉我。
当然,对于国内用户来说,神经性断网的因素也是不得不考虑的。


2013.10.04更新:今天突然发现,Google drive 的空间由 15G 变成 25G 了,喜剧了。

恒大亚冠四强之路

忘记什么时候变成恒大的球迷了,上次追着看比赛还是米卢时代,感谢恒大给我重新带来足球的快乐。

战报统计:
2013亚冠联赛1/4决赛已经全面战罢,广州恒大令人信服的两回合6-1轻松淘汰卡塔尔球队莱赫维亚,10场比赛打进25球,攻击火力威震亚洲足坛。本期《胜利时光机》就一起回顾下本赛季广州恒大的四强晋级之路。

恒大亚冠四强之路 10场25球斩西亚狼灭日韩

继续阅读恒大亚冠四强之路

2013年8月-这博客对我来说很重要

00_feature_life_0转眼间,八月已经过去。光阴似箭,岁月如梭啊。。。对于我来说,8月是忙碌,充实的。

首先,我重新建立了我的博客。我想我还是需要一个地方去表达我的情感,去展示我的成就,去分享我的快乐,去释放我的压抑,去锻炼我的思维表达,去推动我的前进。是的,这博客的确是一个对我来说很重要的地方。这个是我自己的地方,不是新浪的,不是腾讯的,不是谷歌的,也不是百度的,这个就是我的,我自己的域名,我自己的空间。

其次,生活的压力越来越大了。深圳的消费水平已经令我有点吃不消了,房东还给我了一个惊喜,下个月加房租。1600RMB每月、一房一厅、农民房,真的很贵,但是在深圳蔡屋围,这个已经算是便宜的了。真想拥有自己的房子,不知何年何月何日能得偿所愿~~~

工作方面,这个月没有明确的目标,所以把自己淹没在各种各样的新闻资讯里面了。信息过剩,时间碎片化的时代,很容易及迷失在网络资讯中,这个坏习惯要认真对待了。
本月下旬,决定学习UML,unified model language, 统一建模语言,可以帮助深入了解系统的真实需求、构建系统蓝图框架、高效开发,所以要好好学习学习。OOA、OOD、UML都是有意思的新知识,我必须掌握它,等下个月的这个时候,让我再来评估一下我的进展。

Android Path 类运用实践

理论学习了 Android Path 类之后,对 Path 类的属性方法都有所了解,写两个例子实践一下。理论与实践结合嘛。

实例1,五环 + 文字:

useesee

源码:

package com.example.pathstudy;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.View;

public class PathStudyActivity extends Activity {

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(new PathStudyView(getApplicationContext()));
	}

	private class PathStudyView extends View {

		public PathStudyView(Context context) {
			super(context);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onDraw(Canvas canvas) {
			// TODO Auto-generated method stub
			// super.onDraw(canvas);
			canvas.drawColor(Color.WHITE);
			Paint mPaint = new Paint();
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setStrokeWidth(20);

			int originX = 0;
			int originY = 0;
			int offsetX = 0;
			int offsetY = 0;
			int offsetLengthX = 240;
			int offsetLengthY = 110;

			float circleX = 150;
			float circleY = 200;
			float radius = 100;

			// first circle
			mPaint.setColor(Color.BLUE);
			Path mPath = new Path();
			mPath.addPath(getDrawCirclePath(circleX, circleY, radius));
			canvas.drawPath(mPath, mPaint);

			// second circle
			mPaint.setColor(Color.BLACK);
			canvas.save();
			offsetX = originX + offsetLengthX;
			canvas.translate(offsetX, offsetY);
			mPath.reset();
			mPath.addPath(getDrawCirclePath(circleX, circleY, radius));
			canvas.drawPath(mPath, mPaint);
			canvas.restore();

			// thid circle
			mPaint.setColor(Color.RED);
			canvas.save();
			offsetX += offsetLengthX;
			canvas.translate(offsetX, offsetY);
			mPath.reset();
			mPath.addPath(getDrawCirclePath(circleX, circleY, radius));
			canvas.drawPath(mPath, mPaint);
			canvas.restore();

			// forth circle
			mPaint.setColor(Color.YELLOW);
			canvas.save();
			offsetX = originX + offsetLengthX / 2;
			offsetY = originY + offsetLengthY;
			canvas.translate(offsetX, offsetY);
			mPath.reset();
			mPath.addPath(getDrawCirclePath(circleX, circleY, radius));
			canvas.drawPath(mPath, mPaint);
			canvas.restore();

			// fifth circle
			mPaint.setColor(Color.GREEN);
			canvas.save();
			offsetX += offsetLengthX;
			canvas.translate(offsetX, offsetY);
			mPath.reset();
			mPath.addPath(getDrawCirclePath(circleX, circleY, radius));
			canvas.drawPath(mPath, mPaint);
			canvas.restore();

			// draw text kevinems.com
			// fifth circle
			mPaint.setColor(Color.BLACK);
			mPaint.setStyle(Paint.Style.FILL);
			mPaint.setTextSize(100);
			mPaint.setStrokeWidth(5);
			String websiteStr = "kevinems.com";
			canvas.drawText(websiteStr, 110, 500, mPaint);
			canvas.restore();

		}

		private Path getDrawCirclePath(float x, float y, float radius) {
			Path mPath = new Path();
			mPath.setFillType(Path.FillType.EVEN_ODD);
			mPath.addCircle(x, y, radius, Path.Direction.CCW);
			return mPath;
		}
	}
}

实例2,可以随意绘画 path 的手写板:

paint-pad

源码:

package com.example.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class PathView extends View {
	private static final String LOG_TAG = "PathView";
	private Path mPath;
	private Paint mPaint;
	private float mPosX;
	private float mPosY;

	public PathView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}

	private void init() {
		// TODO Auto-generated method stub
		mPath = new Path();
		mPaint = new Paint();

		mPaint.setColor(Color.GREEN);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(5);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		// super.onDraw(canvas);
		Log.i(LOG_TAG, "onDraw");
		canvas.drawColor(Color.WHITE);
		canvas.drawPath(mPath, mPaint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		// return super.onTouchEvent(event);
		int action = event.getAction();
		float x = event.getX();
		float y = event.getY();

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mPath.moveTo(x, y);
			break;

		case MotionEvent.ACTION_MOVE:
			mPath.quadTo(mPosX, mPosY, x, y);

			invalidate();
			break;

		default:
			break;
		}

		mPosX = x;
		mPosY = y;

		return true;
	}
}