android开发常见编程错误总结

1.设置TextView的文本颜色

1
2
3
TextView tv;
...
tv.setTextColor(R.color.white);

其实这样设置的颜色是 R.color.white的资源ID值所代表的颜色值,而不是资源color下的white颜色值:正确的做法如下:

1
tv.setTextColor(getResources().getColor(R.color.white));

这个出错的概率满高的,就是因为二者都是int类,导致编译器不报错。

2.读取Cursor中的值

1
2
3
4
5
6
7
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

编译没有问题,只有在运行的时候才会发现。

正确的做法是:

1
2
3
4
5
6
7
8
9
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 ;
}

或者:

1
2
3
4
5
6
7
8
9
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),写出如下的语句

1
name <> 'zhangsan'

但是,这样写的语句,如果碰到name值为空的时候,就有问题,即name为空时 以上的布尔值为false,而不是true.

原因很可能,SQLite中的判断函数采用类似写法:

1
2
3
4
boolean judge(String self, String conditions){
     if ( null  == self) return  false ;
     return  self.equalsIgnoreCase(conditions);
}

其中 self为数据库中name的值,而conditions为上面示例中的 zhangsan。

所以,以上查询条件的正确写法是:

1
name <> 'zhangsan'  or name is null

除非你也想过滤掉name 为空的记录。

5.如下所示,想要在按钮显示"删 除"(没错删除中间有个空格),以下的字符串资源是错误的:

1
<string name= "button_delete_text" >删 除</string>

这样的出来,最终看不到中间的空格,应该是Android SDK编译的时候,会自动过滤掉String中的空格部分,所以应该采用以下的方式:

1
<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必须设置:

1
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

否则,会报如下类似的错误:

1
Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag.

而我们还要提防系统控件中的隐性调用startActivity:

1
2
3
TextView tv = new  TextView(mContext);
tv.setAutoLinkMask(Linkify.ALL);
<br>tv.setText(content);

当content内容中有电话号码/邮件/URL时,并且mContext不是非Acitvity的context,而是app的context时(XXXActivity.this.getApplicationContext()),

就会出现如下的错误:

1
2
3
4
5
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. 控件有时不能充满整个屏幕:

1
2
3
4
5
6
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);

而应该是:

1
2
3
4
5
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没有起来

1
2
Intent service = new  Intent( this , FuncService.class);
startService(service);

很有可能是忘了在AndroidManifest.xml中注册FuncService

1
<service android:name= "com.android.example.FuncService" />

10.TextView中为什么会在有些行尾出现"..."字符,当然不是所有手机都是有问题,本来笔者刚开始也以为可能是

手机的ROM问题,认真review了代码,发现如下的代码:

1
2
mIntroView = (TextView) findViewById(R.id.description);
mIntroView.setEllipsize(TruncateAt.END);

问题是上面的第2行,之前是因为要限定文本的行数,后来去掉限制,没有去掉以上的代码。

该行代码会导致很多的ROM上:只要一个文本行的文字在一个手机屏幕行显示不下的话,就自动在

行尾截断并在行尾添加"...",而之前没有问题是因为:全部显示的时候,我调用了如下方法:

1
mIntro.setMaxLines(Integer.MAX_VALUE);

11.不要太相信工具,比如Eclipse里面的断点遇到多线程什么,经常不起作用/走不到,还有就是如果语句为空的也不会走,这时候别太早下结论断点地方出错了,

所以每个工程都应该有日志的开关,通过查看日志来确认,某个路径是否走到或者某个变量的值,。。。

12.Java中的月份是从0开始的,所以格式化月份的时候,记得在原有的值上加1处理,如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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的分割线,如果不是图片的话,应注意顺序:

1
2
3
4
5
6
7
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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值