Thursday 29 September 2016

java - onPostExecute is only sometimes called in AsyncTask



My AsyncTask is executed in my MainActivity, but it doesn't call onPostExecute. The method doInBackground is finished until the return statement (checked with System.out)!




The Call:



@Override
protected void onStart() {
super.onStart();

if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);


if (CheckPermissions()) {
Prepare();
}
}
}

private void Prepare() {
MusicStore musicStore = new MusicStore(getApplicationContext());

sSongs = musicStore.getSongs();


StoreParcel storeParcel = new StoreParcel(StoreParcel.StoreAction.READ_PLAYLISTS, this);

musicStore.execute(storeParcel);

if (sSongs.length < 1) {
fabPlayPause.hide();

snbInformation = Snackbar.make(recyclerView, getString(R.string.snb_Information) + "Music.", Snackbar.LENGTH_INDEFINITE);
snbInformation.show();

}
else {
fabPlayPause.show();
}

bindService(playIntent, musicServiceConn, BIND_AUTO_CREATE);

startService(playIntent);
}



The AsyncTask:



public class MusicStore extends AsyncTask {
private Context mContext;

public MusicStore(Context context) {
mContext = context;
}


//region AsyncTask

@Override
protected StoreParcel doInBackground(StoreParcel... params) {
StoreParcel parcel = params[0];

StoreParcel storeParcel = new StoreParcel(parcel.getAction(), parcel.getPlaylistInterface());

switch (parcel.getAction()) {
case WRITE_PLAYLISTS:

WritePlaylists(parcel.getPlaylists());
break;
case READ_PLAYLISTS:
storeParcel.setPlaylists(ReadPlaylists());
break;
}

return storeParcel;
}


@Override
protected void onPostExecute(StoreParcel storeParcel) {
if (storeParcel.getAction() == StoreParcel.StoreAction.READ_PLAYLISTS) {
storeParcel.getPlaylistInterface().SyncPlaylists(storeParcel.getPlaylists());
}

super.onPostExecute(storeParcel);
}

//region Methods


private void WritePlaylists(Playlist[] playlists) {
File dir = new File(mContext.getFilesDir() + Preferences.dirPlaylists);

if (!dir.exists()) {
dir.mkdirs();
}

for (File f : dir.listFiles()) {
f.delete();

}

if (playlists == null) return;

String sFilename;
File file;

for (int i = 0; i < playlists.length; i++) {
sFilename = playlists[i].getName();


try {
file = new File(dir, sFilename + ".json");
file.createNewFile();

Writer writer = new OutputStreamWriter(new FileOutputStream(file));

Gson gson = new GsonBuilder().create();
gson.toJson(playlists[i], writer);

writer.close();

}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

private Playlist[] ReadPlaylists() {
Playlist[] playlists;


File dir = new File(mContext.getFilesDir() + Preferences.dirPlaylists);

File[] files = dir.listFiles();

if (files == null) return null;

playlists = new Playlist[files.length];

Reader reader = null;


try {
for (int i = 0; i < files.length; i++) {
reader = new InputStreamReader(new FileInputStream(files[i]));

Gson gson = new GsonBuilder().create();
playlists[i] = gson.fromJson(reader, Playlist.class);
}

if (reader != null) reader.close();
}

catch (IOException ioe) {
ioe.printStackTrace();
}

return playlists;
}

//endregion

//endregion

}


The StoreParcel is a class created by me! It only countains an Interface, and an Enum-Value!


Answer



I think you should run the task in onResume so you are the ui exists. You can do UI stuff in onStart and onPostExecute has to run on UI thread.



@Override
protected void onStart() {
super.onStart();


if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);
}
}

@Override
protected void onStart() {
super.onStart();
if (CheckPermissions()) {

Prepare();
}
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...