1.設定TextView的文字顏色
TextView tv;
...
tv.setTextColor(R.color.white);
其實這樣設定的顏色是 R.color.white的資源ID值所代表的顏色值,而不是資源color下的white顏色值。正確的做法如下:
tv.setTextColor(getResources().getColor(R.color.white));
這個出錯的概率滿高的,就是因為二者都是int類,導致編譯器不報錯,但是有警告,所以任何警告都要小心檢視。
2.讀取Cursor中的值
Uri uri; Cursor cursor = contentResolver.query(uri, null,null,null,null); if(cursor !=null){ String name = cursor.getString(1);// curosr.close(); cursor =null; }
上面語句中的,執行到cursor.getString(1)部分就會報異常,異常是: Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 4
編譯沒有問題,只有在執行的時候才會發現。
正確的做法是:
Uri uri; Cursor cursor = contentResolver.query(uri, null,null,null,null); if(cursor !=null){ if(cursor.moveToFirst()){ String name = cursor.getString(1);// } curosr.close(); cursor =null; }
或者:
Uri uri; Cursor cursor = contentResolver.query(uri, null,null,null,null); if(cursor !=null){ while(cursor.moveToNext()){ String name = cursor.getString(1);// } curosr.close(); cursor =null; }
3. 不要使用標有Deprecated的函式或者類,比如不要使用android.telephony.gsm.SmsMessage,而應該用android.telephony.SmsMessage,這樣避免採用不同的3G協議時不會出現問題。
4. SQLite中的查詢條件,比如一個叫name的欄位,其欄位型別為TEXT,如果我們要判斷其name不等某個值(如zhangsan),寫出如下的語句:
name <> 'zhangsan'
但是,這樣寫的語句,如果碰到name值為空的時候,就有問題,即name為空時 以上的布林值為false,而不是true.
原因很可能,SQLite中的判斷函式採用類似寫法:
boolean judge(String self, String conditions){ if(null == self) return false; return self.equalsIgnoreCase(conditions); }
其中 self為資料庫中name的值,而conditions為上面示例中的 zhangsan。
所以,以上查詢條件的正確寫法是:
name <> 'zhangsan' or name is null
除非你也想過濾掉name 為空的記錄。
5.如下所示,想要在按鈕顯示"刪 除"(沒錯刪除中間有個空格),以下的字串資源是錯誤的:
<string name="button_delete_text">刪 除</string>
這樣的出來,最終看不到中間的空格,應該是Android SDK編譯的時候,會自動過濾掉String中的空格部分,所以應該採用以下的方式:
<string name="button_delete_text">刪\u0020除</string>
類似地,其他的特殊符號都可以用\u00XX來轉義,如 ' ---- \u0027, < ----- \u003C, > ---- \u003E 。
注意這裡的數字是16進位制哦。
還有一種方法是:這個應該是XML經常使用的方法(new 2013.03.28)
'
<
>
別忘了數字後面的分號哦,而且其中的數字是十進位制的
6. context的問題:
如果在一個非Activity的context裡面呼叫startActivity,那麼其intent必須設定:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
否則,會報如下類似的錯誤:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
而我們還要提防系統控制元件中的隱性呼叫startActivity:
TextView tv = new TextView(mContext); tv.setAutoLinkMask(Linkify.ALL); tv.setText(content);
當content內容中有電話號碼/郵件/URL時,並且mContext不是非Acitvity的context,而是app的context時(XXXActivity.this.getApplicationContext()),
就會出現如下的錯誤:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? E/AndroidRuntime(10382): at android.app.ContextImpl.startActivity(ContextImpl.java:622) E/AndroidRuntime(10382): at android.content.ContextWrapper.startActivity(ContextWrapper.java:258) E/AndroidRuntime(10382): at android.text.style.URLSpan.onClick(URLSpan.java:62)
由於URLSpan.onClick中呼叫startActivity是由系統控制的,所以我們必須傳入activity的contex,才不會出現如上的異常,導致程式退出。
7. 另外一個context的問題:如果你在一個單例項的物件中,有個註冊監聽器的行為的話,那麼傳給這個單例項
物件的context,就必須是ApplicationContext了,否則會出現:receiver leak的錯誤。
8. 控制元件有時不能充滿整個螢幕:
LinearLayout panel = new LinearLayout(this); LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); panel.setLayoutParams(llp); root.addView(panel);
而應該是:
LinearLayout panel = new LinearLayout(this); LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); root.addView(panel. llp);
9.按照以下的方式啟動service,但是service沒有起來
Intent service = new Intent(this, FuncService.class); startService(service);
很有可能是忘了在AndroidManifest.xml中註冊FuncService
<service android:name="com.android.example.FuncService"/>
10.TextView中為什麼會在有些行尾出現"..."字元,當然不是所有手機都是有問題,本來筆者剛開始也以為可能是
手機的ROM問題,認真review了程式碼,發現如下的程式碼:
mIntroView = (TextView) findViewById(R.id.description);
mIntroView.setEllipsize(TruncateAt.END);
問題是上面的第2行,之前是因為要限定文字的行數,後來去掉限制,沒有去掉以上的程式碼。
該行程式碼會導致很多的ROM上:只要一個文字行的文字在一個手機螢幕行顯示不下的話,就自動在
行尾截斷並在行尾新增"...",而之前沒有問題是因為:全部顯示的時候,我呼叫瞭如下方法:
mIntro.setMaxLines(Integer.MAX_VALUE);