2011-12-28 77 views
0

我遇到了GridAdapter for Andorid gridview的問題。錯誤是「12-28 21:35:44.893:E/AndroidRuntime(370):java.lang.RuntimeException:無法啓動活動ComponentInfo {btn.grid/btn.grid.ButtonGridActivity}:java.lang.ArrayIndexOutOfBoundsException 」GridAdapter數組越界了嗎?

和適配器

package btn.grid; 



import android.content.Context; 
import android.graphics.Color; 
import android.util.DisplayMetrics; 
import android.view.Gravity; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.GregorianCalendar; 
import java.util.List; 

class MonthAdapter extends BaseAdapter { 
     private GregorianCalendar mCalendar; 
     private Calendar mCalendarToday; 
     private Context mContext; 
     private DisplayMetrics mDisplayMetrics; 
     private List<String> mItems; 
     private int mMonth; 
     private int mYear; 
     private int mDaysShown; 
     private int mDaysLastMonth; 
     private int mDaysNextMonth; 
     private int mTitleHeight, mDayHeight; 
     private final String[] mDays = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; 
     private final int[] mDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 

     public MonthAdapter(Context c, int month, int year) { 
       mContext = c; 
       mMonth = month; 
       mYear = year; 
       mCalendar = new GregorianCalendar(mYear, mMonth, 1); 
       mCalendarToday = Calendar.getInstance(); 

       populateMonth(); 
     } 

     private void populateMonth() { 
       mItems = new ArrayList<String>();    
       for (String day : mDays) { 
         mItems.add(day); 
         mDaysShown++; 
       } 

       int firstDay = getDay(mCalendar.get(Calendar.DAY_OF_WEEK)); 
       int prevDay; 
       if (mMonth == 0) 
         prevDay = daysInMonth(11) - firstDay + 1; 
       else 
         prevDay = daysInMonth(mMonth - 1) - firstDay + 1; 
       for (int i = 0; i < firstDay; i++) { 
         mItems.add(String.valueOf(prevDay + i)); 
         mDaysLastMonth++; 
         mDaysShown++; 
       } 

       int daysInMonth = daysInMonth(mMonth); 
       for (int i = 1; i <= daysInMonth; i++) { 
         mItems.add(String.valueOf(i)); 
         mDaysShown++; 
       } 

       mDaysNextMonth = 1; 
       while (mDaysShown % 7 != 0) { 
         mItems.add(String.valueOf(mDaysNextMonth)); 
         mDaysShown++; 
         mDaysNextMonth++; 
       } 

       mTitleHeight = 30; 
       int rows = (mDaysShown/7); 
       mDayHeight = (mDisplayMetrics.heightPixels - mTitleHeight 
           - (rows * 3) - getBarHeight())/ (rows - 1); 
     } 

     private int daysInMonth(int month) { 
       int daysInMonth = mDaysInMonth[month]; 
       if (month == 1 && mCalendar.isLeapYear(mYear)) 
         daysInMonth++; 
       return daysInMonth; 
     } 

     private int getBarHeight() { 
       switch (mDisplayMetrics.densityDpi) { 
       case DisplayMetrics.DENSITY_HIGH: 
         return 48; 
       case DisplayMetrics.DENSITY_MEDIUM: 
         return 32; 
       case DisplayMetrics.DENSITY_LOW: 
         return 24; 
       default: 
         return 48; 
       } 
     } 

     /** 
     * For week starting Monday 
     * @param day from Calendar.DAY_OF_WEEK 
     * @return day week starting Monday 
     */ 
     private int getDay(int day) { 
       switch (day) { 
       case Calendar.MONDAY: 
         return 0; 
       case Calendar.TUESDAY: 
         return 1; 
       case Calendar.WEDNESDAY: 
         return 2; 
       case Calendar.THURSDAY: 
         return 3; 
       case Calendar.FRIDAY: 
         return 4; 
       case Calendar.SATURDAY: 
         return 5; 
       case Calendar.SUNDAY: 
         return 6; 
       default: 
         return 0; 
       } 
     } 

     private boolean isToday(int day, int month, int year) { 
       if (mCalendarToday.get(Calendar.MONTH) == month 
           && mCalendarToday.get(Calendar.YEAR) == year 
           && mCalendarToday.get(Calendar.DAY_OF_MONTH) == day) { 
         return true; 
       } 
       return false; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
       final TextView view = new TextView(mContext); 
       view.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); 
       view.setText(mItems.get(position)); 
       view.setBackgroundColor(Color.rgb(244, 244, 244)); 
       view.setTextColor(Color.BLACK); 

