2014年3月29日 星期六

Andorid animation: animator set 製作button閃爍效果

以下實作一組重複發生的  淡出-移動-淡入 動畫,


套用在半透明gradient drawable上面可以製造出原件閃亮亮的效果

2013年12月4日 星期三

grep + less with color


grep -R --color=always "search string" * | less -R


若只有--color的話預設為--color=auto,pipe with less使用的話不會有顏色

less -R才會翻譯顏色escape charactor


2013年11月26日 星期二

linux 使用swap memory

最近嘗試在aws ec2 上deploy 一個ror的project

但因為使用的是free trail instace所以memory很小,deploy的時候會噴cannot allocate memory

要切一塊disk空間作為swap memory以解決這個問題


首先先確認是否已經存在swap memory:

sudo swapon -s


如果沒有會顯示如下
Filename    Type  Size Used Priority


在確認沒有swap memory後檢查我們是否有足夠的硬碟空間,我們要做一塊512mb的swap memory所以要至少這麼多

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.9G  3.5G  4.1G  47% /
udev            288M   12K  288M   1% /dev
tmpfs           119M  176K  118M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            296M     0  296M   0% /run/shm


開始建立swap memory

sudo dd if=/dev/zero of=/swapfile bs=1024 count=512k
sudo mkswap /swapfile
執行完會顯示
Setting up swapspace version 1, size = 262140 KiB
no label, UUID=xxxxxxxxxxxxxxxxxxxxxxxxxxx

接著使用這個空間
sudo swapon /swapfile

不過只是這樣重開機的話會失去效用,所以要把這塊swap memory加入fstab(file system table)中
sudo vim /etc/fstab

加入這行
 /swapfile       none    swap    sw      0       0 

記得把Swappiness設定為0, 這樣可以確保os只有在緊急的時候(例如不swap就噴out of memory)才做swap動作,增加效能

sudo su -
echo 0 > /proc/sys/vm/swappiness
exit



2013年11月11日 星期一

Android: 使用LightingColorFilter 來做使用image background的button的onClick特效

以往我在做用其他image為background的button的onClick特效時,都要準備好兩張image,

一張為按下去前,一張為按下去後,實為麻煩.

後來發現只要使用Android sdk內建的LightingColorFilter就可以用一張圖達到不錯的類似效果:


mTestBtn.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(event.getAction() ==MotionEvent.ACTION_DOWN) v.getBackground().setColorFilter(new LightingColorFilter(0xFF999999, 0xFF000000)); else if(event.getAction() ==MotionEvent.ACTION_UP) v.getBackground().clearColorFilter(); return false; } });

Android:setting text size in pixel


textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, valueInPixel);

2013年11月5日 星期二

Android: 當資料庫越來越肥大 之 容易擴充的DB架構

使用這樣的寫法在修改或擴增database的時候可以比較舒服(我覺得啦XD)
不過如果只是要寫一個小小且不太會擴充的db那就先不需要這把牛刀了!

後面有完全沒有整理過(囧)的範例code,可能看code比較好懂.

此架構大致分為五個部分:

DBHelper


  • 這個就是一般在寫db的時候繼承SQLiteOpenHelper而來的class,這邊增加了一些function讓操作更便利一點.擔負起了依照schema來建立table、實際操作db等重責大任.
  • 這個class是獨立於project的,可以直接貼到別的project.

DBSchema


  • 掌握了整個db的架構,建立實體以後會喂给DBHelper的constructor吃.
  • 這個class幾乎也獨立於不同project,除了要在變數定義的時候告知這個project中table的相關資訊.另外加入新的Table時也記得要在這裡增加定義.

DBTable

  • 每一個table有自己專屬的class,所以加入新table的時候基本上不會動到舊的架構.
  • 提供的method儘量不存取到自己以外的table.
  • 提供存取自己table 的method给data provider使用.

Data Provider

  • 扮演db的adapter角色,可以存取多個db並且將資料處理組合後以便使用.
  • app的其他部分需要存取資料理當只會使用到Provider,不會直接使用DBTable.
  • Provider理當是唯一會直接使用到DBTable的class.
  • 可以視需求增加不同的data provider

Global initialization

因為DBHelper是採用singleton,所以用application context來做初始化.
我是另外建立了一個application class來確保db在被任何activity使用前已經初始劃完成.



