android - incomplete asynctask crashes my app -
i using asynctask
in of fragment
, activity
, these work nice. problem when press button or exit app @ time of asynchronous
task execution, app crashes. log cat:
08-16 08:15:34.032: e/androidruntime(21957): fatal exception: main 08-16 08:15:34.032: e/androidruntime(21957): java.lang.illegalstateexception: can not perform action after onsaveinstancestate 08-16 08:15:34.032: e/androidruntime(21957): @ android.support.v4.app.fragmentmanagerimpl.checkstateloss(fragmentmanager.java:1327) 08-16 08:15:34.032: e/androidruntime(21957): @ android.support.v4.app.fragmentmanagerimpl.enqueueaction(fragmentmanager.java:1338) 08-16 08:15:34.032: e/androidruntime(21957): @ android.support.v4.app.backstackrecord.commitinternal(backstackrecord.java:595) 08-16 08:15:34.032: e/androidruntime(21957): @ android.support.v4.app.backstackrecord.commit(backstackrecord.java:574) 08-16 08:15:34.032: e/androidruntime(21957): @ me.kaidul.uhunt.mainactivity.selectitem(mainactivity.java:434) 08-16 08:15:34.032: e/androidruntime(21957): @ me.kaidul.uhunt.mainactivity.access$0(mainactivity.java:387) 08-16 08:15:34.032: e/androidruntime(21957): @ me.kaidul.uhunt.mainactivity$getproblemlisttask.onpostexecute(mainactivity.java:680) 08-16 08:15:34.032: e/androidruntime(21957): @ me.kaidul.uhunt.mainactivity$getproblemlisttask.onpostexecute(mainactivity.java:1) 08-16 08:15:34.032: e/androidruntime(21957): @ android.os.asynctask.finish(asynctask.java:417) 08-16 08:15:34.032: e/androidruntime(21957): @ android.os.asynctask.access$300(asynctask.java:127) 08-16 08:15:34.032: e/androidruntime(21957): @ android.os.asynctask$internalhandler.handlemessage(asynctask.java:429) 08-16 08:15:34.032: e/androidruntime(21957): @ android.os.handler.dispatchmessage(handler.java:99) 08-16 08:15:34.032: e/androidruntime(21957): @ android.os.looper.loop(looper.java:123) 08-16 08:15:34.032: e/androidruntime(21957): @ android.app.activitythread.main(activitythread.java:4627) 08-16 08:15:34.032: e/androidruntime(21957): @ java.lang.reflect.method.invokenative(native method) 08-16 08:15:34.032: e/androidruntime(21957): @ java.lang.reflect.method.invoke(method.java:521) 08-16 08:15:34.032: e/androidruntime(21957): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:868) 08-16 08:15:34.032: e/androidruntime(21957): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:626) 08-16 08:15:34.032: e/androidruntime(21957): @ dalvik.system.nativestart.main(native method)
i not adding here asynctask
code working without pressing button or exiting app. call asynctask
new gettaskdone().execute(parameter)
, there onpostexecute
in every asyctask
.
how can avoid app crashing ?
edit:
now thinking that, problem might not in asynctask
. because other asynctask
working regardless of backpress/exit.
this problematic asynctask:
protected class getproblemlisttask extends asynctask {
@override protected void doinbackground(string... params) { inputstreamreader isr = null; if (hasconnection) { date date = new date(); long savedtime = prefs.getlong(commonutils.last_saved, date.gettime()); long = date.gettime(); if (now - savedtime > fivedays || (now - savedtime <= fivedays && prefs.getboolean( commonutils.problemlistiscached, false) == false)) { if (commonutils.isdebuggable) { log.d("updating", "need update!"); } prefs.edit() .putboolean(commonutils.problemlistiscached, false) .commit(); isr = new jsondownloader().getjsonstringfromurl(params[0]); bufferedreader br = new bufferedreader(isr, buffersize); stringbuilder sb = new stringbuilder(); string line = null; try { while ((line = br.readline()) != null) { sb.append(line + "\n"); } } catch (ioexception e) { log.d("problem", "in file writting"); } writetofile(sb.tostring(), commonutils.file_problem_list); prefs.edit() .putboolean(commonutils.problemlistiscached, true) .commit(); try { isr.close(); } catch (ioexception e) { if (commonutils.isdebuggable) { log.d("isr", e.tostring()); } } try { br.close(); } catch (ioexception e) { if (commonutils.isdebuggable) { log.d("br", e.tostring()); } } prefs.edit().putlong(commonutils.last_saved, now).commit(); } else { if (commonutils.isdebuggable) { log.d("old_copy", "old copy rendering"); } try { isr = new inputstreamreader( openfileinput(commonutils.file_problem_list)); } catch (filenotfoundexception e) { log.d("file_not_found", "file missing!"); } } } else { try { isr = new inputstreamreader( openfileinput(commonutils.file_problem_list)); } catch (filenotfoundexception e) { log.d("file_not_found", "file missing!"); } } if (commonutils.isdebuggable) { log.d("start", "mapping start"); } try { isr = new inputstreamreader( openfileinput(commonutils.file_problem_list)); } catch (filenotfoundexception e1) { } jsonreader reader = new jsonreader(isr); try { reader.beginarray(); while (reader.hasnext()) { reader.beginarray(); problems.put( reader.nextint(), new problems(reader.nextstring(), reader .nextstring(), reader.nextint())); while (reader.hasnext()) reader.skipvalue(); reader.endarray(); } reader.endarray(); reader.close(); } catch (ioexception e) { if (commonutils.isdebuggable) { log.d("problems", "hashmaping problem"); } } return null; } @override protected void onpostexecute(void result) { getsupportactionbar().sethomebuttonenabled(true); getsupportactionbar().setdisplayhomeasupenabled(true); // selecitem() function. it's task add fragment activity. selectitem(0); if (commonutils.isdebuggable) { log.d("successful", "eventually survived!"); } }
}
asynctask's onpreexecute
, onpostexecute
run on ui thread. i'm assuming you're not retaining instance of asynctask , calling cancel on in fragment/activity's ondestroy
.
either add that, or add boolean flag stating if app visible or not (api 17 introduced activity.isdestroyed()
, if you're using api level >= 17 use that).
note: if add call cancel asynctask, you'll still need call along lines of:
if(iscancelled()) { return; }
in beginning of onpostexecute
.
edit: more complete example of iscancelled()
method:
in activity:
protected void ondestroy() { super.ondestroy(); if(task != null && task.getstatus() != asynctask.status.finished) { task.cancel(true); } }
and assign task class-wide variable, can add task =
line that's doing new asynctask().execute();
, it'll work now.
according documentation asynctask.cancel() guarantees onpostexecute never called don't need iscancelled()
check in there stated previously.
Comments
Post a Comment