I’m having a bizarre problem and I’m not sure if I’m doing something wrong or something.
For some reason, my AsyncTask won’t call doInBackground but it calls onPostExecute(). It’s essential that this AsyncTask gets called because it initializes a variable I will need throughout the rest of the app.
I have a nested class in my main activity that extends AsyncTask. This class takes care of downloading file names from the user’s Dropbox account:
protected class FilesLister extends AsyncTask<String, Integer, Long>
{
@Override
protected Long doInBackground(String... params)
{
Log.i("Entries", "We believe Entries has some values now.");
ArrayList<Entry> theFiles = new ArrayList<Entry>();
try
{
Entry entries = mDBApi.metadata("/", 20000, null, true, null);
for (Entry e : entries.contents)
{
Log.i("Hm", e.fileName());
if (!e.isDeleted)
{
if(!e.isDir)
{
theFiles.add(e);
}
}
}
theEntries = theFiles.toArray(new Entry[theFiles.size()]);
} catch (DropboxException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
protected void onPostExecute(Long result)
{
super.onPostExecute(result);
Log.i("Now", "Calling refresh.");
refresh();
}
}
Like you can see, onPostExecute calls a method called refresh(). refresh() is implemented as follows:
public void refresh()
{
//Sort all this files by last modified date.
Arrays.sort(theEntries, new Comparator<Entry>()
{
@Override
public int compare(Entry firstFile, Entry secondFile)
{
//"EEE, dd MMM yyyy kk:mm:ss ZZZZZ"
SimpleDateFormat formater = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss ZZZZZ");
try
{
Date date1 = (Date)formater.parse(firstFile.modified);
Date date2 = (Date)formater.parse(secondFile.modified);
return date1.compareTo(date2);
} catch (ParseException e1)
{
e1.printStackTrace();
}
return 0;
}
});
//Now we create a String[] array to hold the names of all the fetched files...
ArrayList<String>txtFilesNames = new ArrayList<String>();
for(int i = theEntries.length - 1; i >= 0; i--)
{
//Loops goes from top to bottom so the latest file appears at the top of the ListView.
txtFilesNames.add(theEntries[i].fileName());
}
actualFileNames = txtFilesNames.toArray(new String[txtFilesNames.size()]);
ArrayAdapter<String> ad = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, actualFileNames);
lv.setAdapter(ad);
}
I know refresh() is being called for two reasons: LogCat logs “Calling refresh.” and then the app crashes because of a NullPointerException. The null pointer exceptions is thrown because theEntries is indeed null, and it will be null unless doInBackground() gets called. And I know doInBackground is never called due to the null pointer and because the Log I put on it’s body never gets called. So what could cause my doInBackground() method not to get called? If it matters, I execute the AsyncTask in my onResume method, and I don’t execute any other AsyncTasks in either onCreate or onStart.
Are you sure doInBackground isn’t getting called? There are plenty of other ways which could cause theEntries to be null. For instance, an exception here:
could cause theEntries to be null. Also, I think you could do this a better way. Instead of setting theEntries within doInBackground (which is in a different thread than your object was created in) you should instead have that function return the entries which will pass them to onPostExecute.I believe the code would look like this:
Then in your refresh method do the assignment.. Also you should check for null in the refresh method.