Android编程注意事项
一、使用IO流时要注意关闭
当从网络上或本地读取、写入文件时,一定要注意将IO流进行关闭。未关闭可能导致系统内存不足从而使系统抛出OOM异常。
解决方案:在try-catch作用域内应在finally中关闭
InputStream inputStream = null;
try {
inputStream = httpResponse.getEntity.getContent();
......
} finally {
if (inputStream != null) {
try {
inputStream.cloase();
} catch(IOException e) {
e.printStachTrace();
}
}
}
二、使用除法或求余没有判断分母为0隐患
使用除法或者求余运算时,一定要确定分母不为0;若不能确定分母一定不为0,则要进行判断
解决方案:调用函数前,对函数的返回值的长度进行判断。并且要对为0的情况进行处理,以使逻辑更加合理
int boardListSize = mBoardTextList.size();
if(boardListSize > 0) {
text = mBoardTextList.get(mBoardIndex % boardListSize);
} else {
text = defaultValue;
}
三、格式化数字异常未捕获的隐患
在将其他类型转化成数字时,可能无法将其转换成合适的数字,导致抛出NumberFormatException
解决方案:在任何用到格式化数字时,捕获异常,并进行处理,主要是对转化异常的值赋一个初始值
public static Float formatMileage(Sring mAverageSpeed) {
float mileage;
try {
mileage = Float.parseFloat(mAverageSpeed);
} catch(NumberFormatException) {
mileage = default;
}
return mileage;
}
四、【越界】使用String.split结果未判断长度隐患
在使用String.split方法对字符串进行分割后,是用得到的数组时,要先对数组长度进行检查,防止出现数组越界的问题。如下:
String source = "<br/>";
String[] infos = source.split("<br/>");
String poiName = infos[0];
<div> </div>
解决方案:在使用split结果数组前,添加对数组长度的判断。最好给一个默认值也
String source = "<br/>";
String[] infos = source.split("<br/>");
if(0 < infos.length){
String poiName = infos[0];
}
五、【越界】使用String.substring前未判断长度隐患
在使用String.substring时,未对字符串的长度进行检查,截取字符串时可能会发生越界而导致Crash。如:
String sb = new String();
String value = sb.substring(0,sb.length()-1);
解决方案:在使用substring前,对字符串的长度进行判断
如下:
String sb = new String();
if( sb.length() > 0){
String value = sb.substring(0,sb.length()-1);
}
六、方法中存在return null的情况,返回对象为判断直接进行方法调用隐患
如果一个方法的返回值可能为null,那么在使用这个返回值时,就要提前进行判断,在不为空的情况下才能调用返回值对象的方法,否则会出现java.lang.NUllPointerException的异常,导致appCrash。如:
public ArrayList<RouteListItem> getRouteNodeData() {
if (mRouteList.size() == 0)
return null;
} else {
return mRouteList;
}
}
public void clearItem(){
RouteResultManager mgr = RouteResultManager.instance(mContext);
mFocusItemIndex = mgr.getRouteNodeData().get(0);
}
解决方案:对方法中含有return null的返回对象进行直接方法调用时需要先进行判断。
public ArrayList<RouteListItem> getRouteNodeData() {
if (mRouteList.size() == 0) {
return null;
} else {
return mRouteList;
}
}
public void clearItem(){
RouteResultManager mgr = RouteResultManager.instance(mContext);
if(mgr.getRouteNodeData() != null ){
mFocusItemIndex = mgr.getRouteNodeData().get(0);
}
}
七、【异常】ArrayList使用get方法获取元素未判断下标有效性的隐患
ArrayList通过get方法使用下标获取元素,如果使用的下标不在ArrayList大小范围内,将产生java.lang.IndexOutOfBoundsException的异常,导致app出现Crash。如下
private ArrayList<Reply> mRepliesData;
public boolean onContextItemSelected(int selectedPosition) {
mRepliesAdapter = new NoteReplyAdapter(this, mRepliesData);
Reply reply = mRepliesData.get(selectedPosition);
……
return super.onContextItemSelected(item);
}
**解决方案:在使用ArrayList的get方法获取元素时,需要判断使用的下标的有效性。
private ArrayList<Reply> mRepliesData;
public boolean onContextItemSelected(int selectedPosition) {
mRepliesAdapter = new NoteReplyAdapter(this, mRepliesData);
if (selectedPosition < mRepliesData.size()) {
Reply reply = mRepliesData.get(selectedPosition);
}
……
return super.onContextItemSelected(item);
}
八、【判空】通过HashMap获取对象使用未判空隐患
在java代码实现时,通过Hashmap的get方法获取对象,并且不是使用Hashmap的iterator获取,如果key不存在时获取的对象为null,在使用此对象可能出现java.lang.NullPointerException的异常,导致app出现Crash。如:
private HashMap<Long, OfflineCacheStatus> mCacheStatus;
……
synchronized (mLatestDatas) {
for (BaiduMp3MusicFile bmmf : mLatestDatas) {
if(bmmf == null) continue;//add this line,question?
status = mCacheStatus.get(bmmf.mId_1);
// status为null,使用status.path报空指针异常
if (!StringUtils.isEmpty(status.path)) {
bmmf.mPath = status.path;
}
}
}
解决方案:在使用Hashmap获取对象前,判断该对象是否为null,并进行异常处理
private HashMap<Long, OfflineCacheStatus> mCacheStatus;
……
synchronized (mLatestDatas) {
for (BaiduMp3MusicFile bmmf : mLatestDatas) {
if(bmmf == null) continue;//add this line,question?
status = mCacheStatus.get(bmmf.mId_1);
// status为null,使用status.path报空指针异常
if (status != null) {
if (!StringUtils.isEmpty(status.path)) {
bmmf.mPath = status.path;
}
}
}
}