IndexOutOfBoundsException While Accessing the listview through Adapter-Collection of common programming errors

I have implemented my ListView and i am populating the list with custom adapter that extends the BaseAdapter and using the .NET based service , pulling and populating the values in the list. This works fine, but when i tried to continuously do some operations on the list(like deleting the entries, Refreshing, Editing..), I am getting the following error. This error doesn’t comes all the time. But comes 1 out of 15/20 tries.

Trying to resolve, Roaming around the web , to find out why doesn’t it occur.. Still Searching…

11-25 21:38:39.257: ERROR/AndroidRuntime(2169): Uncaught handler: thread main
                    exiting due to uncaught exception

11-25 21:38:39.325: ERROR/AndroidRuntime(2169): java.lang.IndexOutOfBoundsException:
                    Invalid location 0, size is 0

11-25 21:38:39.325: ERROR/AndroidRuntime(2169):at 
                     java.util.ArrayList.get(ArrayList.java:341)

ListActivity class : STSBankDetailsListingScreenActivity.java

 public class STSBankDetailsListingScreenActivity extends ListActivity implements Runnable {

// All my Declarations are here....

   ...........................
.....................
        ...................

private STSAddClientBankDetailsListingScreenAdapter mBankDetailsAdapter = null;


@Override
public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "onCreate");
    super.onCreate(savedInstanceState);
    .......................
    ......................
    // Set the activity content from the XML resource
    setContentView(R.layout.XXX);

    .....................
    .....................

    // Set the typeface with the specified font
    ........................................................
    .........................................................
    // Initializing the progress dialog to show the loading status
    mProgressDialog = ProgressDialog.show(this,"Loading....","Please wait");


    // Capture the widgets that are defined in the XML resource
    mBack = (Button) findViewById(R.id.backButton);

    .................................
    ................................
    // Setting the custom fonts & Text
    ................................
    ...............................

    // Create a Thread for long running operations
    mThread = new Thread(STSBankDetailsListingScreenActivity.this);
    mThread.start();

    // Instantiate the listview adapter class
    mBankDetailsAdapter = new  STSAddClientBankDetailsListingScreenAdapter(this);

    // Adding the listners for the items in the listview
    getListView().setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {

    mDetailsHolder = new ArrayList();
    mDetailsHolder.add(STSURLConstants.AUTH_KEY);
    mDetailsHolder.add(mBankICode.get(position).toString());
    mDetailsHolder.add(mUserTypeHolder.get(position).toString());
    mDetailsHolder.add(mAccountNameHolder.get(position).toString());
    mDetailsHolder.add(mBankCodeHolder.get(position).toString());
    mDetailsHolder.add(mBankNameHolder.get(position).toString());
    mDetailsHolder.add(mBankAddressHolder.get(position).toString());
    mDetailsHolder.add(mOpeningBalanceHolder.get(position).toString());
    mDetailsHolder.add(mAmtInHolder.get(position).toString());

    }

    });
}

@Override
protected void onStart() {
    Log.i(TAG, "onStart");
    super.onStart();
}

@Override
protected void onRestart() {
    Log.i(TAG, "onRestart");
// Show the Progress Dialog 
mProgressDialog = ProgressDialog.show(STSBankDetailsListingScreenActivity.this,     "Loading...", "Please wait");
// Create a Thread for long running operations
    mThread = new Thread(STSBankDetailsListingScreenActivity.this);
    mThread.start();
    super.onRestart();
}

@Override
protected void onPause() {
    Log.i(TAG, "onPause");
    super.onPause();
}

@Override
protected void onResume() {
    Log.i(TAG, "onResume");
    //updateUI();
    super.onResume();
}

@Override
protected void onStop() {
    Log.i(TAG, "onStop");
    super.onStop();
}

@Override
protected void onDestroy() {
    Log.i(TAG, "onDestroy");
    if(mThread != null) {
        Thread dummyThread = mThread;
        mThread = null;
           // Post an interrupt request to this thread
        dummyThread.interrupt(); 
    }
    super.onDestroy();
}

@Override
public void run() {
    // TODO Auto-generated method stub
    try {
        // Clear the arraylist before adding up the entries
        mBankNameHolder.clear(); 
        ..............................

        // Instantiate the class 
        mWSConsumer = new STSWebServiceConsumer();
        // Call to fetch the bank details from the service
        mSTSSelectBankAccountList = mWSConsumer.SelectBankAccountDetails();

// Do the necessary actions to pull the values from the list
for(STSSelectBankAccountDetails s : mSTSSelectBankAccountList) {
// Populate the list....
mBankNameHolder.add(String.valueOf(s.getmBaBankName().toString()));
...............................
...............................
}
} else { Log.i(TAG, "Something went wrong !"); }
        } catch(Exception err) {
        err.printStackTrace();
    } 
    handler.sendEmptyMessage(0);  }

