Android編程容易犯的錯誤

來源:互聯網
上載者:User

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)

&#39;

&#60;

&#62;

別忘了數字後面的分號哦,而且其中的數字是十進位的

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);

 11.不要太相信工具,比如Eclipse裡面的斷點遇到多線程什麼,經常不起作用/走不到,還有就是如果語句為空白的也不會走,這時候別太早下結論斷點地方出錯了,

所以每個工程都應該有日誌的開關,通過查看日誌來確認,某個路徑是否走到或者某個變數的值,。。。

 12.Java中的月份是從0開始的,所以格式化月份的時候,記得在原有的值上加1處理,如

Calendar calendar = Calendar.getInstance();            if(!TextUtils.isEmpty(dateTimes)){                long milliseconds = WLDateUtils.parseDayTime(dateTimes);                calendar.setTimeInMillis(milliseconds);            }            final int old_year = calendar.get(Calendar.YEAR);            final int old_month = calendar.get(Calendar.MONTH);            final int old_day = calendar.get(Calendar.DAY_OF_MONTH);            mDatePickerDialog = new DatePickerDialog(this, new OnDateSetListener(){                @Override                public void onDateSet(DatePicker view, int year,                        int monthOfYear, int dayOfMonth) {                    if(year != old_year || monthOfYear != old_month || dayOfMonth != old_day){                        String dateTimes = String.format("%04d-%02d-%02d", year,                                monthOfYear + 1, dayOfMonth);//月份是從0開始的                    }                }            },             old_year, old_month, old_day);

13.設定ListView的分割線,如果不是圖片的話,應注意順序:

        mListView = new ListView(this);        mListView.setCacheColorHint(0);        mListView.setBackgroundDrawable(null);        mListView.setDivider(getResources().getDrawable(R.drawable.list_divider));        mListView.setDividerHeight(2);其中:<drawable name="list_divider">#00CCCC00</drawable>

即 setDividerHeight 函數應該在setDivider之後,否則這個分割線無效。

 

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.