寒冰噴霧

最近被蟑螂搞的很煩,

惱怒之下買了這個東西,

寒冰噴霧,

看部落格介紹感覺很厲害,

當下又被蟑螂搞的很煩,

就直接在露天下標了,

不過出貨速度實在有夠慢,

將近一個禮拜才拿到,

今天剛好一進浴室就遇到一隻大蟑螂,

立馬來試驗,

結果一噴他馬上亂跑,

噴了好幾次才翻肚,

而且噴不死,

不過我想這東西最大的優點就是不用去處理,

像用拖鞋或者肥皂水,

都還要去清理周圍環境,

拿這個噴只要把蟑螂拿去沖掉就好,

而且噴起來有莫名的爽感(?,

但是含運要320,

個人認為不如買一點訣會更好。

B580 續航力測試

自己改造了 B580 許多的硬體規格,

因此想來測試看看改造後的續航力,

CPU:I5-3230M

GPU:HD4000

RAM:6G

SSD:M4 128G

WLAN:AR5B197

在亮度10,電池計畫為平衡的情形下,

連續撥放奇樂網的Doctor Who影集,

使用Wifi,

從晚上 08:14 分 撥到 晚上 11:44分,

電源從100% - > 5% ,

總共經過 3:30 分,

還算OK,

接下來會接手一台G460,

該怎麼改造呢!?

MySQL 對 VARCHAR 的 Index 空間佔用的問題…

轉貼一下別人的測試,

之前有一個老師跟我說MySQL設定好長度以後,

每個資料都會依照最大長度去儲存,

害我每次設計都要想很久,

以下是原文,轉貼自此

之前不知道從哪邊學到錯的東西… 後來實驗後發現搞錯了。MySQL 對 VARCHAR 欄位下 index 所實際佔用的空間仍是實際大小,而非最大長度。

測試方法是建立表格,database schema 是 CREATE TABLE test (id INT UNSIGNED PRIMARY AUTO_INCREMENT, data VARCHAR(255));

這是 1M row,其中 data 都是 “a”,這是 OPTIMIZE TABLE 後的結果:(以下每個都有 OPTIMIZE TABLE)

-rw-rw---- 1 mysql mysql     8586 Jul 30 22:42 test.frm
-rw-rw---- 1 mysql mysql 37748736 Jul 30 22:42 test.ibd

這是 ADD INDEX (data) 後的結果:

-rw-rw---- 1 mysql mysql     8586 Jul 30 22:46 test.frm
-rw-rw---- 1 mysql mysql 50331648 Jul 30 22:46 test.ibd

這是 1M row,data 都是 “a” * 100 (一百個 a) 的結果:

-rw-rw—- 1 mysql mysql 8586 Jul 30 23:14 test.frm
-rw-rw—- 1 mysql mysql 146800640 Jul 30 23:15 test.ibd

這是 ADD INDEX (data) 後的結果:

-rw-rw---- 1 mysql mysql      8586 Jul 30 23:21 test.frm
-rw-rw---- 1 mysql mysql 260046848 Jul 30 23:23 test.ibd

實驗可以看出來 MySQL 的確是依照內容的實際長度索引,而非用欄位的最大長度做。

Android 字串壓縮 (String Compress)

最近在做專題的時候,

需要把JSON字串轉成QRCODE,

可是直接轉換的話,QRCODE會變得非常複雜,難以辨識,

因此上網找了一下,果然有人使用GZIP來壓縮字串,

可是在我使用了以後,

QRCODE卻無法正確被解析,

查了一下發現應該是一些Header遺失了,

導致GZIP無法正確解壓縮,

因此我決定壓縮以後再把字串用Base64編碼一次,

解壓縮的時候先用Base64解碼,

藉此把Header保留,

一試果然成功了,

不過此方法會導致壓縮率減小,

但是也夠用了

以下是程式碼,獻醜了!

ZipUtil
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
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import android.util.Base64;

public class ZipUtil {
// 壓縮
public static String compress(String str) throws IOException {
if (str == null || str.length() == 0) {
return str;
}

ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes());
gzip.close();

String encode = Base64.encodeToString(out.toString("ISO-8859-1")
.getBytes("ISO-8859-1"), Base64.DEFAULT);

return encode;
}

// 解壓縮
public static String uncompress(String str) throws IOException {
if (str == null || str.length() == 0) {
return str;
}
byte[] src = Base64.decode(str.getBytes("ISO-8859-1"), Base64.DEFAULT);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(src);
GZIPInputStream gunzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = gunzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}

return out.toString();
}
}

大部分的程式碼都是參考這裡

附上壓縮前跟壓縮後的QRCODE差異

Before
Before

After
After

Android Spinner 禁用選項 (Disable item)

找了很久都找不到要怎麼禁用Spinner裡面的item,