       if (position <= 6) { 
         // names 
         view.setBackgroundColor(Color.argb(100, 10, 80, 255)); 
         view.setHeight(mTitleHeight); 
       } else if (position <= mDaysLastMonth + 6) { 
         // previous month 
         view.setBackgroundColor(Color.rgb(234, 234, 245)); 
         view.setHeight(mDayHeight); 
       } else if (position <= mDaysShown - mDaysNextMonth ) { 
         // current month 
         view.setHeight(mDayHeight); 
         int day = position - (mDaysLastMonth + 6); 
         if (isToday(day, mMonth, mYear)) { 
           view.setTextColor(Color.RED); 
         } 
         // check db and colour for shifts 
         // ... 
       } else { 
         // next month 
         view.setHeight(mDayHeight); 
         view.setBackgroundColor(Color.rgb(234, 234, 245)); 
       } 
       return view; 
     } 

     @Override 
     public int getCount() { 
       return mItems.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
       return mItems.get(position); 
     } 

     @Override 
     public long getItemId(int position) { 
       return position; 
     } 
} 

* logcat的

12-28 21:35:44.873: W/dalvikvm(370): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
12-28 21:35:44.893: E/AndroidRuntime(370): FATAL EXCEPTION: main 
12-28 21:35:44.893: E/AndroidRuntime(370): java.lang.RuntimeException: Unable to start activity ComponentInfo{btn.grid/btn.grid.ButtonGridActivity}: java.lang.ArrayIndexOutOfBoundsException 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.os.Looper.loop(Looper.java:123) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread.main(ActivityThread.java:3683) 
12-28 21:35:44.893: E/AndroidRuntime(370): at java.lang.reflect.Method.invokeNative(Native Method) 
12-28 21:35:44.893: E/AndroidRuntime(370): at java.lang.reflect.Method.invoke(Method.java:507) 
12-28 21:35:44.893: E/AndroidRuntime(370): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
12-28 21:35:44.893: E/AndroidRuntime(370): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
12-28 21:35:44.893: E/AndroidRuntime(370): at dalvik.system.NativeStart.main(Native Method) 
12-28 21:35:44.893: E/AndroidRuntime(370): Caused by: java.lang.ArrayIndexOutOfBoundsException 
12-28 21:35:44.893: E/AndroidRuntime(370): at btn.grid.MonthAdapter.daysInMonth(MonthAdapter.java:82) 
12-28 21:35:44.893: E/AndroidRuntime(370): at btn.grid.MonthAdapter.populateMonth(MonthAdapter.java:62) 
12-28 21:35:44.893: E/AndroidRuntime(370): at btn.grid.MonthAdapter.<init>(MonthAdapter.java:40) 
12-28 21:35:44.893: E/AndroidRuntime(370): at btn.grid.ButtonGridActivity.onCreate(ButtonGridActivity.java:16) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
12-28 21:35:44.893: E/AndroidRuntime(370): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 
12-28 21:35:44.893: E/AndroidRuntime(370): ... 11 more 
+0

如果你可以發佈一些更多的堆棧跟蹤,那就太好了。您現在提供的堆棧跟蹤沒有顯示任何行號,並且您的代碼發佈會稍微大一些。 – kosa 2011-12-28 20:44:10

+0

現在更新logcat。 – 2011-12-28 22:00:18

+0

可以在populateMonth()方法的這些行之前爲mMonth執行System.out.println():if(mMonth == 0) prevDay = daysInMonth(11) - firstDay + 1; else prevDay = daysInMonth(mMonth-1) - firstDay + 1; – kosa 2011-12-28 22:06:46

回答

0

從你的額外stracktrace,你可以看到從ArrayIndexOutOfBoundsException線82.這意味着起源,在異常的結果如下:

int daysInMonth = mDaysInMonth[month]; 

換句話說,在mDaysInMonth中使用無效索引進行查找;可能month > 11雖然它可能也是負面的。

month是你傳遞給參數:

private int daysInMonth(int month) 

,導致外,這個方法的調用從管線62來:

int daysInMonth = daysInMonth(mMonth); 

這意味着,mMonth是無效的指標用於最終的數組查找。由於mMonth正在適配器的構造函數中進行初始化,因此您最好在創建MonthAdapter時檢查通過它的值。

public MonthAdapter(Context c, int month, int year) { 
    (...) 
    mMonth = month; 
    (...) 
}