3

My code is throwing an IndexOutOfBounds exception at some point (can't figure out where). The exception log below:

12-09 15:03:59.962: ERROR/AndroidRuntime(8735): FATAL EXCEPTION: main
    Process: br.com.app, PID: 8735
    java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    at java.util.ArrayList.get(ArrayList.java:308)
    at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:225)
    at android.widget.AbsListView.obtainView(AbsListView.java:2240)
    at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
    at android.widget.ListView.onMeasure(ListView.java:1175)
    at android.view.View.measure(View.java:16458)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
    at android.view.View.measure(View.java:16458)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.view.View.measure(View.java:16458)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
    at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
    at android.view.View.measure(View.java:16458)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2289)
    at android.view.View.measure(View.java:16458)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1914)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1111)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1293)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5582)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
    at android.view.Choreographer.doFrame(Choreographer.java:532)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4998)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
    at dalvik.system.NativeStart.main(Native Method)

As you can see, this log doesn't show any class I wrote myself. To understand better what is happening, here is what my app do at this point: - A http request is made to fetch an array of data from server - I use this array to populate a ListView with several options user can choose

After a few tests, I've noticed that this error only occurs when the jsonArray I get from server has between 1 and 7 elements. If a specific search returns, let's say, 0, 7, 40 items, everything is ok. When I get only one element, or 4 elements, the app crashes.. No idea at all why this happens...

the method below is executed right after I get response from server:

private void didDownload(JSONObject result) {
    try {
        listingsArray = concatArray(listingsArray, result.getJSONArray("empresas"));
        Location currentLocation = PreferenceData.getUserLocation(myContext);
        for(int i = 0, j = listingsArray.length(); i < j; i++){

            JSONObject c = listingsArray.getJSONObject(i);
            JSONObject listing      = c.getJSONObject("listing");
            double listingLatitude  = listing.getDouble("latitude");
            double listingLongitude = listing.getDouble("longitude");
            Location listingLocation = new Location("");
            listingLocation.setLongitude(listingLongitude);
            listingLocation.setLatitude(listingLatitude);
            float distance = currentLocation.distanceTo(listingLocation);
            listingsArray.getJSONObject(i).put("distancia", distance);
        }

        imageURLs = new String[listingsArray.length()];
        for(int i = 0; i < listingsArray.length(); i++) {
            String url = ImageUrlBuilder.buildURL(listingsArray.getJSONObject(i).getString("thumb"), myContext, "thumb");
            imageURLs[i] = url;
        }

    } catch (JSONException e) {
        Log.e(TAG, "Erro no Json");
    }

    tamanho = listingsArray.length();
    cacheUpdated();
}

while debugging, step by step, the method below was the last one I could follow before the crash (this one runs in a worker thread, from another class, to load images into my listview items)

class PhotosLoader implements Runnable {
    PhotoToLoad photoToLoad;
    PhotosLoader(PhotoToLoad photoToLoad){
        this.photoToLoad=photoToLoad;
    }

    @Override
    public void run() {
        try{
            if(imageViewReused(photoToLoad))
                return;
            Bitmap bmp=getBitmap(photoToLoad.url);
            memoryCache.put(photoToLoad.url, bmp);
            if(imageViewReused(photoToLoad))
                return;
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
            handler.post(bd); //here is where I can't debug further... The IndexOutOfBounds exception isn't caught below...
        }catch(Exception e){
            e.printStackTrace();
            Crashlytics.logException(e);
        }
    }
}

I'm not sure if these methods have something to do with the error... Thanks in advance for any directions on this!

[UPDATE] getView():