只好自己寫一個Adapter,獻醜了。

SpinnerArrayAdapter.java
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

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class SpinnerArrayAdapter extends ArrayAdapter<String>{

private int[] ItemPositionIsDisable;

public SpinnerArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}

public SpinnerArrayAdapter(Context context, int textViewResourceId, String[] objects) {
super(context, textViewResourceId,objects);
ItemPositionIsDisable = new int[objects.length];
}

public SpinnerArrayAdapter(Context context,String[] objects){
this(context, android.R.layout.simple_spinner_item,objects);
this.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}

public SpinnerArrayAdapter(int stringArrayResourceId,Context context){
this(context, context.getResources().getStringArray(stringArrayResourceId));
}

public boolean isEnabled(int position) {
if (ItemPositionIsDisable[position]==1)
return false;
return true;
}

public void setItemPositionIsDisable(int position,boolean IsDisable) {

ItemPositionIsDisable[position] = (IsDisable) ? 1 : 0;
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {

View mView = super.getDropDownView(position, convertView, parent);
TextView mTextView = (TextView) mView;

if (ItemPositionIsDisable[position] == 1) {

mTextView.setTextColor(Color.GRAY);

} else if (ItemPositionIsDisable[position] == 0) {
mTextView.setTextColor(Color.BLACK);
}
return mView;

}
}

用法也很簡單,

使用setItemPositionIsDisable(int position,boolean IsDisable)來設定就好,

並且支持直接使用R.array中的Resource,以下是用法範例。

1
2
3
4
5
SpinnerArrayAdapter mSpinnerArrayAdapter = new SpinnerArrayAdapter(R.array.level_array,this);
mSpinnerArrayAdapter.setItemPositionIsDisable(1,true);
mSpinnerArrayAdapter.setItemPositionIsDisable(2,true);
mSpinnerArrayAdapter.setItemPositionIsDisable(3,true);
mSpinner.setAdapter(mSpinnerArrayAdapter);

提供大家參考!

Android的OnCreate多次調用

今天在寫Android的時候,

一直遇到一個鬼打牆的問題

OnCreate在ActivityResult以後一直被調用,

因為我的ActivityForResult寫在OnCreate中,

所以就一直無限循環,

上網查了大家都說在AndroidManifest中加入

android:configChanges="orientation|keyboardHidden"

就可以了,可是問題依舊,

後來終於在Stackoverflow中找到救命浮木,

原來在API 13以上還要再加入screenSize才可以,

所以應該要改成這樣

android:configChanges="orientation|keyboardHidden|screenSize"

找了我一整個早上,

崩潰!

來源:http://stackoverflow.com/questions/10411009/activity-killed-oncreate-called-after-taking-picture-via-intent

eBay全球CEO演講:盡你所能,成為最卓越的領導者

美國時間6月15日,eBay全球CEO 約翰多納霍在史丹佛大學商學院的畢業典禮上發表題為「Be The Best Leader You Can Be」(盡你所能,成為最卓越的領導者)的演講。多納霍在演講中闡述了領導力四法則。1. 工作要有目的性:投身對自己有意義的工作;2.學無止境:偉大的領導者從來不會因自恃過高而停止學習;3. 挫折孕育寶貴經驗:困難砥礪品格,品格是領導者最重要的才能;4. 追求工作生活平衡:生活體驗也是一種領導力培訓。以下是約翰多納霍根據演講內容撰寫的部落格文,原文發表在他的LinkedIn主頁上。

Read More

JQuery.validate的一些規則

最近需要用到一些前端的驗證,在這邊紀錄一下自己所用的規則

身分證驗證
1
2
3
4
5
6
7
8
9
jQuery.validator.addMethod("ROC_Citizen_ID",
function(citizenid, element) {

citizenid = citizenid.replace(/\s+/g, "");

return(
this.optional(element) || /^[A-Z]{1}[1-2]{1}[0-9]{8}$/.test(citizenid));

}, "不合理的身分證字號");
台灣地區手機驗證(XXXX-XXXXXX)
1
2
3
4
5
6
7
8
9
jQuery.validator.addMethod("ROC_Celphone",
function(cellphone, element) {

cellphone = cellphone.replace(/\s+/g, "");

return(
this.optional(element) || /[0][1-9]{3}\-[0-9]{6}/.test(cellphone));

}, "請輸入XXXX-XXXXXX");
台灣地區市話驗證(XX-XXXXXXXX)
1
2
3
4
5
6
7
8
9
jQuery.validator.addMethod("ROC_Telphone",
function(cellphone, element) {

cellphone = cellphone.replace(/\s+/g, "");

return(
this.optional(element) || /[0-9]{2}\-[0-9]{7}/.test(cellphone));

}, "請輸入XX-XXXXXXXX");