private void updateUI() {
Log.i(TAG, "updateUI");
runOnUiThread(new Runnable() {
    @Override
    public void run() {
    try {
    // Set the data behind the list view
 mBankDetailsAdapter = new  STSAddClientBankDetailsListingScreenAdapter(STSBankDetailsListingScreenActivity.this,           mBankNameHolder, mAccountNameHolder, mIsCheckedHolder);
    getListView().setAdapter(mBankDetailsAdapter);
    // Notifies the attached view that the underlying data has been changed
    mBankDetailsAdapter.notifyDataSetChanged();
    } catch(Exception err) {
        err.printStackTrace();      }
        }
        });
    }

public Handler handler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        switch (msg.what) {
        case 0:
            // Do Nothing...
            break;
        case 1:
            // Calls the run method of the runnable object
            mThread.run();
            break;
        default:
            break;
        }
        // Update the UI
        updateUI();

        // Dismiss the progress dialog once done
        if(mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
            //mQuickAction.dismiss();
        }
    }
};

}

Adapter class : STSAddClientBankDetailsListingScreenAdapter.java

public class STSAddClientBankDetailsListingScreenAdapter extends
    BaseAdapter {
// Declare all the needed
private Activity mActivity = null;
private List mBankNameHolder = new ArrayList();
private List mAccountNameHolder = new ArrayList();
private List mIsChecked = new ArrayList();

private static final String TAG = STSAddClientBankDetailsListingScreenAdapter.class.getSimpleName();
private static LayoutInflater mLayoutInflater = null; // This class is responsible for instantiating the layout XML file in to its corresponding view objects

public STSAddClientBankDetailsListingScreenAdapter(Context context) {
    // Obtains the layout interface from the given context
    mLayoutInflater = LayoutInflater.from(context);
}

public STSAddClientBankDetailsListingScreenAdapter(Activity activity, List bankName, List accountName, List isChecked) {
    mActivity = activity;
    mBankNameHolder = bankName;
    mAccountNameHolder = accountName;
    mIsChecked = isChecked;
}
/* (non-Javadoc)
 * @see android.widget.Adapter#getCount()
 */
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return mBankNameHolder.size();
}

/* (non-Javadoc)
 * @see android.widget.Adapter#getItem(int)
 */
@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

/* (non-Javadoc)
 * @see android.widget.Adapter#getItemId(int)
 */
@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

/* (non-Javadoc)
 * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
 */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder viewHolder;
    if(convertView == null) {
        convertView = mLayoutInflater.inflate(R.layout.profile_client_bank_details_listing_item, null);
        viewHolder = new ViewHolder();
        // Capture the widgets defined in the XML resource
        viewHolder.mBankName = (TextView) convertView.findViewById(R.id.message01);
        viewHolder.mAccountName = (TextView) convertView.findViewById(R.id.message02);
        viewHolder.mChecked = (ImageView) convertView.findViewById(R.id.image01);
        convertView.setTag(viewHolder); // Set the tag associated with this view
     } else {
         viewHolder = (ViewHolder) convertView.getTag(); // Returns the view tag
         }
    // Bind the controls with the resource
    viewHolder.mBankName.setText(mBankNameHolder.get(position).toString());
    viewHolder.mAccountName.setText(mAccountNameHolder.get(position).toString());
    // Set the tick mark according to the values
    boolean checked = Boolean.parseBoolean(mIsChecked.get(position).toString());
    if(checked) {
        viewHolder.mChecked.setVisibility(View.VISIBLE);
    } else {
        viewHolder.mChecked.setVisibility(View.INVISIBLE);
    }
    return convertView;
}

static class ViewHolder {
    TextView mBankName, mAccountName;
    ImageView mChecked;
}

}

Please if Any sort of help is highly appreciated.

Thank you once again…

  1. what I strongly feel is that your adapter method – getCount() gives wrong output in that particular case. I would suggest not to take size from mBankNameHolder take size from some other parameter or check this value with log/debug in each case.

    public int getCount() {
        // TODO Auto-generated method stub
        return mBankNameHolder.size();
    }