Sean's Note: 12月 2012

2012年12月29日 星期六

Primitive type & Reference type

在 Java 裡,型別被分為兩大類 Primitive type 和 Reference type,

有八個型別屬於 Primitive type,分別是 boolean, char, byte, short, int, long, float, double,

其他如 String, Array 和使用者自定義的 class 則屬於 Reference type。

而兩者重要的差別在於,當變數被當作函式的參數傳遞時,

Primitive type 的值不因函式運算而改變。

Reference type 的值會因函式運算而改變 (除了 String 以外!)。

大多人會覺得那這不就是 C++ 中的 call by reference 嗎?

其實都是 call by value,因為 Java 不允許處理記憶體位置。

 (詳見: http://openhome.cc/Gossip/JavaEssence/CallByValue.html)。

String 雖然是 Reference type,但在函式裡更改其值,並不影響外部變數的結果,

這是因為 str = "Hello" 等同於 str = new String("Hello"),str 指向了新的記憶體空間,

所以不會更動到原本的記憶體。

2012年12月28日 星期五

[Eclipse] Getting error when importing existing android code into workspace.

在 Eclipse 裡 "Import" -> "Existing Android Code Into Workspace" 時,出現了如下圖的

錯誤訊息 :

Invalid project description
原因是我把 source 來源也放在 workspace 裡,解決的方法有兩個:
  1. 勾選 "Copy projects into workspace"。
  2. 把 source 放到其他地方不要放在 workspace 裡,然後再 import 一次。(不過這樣 project 會放在 workspace 外面)。

2012年12月18日 星期二

用 Java 讀取 HTTP 網頁內容

在 JDK 的 java.net 包中已經提供了訪問 HTTP 協定的基本功能:HttpURLConnection。

Apache 也提供了對應的 HttpClient 功能更為強大也更容易使用。

HttpURLConnection 與 HttpClient 的比較可參考這篇文章 :

http://superonion.iteye.com/blog/1545496

而下面是個完整可執行的程式碼,用來讀取 Apache 的網頁資訊 :

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

// Using version 4.2.2
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpClientSample{
    public   static   void  main(String[] args) throws ClientProtocolException, IOException {
     DefaultHttpClient  httpClient = new DefaultHttpClient();
    
     // Prepare a request object
     HttpGet httpget = new HttpGet("http://www.apache.org/");

     // Execute the request
     HttpResponse response = httpClient.execute(httpget);

     // Examine the response status
     System.out.println(response.getStatusLine());

     // Get hold of the response entity
     HttpEntity entity = response.getEntity();
     System.out.println(entity.getContentType());
     
     //System.out.println(EntityUtils.toString(entity));
     // If the response does not enclose an entity, there is no need
     // to worry about connection release
     if (entity != null) {
         InputStream instream = entity.getContent();
         try {
             BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
             // do something useful with the response
             String str;
             while (reader != null && (str = reader.readLine()) != null)
             {
              System.out.println(str);
             }
             
         } catch (IOException ex) {

             // In case of an IOException the connection will be released
             // back to the connection manager automatically
             throw ex;

         } catch (RuntimeException ex) {

             // In case of an unexpected exception you may want to abort
             // the HTTP request in order to shut down the underlying
             // connection and release it back to the connection manager.
             httpget.abort();
             throw ex;

         } finally {
             // Closing the input stream will trigger connection release
             instream.close();

         }
     }
    }
}

2012年12月11日 星期二

[Android] 印出 JavaScript 的 log

我們都知道在網頁開發中,在 JavaScript 裡打上 console.log() 就可以用 Tools 看 log,
同樣的,在開發 Android 1.6 以下的 Web Apps 時,用 console.log() 也可以將 log 印在
Eclipse 端的 LogCat 或手機端的 aLogcat。 在 Android 2.1 (API Level 7) 以上,則必須實做
WebChromeClient 並 override onConsoleMessage() callback 方法。

(詳見: Android Developers)

實測案例:
1. Samsung Galaxy R (Android 4.0.4):  console.log() 無用,必須 override callback 方法。
2. Toshiba AT500 (Android 4.0.3):  console.log() 可直接印出 Tag 為 Console Web 的訊息。

Note:
  1.  AT500 安裝 ADB USB Driver 的方法
  2. 手機上的 aLogcat, CatLog 等 App,因為新的安全政策,已無法在
    Android 4.1 (Jelly Bean) 上的裝置印出 log,除非 root 過,詳見


2012年12月5日 星期三

在 JavaScript 中常用的 bind 方法

有時候我們會頻繁的使用某個 Object 底下的函式,

於是不斷的呼叫 Object.func() ...

我們可以利用 bind 技巧的實現,省去一些程式碼的撰寫。

bind 顧名思義,就是將某個 object 和函式綁定在一起。

範例如下:

function bind(object, func)
{
  return function()
   {
      return func.apply(object, arguments);
   };
}

var testArray = [];
var pushToTest = bind(testArray, testArray.push);

pushToTest("A");
pushToTest("B");
show(testArray); // ["A", "B"]

2012年12月3日 星期一

Android's dialog 選項與 Index 的關係

在建立 Dialog 時,很常見對 Positive/Negative 按鈕,用匿名內層類別 (Anonymous Inner Classes)
的方式各別對其建立 OnClickListener 物件。另外一種寫法是,不管使用者按下哪個選項,
都用同一個 OnClickListener 物件,在依據 int which 參數來判斷是哪個選項。

Positive Button 為 -1
Negative Button 為 -2
Neutral Button 為 -3

Items 則從 0 開始遞增
範例如下:

...

String[] options = {"紅色", "黃色", "綠色" };
builder.setItems(options, listener); // 指定選項
builder.setPositiveButton("確定", listener);
builder.setNegativeButton("取消", listener);
builder.setNeutralButton("設定", listener);

DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener(){
  public void onClick(DialogInterface dialog, int which) {
    // 找到Button元件
    Button btn = (Button) findViewById(R.id.button1);
    // 指定背景色彩
    switch(which){
      case -3:
        // Neutral 選項被按下
        break;
      case -2:
        // Negative 選項被按下
        break;
      case -1:
        // Positive 選項被按下
        break;
      case 0:
        btn.setBackgroundColor(Color.RED);
        break;
      case 1:
        btn.setBackgroundColor(Color.YELLOW);
        break;
      case 2:
        btn.setBackgroundColor(Color.GREEN);
        break;
    }   
  }
};

...


▲ 各選項的 Index