建立一個新的table步驟:

  1. 先建立一個table class.
  2. 去Schema中加入Table資訊.
  3. 接著就可以在data provider中使用這個table.

剩下的就讓code自己來解說吧XD



2013年10月16日 星期三

Android: 建立一個configure class當作參數以增加constructor的彈性

如果初始化一個class所需要設定的參數太多,會造成這個class的constructor過長,這個情況可以利用自定義一個config class作為參數給constructor吃來解決.


這樣做有幾個特點:

  1. 可以確保在物件建構前設定所有建構時所需要的資訊
  2. 統一參數設定時機
  3. config class中對於optional的參數可以有default值
  4. 設定參數時可以有很大的自由度不用依照constructor規定的參數順序.
  5. 不代表之後不能變動參數,還是可以加入function 如MyClass.setNewHeight()


用法:


//usage //為何要使用Builder與其實作後面說明 MyClassConfig config = MyClassConfig.Builder() .setHeight(100) .setWidth(50) .setXXX(...) .setYYY(...) .build(); MyClass mc = new MyClass(config); //constructor MyClass(MyClassConfig config) { this.height = config.height; this.width = config.width; //other initialization ... }


接下來介紹config class的實作,架構如下:


public class MyClassConfig { //1.config class fields ... //2.config class constructor ... //3.static inner builder class: public static class Builder { // 3.1 builder fields ... // 3.2 builder constructor ... // 3.3 builder setter ... // 3.4 build() function ... } // end of builder }//end of MyClassConfig


1. config class fields

  //首先定義fields,使用final qualifier來確保config建構的時候要完成全部的設定 final int height; final int width; ...

使用final qualifier有兩個用意

  • 確保全部的設定在config建構的時候就會完成
  • MyClass要可以直接存取這些fields所以不能是private但又不希望config建構後fields還會被更動
(ps1. java沒有指定private或public時候的存取權是package)
(ps2. final 變數除了在宣告的時候直接assign值外唯一的設定機會是在constructor中)

藉由Builder的幫助來建立fields為final的config class

2.config class constructor



config class的constructor吃一個Builder物件作為參數

public MyClassConfig(Builder pBuilder) { this.height = pBuilder.height; this.width = pBuilder.width; ... }



3.static inner builder class


這邊加上static是因為static inner class不用reference到outer class 的instance,才可以直接用以下方式建立:

new MyClassConfig.Builder();

最後是builder 的實作


public static class Builder{ //3.1 builder fields private int height; //可以在這邊設定default value,如果build過程中沒有被更改,default value會被assign到最後build出來的config class中 private int width = 100; //3.2 builder constructor //如果建立config的時候需要一些外部資訊可以當作builder constructor的參數傳入 public Builder(){}; //3.3 builder setter //設定config參數的functions, 回傳自己是為了可以達到method chaining的效果 //i.e., builder.setHeight(100).setWidth(100).build(); public Builder setHeight(int h) { this.height = h; return this; } public Builder setWidth(int w) { this.width = w; return this; } //3.4 build function //最後建立出config的function public MyClassConfig build() { return new MyClassConfig(this); } }

大概就是這樣,最後附上一段之前寫的code作為範例

package itri.u9lab.towolf.ratiofixer; public class RatioLayoutConfig { final int virtualWidth; final int virtualHeight; final boolean isFullScreenMode; /* * constructor */ public RatioLayoutConfig(Builder pBuilder) { this.virtualHeight = pBuilder.virtualHeight; this.virtualWidth = pBuilder.virtualWidth; this.isFullScreenMode = pBuilder.isFullScreenMode; } /* * config builder */ public static class Builder { private int virtualWidth = 768; private int virtualHeight =1230; boolean isFullScreenMode = false; public Builder() { } public Builder setVirtualSize(int pWidth,int pHeight) { virtualWidth = pWidth; virtualHeight = pHeight; return this; } public Builder setFullScreen(boolean mode) { isFullScreenMode = mode; return this; } public RatioLayoutConfig build() { return new RatioLayoutConfig(this); } }//end of builder public static RatioLayoutConfig getDefaultConfig() { return new Builder().setFullScreen(false).setVirtualSize(768, 1230).build(); } }