/**
 * Create a new ImageView when requested, filling it with a
 * thumbnail or a blank image if no thumb is ready yet.
 */
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    // check if user reached end of list
    if(shouldLoadMoreData(position)){
        loadMoreData();
    }

    // can we recycle an old view?
    if(convertView == null) {
        convertView = mInflater.inflate(R.layout.listing_listview_item, parent, false);
        holder = new ViewHolder();

        holder.listingTitle = (TextView) convertView.findViewById(R.id.listingTitle);
        holder.distancia    = (TextView) convertView.findViewById(R.id.distancia);
        holder.address      = (TextView) convertView.findViewById(R.id.address);
        holder.promotions   = (TextView) convertView.findViewById(R.id.promotions);
        holder.img          = (ImageView) convertView.findViewById(R.id.img);
        holder.loading      = (ProgressBar) convertView.findViewById(R.id.loading);

        convertView.setTag(holder);

    } else {

        holder = (ViewHolder) convertView.getTag();

    }

    try {
        JSONObject c        = listingsArray.getJSONObject(position);
        JSONObject listing  = c.getJSONObject("listing");
        double distance     = c.getDouble("distancia");
        String dist = (distance > 1000) ? String.format("%.1fkm", distance/1000) : String.format("%dm", (int)distance);
        int p               = c.getInt("promotions");
        String promotions = (p > 1) ? p+" Ofertas" : p+" Oferta";
        holder.listingTitle.setText(listing.getString("title"));
        holder.address.setText(listing.getString("address"));
        holder.promotions.setText(promotions);
        holder.distancia.setText(dist);

    } catch (JSONException e) {
        e.printStackTrace();
    }

    // do we have a thumb stored in cache?
    imageLoader.DisplayImage(imageURLs[position], holder.img, holder.loading);

    return convertView;
}
Lucas Jota
  • 1,863
  • 4
  • 24
  • 43
  • Have you tried debugging it step by step? Where does the error pops up? – nstosic Dec 09 '13 at 17:30
  • Can you show the implementation of the `.post()` method in the `Handler` class? – Math Dec 09 '13 at 17:37
  • @NitroNbg I did it, and runned every step until reach handler.post(bd); statement. This is running in a worker thread, so I've tried sleep() and the exception is thrown before the thread wakes up – Lucas Jota Dec 09 '13 at 17:40
  • @Math handler is instantiated like: `Handler handler=new Handler();//handler to display images in UI thread`. when I go to handler.post declaration, it takes me to `post(Runnable r)`method from Handler.java class in android.os package – Lucas Jota Dec 09 '13 at 17:44
  • Is it a samsung phone? If it is check http://stackoverflow.com/questions/8431342/listview-random-indexoutofboundsexception-on-froyo/8433777#8433777 – 4J41 Dec 09 '13 at 17:46
  • @Ajai its actually a LG Nexus, but I'll take a look on it (I'm using an footerview and an endless scrollview too) – Lucas Jota Dec 09 '13 at 17:50
  • @LucasJota: This might help too. http://stackoverflow.com/questions/8256626/android-index-out-of-bounds-error-with-no-application-code-in-stack-trace – 4J41 Dec 09 '13 at 17:53
  • You have trouble with a ListView adapter, as the app crashes in it's getView() method. It is here that you're trying to access element 0 in an ArrayList that is empty – CSmith Dec 09 '13 at 18:22
  • 1
    @CSmith I'm updating my question with my overrided getView(). Anyway, following Ajai's advice, I removed the viewFooter from my adapter and the exception is gone... Maybe something was happening when getView's position matches viewFooter index? – Lucas Jota Dec 09 '13 at 18:35
  • Your `getView()` method is never called. The stacktrace shows that the `getView` of `HeaderViewListAdapter` is called instead. Can you post the class declaration, where you override `getView`? – jboi Dec 09 '13 at 19:17
  • @jboi this class is declared as `public class ListingsAdapter extends BaseAdapter`, and I @override getView() on it's body... am I doing it wrong? – Lucas Jota Dec 09 '13 at 19:34
  • Well, is something wrong with it? Yes, because your inmplementation is not called and does not show up in the stacktrace. What exactly is wrong with it? I don't know. I need the source of the class where `getView` is overwritten. – jboi Dec 09 '13 at 20:00

0 Answers0