Android的“if”块中的奇怪行为

时间:2010-07-21 06:54:17

标签: java android

它像一个小虫一样走路,它像一个小虫唧唧喳喳......我需要有人确认这是一个错误。

我试图通过以下代码从地址簿中获取电话号码:

public JSONObject getAllPhones() throws JSONException{ 
String mPhoneNumberProjection[] = new String[] {
        Contacts.Phones.NAME, Contacts.Phones.NUMBER, Contacts.Phones.TYPE
};
Uri phoneNumbersUri = Contacts.Phones.CONTENT_URI;
JSONObject result = new JSONObject(); 
JSONArray phones = new JSONArray();

Cursor myCursor = mApp.managedQuery(phoneNumbersUri, mPhoneNumberProjection, null, null, null);
mApp.startManagingCursor(myCursor);
if (!myCursor.isAfterLast()){
    myCursor.moveToFirst();
    do{
        JSONObject aRow = new JSONObject();
        for (int i = 0; i < myCursor.getColumnCount(); i++){
            Log.d(LOG_TAG, myCursor.getColumnName(i) + " -> " + myCursor.getString(i));
            aRow.put(myCursor.getColumnName(i), myCursor.getString(i));
        }
        phones.put(aRow);
    } while (myCursor.moveToNext());
}
result.put("phones", phones);
result.put("phoneTypes", getPhoneTypes());
return result;
}

但是当没有联系人,并且!myCursor.isAfterLast()评估为“false”时,程序进入“for”循环。所以它进入“if”块,跳过几个方法并落入“for”循环......

当我将这个循环提取到一个单独的函数中时,一切正常。

我在32位Vista上的Eclipse Helios中这样做。我尝试清理项目,擦除Java缓存,重新启动计算机,创建新的AVD ......我使用的是Android 1.6和Android 2.2,但错误仍然存​​在......

有人可以解释发生了什么吗?

5 个答案:

答案 0 :(得分:1)

似乎这种行为无法在我的机器外再现,因此,我猜,你们都可以免受伤害:)

答案 1 :(得分:0)

我同意,这闻起来像编译错误。编译器可能在字节代码中创建了错误的跳转目标地址。您是否在模拟器和设备上遇到同样的问题?您可以为不同的手机(以及不同的硬件架构)添加模拟器以进行检查,如果这是一般性问题或仅限于您的设备。


可以尝试一下 - 抓住一个反编译器(我推荐JD Java Decompiler,希望它也适用于Android应用程序)并尝试反编译类文件以查看,id反编译结果与您的源代码匹配 - 在至少在逻辑上。如果有很大差异 - &gt;潜在的编译器错误 - &gt;向android开发团队发布报告。

答案 2 :(得分:0)

如果光标位于0个条目中的第一个之前,您确定isAfterLast的计算结果为false吗? ;) 你为什么不直接评估moveToFirst()?如果没有条目,它将评估为false,因此无论如何都不需要调用isAfterLast()。

答案 3 :(得分:0)

ifwhile重写为此

try {
    if (c!=null) {
        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
               //stuff here
        }
    }
} finally {
    if (c!=null) {
        c.close();
    }
}

答案 4 :(得分:0)

我相信是AfterLast按预期工作。 isAfterLast将为false,因为没有你所说的行,所以它永远无法评估它是否在最后一行。

另外在上面的代码示例中,在调用isAfterLast()之前,您从未移动到第一行开始,if语句永远不会再次被评估。

使用

if (cursor.moveToFirst()) {
       // code
    while(cursor.isAfterLast() == false) {
        // code
     String[] columNames = cursor.getColumnNames();
     for (String column : columnNames)  {
         aRow.put(column, cursor.getString(cursor.getColumnIndex(column))); 
     }
    cursor.moveToNext();
    phones.put(aRow);

    }
}

希望有所帮助。