2011年11月13日 星期日

AsyncTask & notifyDataChanged

adapter 的notifyDataChanged()必須在UI thread 中呼叫, 如果不是, 例如, 如果在adapter中, 自行呼叫 notifyDataChanged() 將會造成許多問題, 例如, 按鍵無法接受。在我的個案中,按鍵無法接受,不管是長按或是短按,但是,滑動光學滑鼠之後,就正常了,查網,的確有這個問題。
http://stackoverflow.com/questions/4566101/how-to-fix-notifydatasetchanged-listview-problems-in-dynamic-adapter-wrapper-and

解決的方法是使用AsyncTask, 例如:
 class AppendTask extends AsyncTask<Integer, Float, Exception> {
    @Override
    protected void onPreExecute() {
    ... run in UI thread
 
 
 return float-value; 
    }
    @Override
    protected Exception doInBackground(Integer... params) {
    ...
    ... run in WORKING thread
    ...publishProgress(a,b,c);
    }
 
 @Override
     protected void onProgressUpdate(Float progress) {
     ...run in UI thread
     }
    @Override
    protected void onPostExecute(Exception e) {
     ... run in UI thread
  }
  AsyncTask 的三個參數中,第一個參數(Integer), 是doInBackground()的輸入參數類別,是不定個數的參數。第二個參數(Float) 是onProgressUpdate的輸入參數類別,也是不定個數。第三個參數(如例中之Exception)則為doInBackground的傳回值類別,也是onPostExecute()的輸入類別。
四個函數,只有doInBackground在Working thread(沒有UI的thread)中執行,onPreExecute()第一個被執行,接著就執行doInBackground(), 這是不能省略的函數,在函數中可呼叫(也可以不呼叫)onProgressUpdate一次或多次。onPostExecute()則是在doInBackground結束後執行。

2011年11月8日 星期二

CharBuffer.toString() trap-Example: int32toHex

使用CharBuffer.toString()時, 要注意, 輸出的字串, 是從指標所在的位置開始寫的, 因此, 在輸出之前, 要加上: position(0), 如:
以下是一個範例, 將32位元有正負的整數, 傳成十六進位數字,
 /**
  * Convert 32 bits integer number to hex-decimal string
  * @param num number to convert
  * @return hex-decimal string
  */
public static String Int32ToHex(int num) {
  final int BUFFER_SIZE=8;
  final int BITS=32;
  String pattern="0123456789ABCDEF";
  CharBuffer digits=CharBuffer.allocate(BUFFER_SIZE);
  int digit=0;
  int ref=0x80000000;
  int bitValue=0x8;
  for(int i=0;i<BITS;++i) {
      int offset=i%4;
      if(offset==0 && i!=0) {
      digits.append(pattern.charAt(digit));
      digit=0;
      bitValue=0x8;
   }
   if((num & ref)!=0) digit += bitValue;
   bitValue >>= 1;
   /***
    * Notice that,

    *        0x80000000(-2147483648) >> 1 is NOT 0x40000000, but 0xC0000000(-1073741824)
    *        (-->E0000000(536870912)-->F0000000(268435456)-->F8000000(-134217728))
    *        Always divide by 2, no matter positive or negative number
    * and 0xFFFFFFFF(-1) >> 1 is NOT 0x7FFFFFFF, but still 0xFFFFFFFF
    * For the positive integer, the bit operation is running just as expectation.
    */
   if(ref==0x80000000) ref=0x40000000;
   else ref >>= 1;
  }
  digits.append(pattern.charAt(digit));
  digits.position(0);
  return digits.toString();
}

2011年11月3日 星期四

Spinner trap

發現spinner設定OnItemSelectedListener時, 會自動呼叫一次,
而且是選項0, 在網站上有找到類似的說法,
http://blog.csdn.net/androidbluetooth/article/details/6670153
結果解決的方法, 有點怪異,
原來是,
spinner.setSelection(itemID);
spinner.setOnItemSelectedListener(...);
結果在執行時, 會自動呼叫listener, 傳入的選項是0,
將這兩行交換,
先設定Listener, 再設定選項,
一切就OK了 !!

2011年11月2日 星期三

reference link

在Java 中都是用物件的連結,
例如:
Date a;
Date b=a;
則常a的值改變時,b也會跟著變,
此時, 用以下兩個指令:
(1) a=new Date(); 和
(2) a.setTime(new Date().getTime());
將會有不一樣的效果,
用前者, 則中斷了b 與 a 的連結, 原來, b 指向 a 的位址, 但是new 指令, 結束了 a 原來的位址, 而產生了一個新的位址(與本體), 因此, a, b 成為獨立的兩個變數.
進一步地探討, 如果:
a=b;
c=a;
那麼b-->a-->c 三個會連動, 但是如果,
a=b;
b=c;
則 a 將獨立, 而b,c 連動.

這一點在函數傳遞時也有影響,

a=null;
func(a); 在執行時, a 改變了, 外面的a 是不會變的, 但是如果
Date a;
func(a);
如果在函數中, 使用 a=b, 則連動就結束了,
但如果用a.setTime(...), 那函數結束後, a 的值也改了,
但如果用 b=a, 那a, b 就會連動,

有趣!!