android - AsyncTask and changes of orientation -
i've problem re-creation of activity, progress dialog , async task when change orientation of screen. saw solutions here , decided use onretaincustomnonconfigurationinstance() save instance of asynctask. well, in oncreate check if there instance of asynctask and, if exist, show new progress dialog. dialog blocks ui in infinite loop (in onpostexecute there dialog.dismiss() ) , activity doesn't show results of course.
oncreate
getdirection = (getdirection) getlastcustomnonconfigurationinstance(); if(getdirection != null) { dialog = new progressdialog(routeactivity.this); dialog.setmessage(getresources().getstring(r.string.loading_data)); dialog.setindeterminate(false); dialog.setcancelable(false); dialog.show(); } else { getdirection = new getdirection(); getdirection.execute(); }
onretaincustomnonconfigurationinstance
@override public object onretaincustomnonconfigurationinstance() { return getdirection; } @override protected void ondestroy() { super.ondestroy(); if (dialog.isshowing()) { dialog.dismiss(); } }
edit #1: adopted solution of kingfisher fragment , retained fragment there npe on expandable listview when change orientation during doinbackground of asynctask.
08-14 12:50:40.866: e/androidruntime(22739): fatal exception: main 08-14 12:50:40.866: e/androidruntime(22739): java.lang.nullpointerexception 08-14 12:50:40.866: e/androidruntime(22739): @ com.pasquini.adapter.listrouteexpandableadapter.getgroupcount(listrouteexpandableadapter.java:78) 08-14 12:50:40.866: e/androidruntime(22739): @ android.widget.expandablelistconnector.getcount(expandablelistconnector.java:399) 08-14 12:50:40.866: e/androidruntime(22739): @ android.widget.listview.setadapter(listview.java:460) 08-14 12:50:40.866: e/androidruntime(22739): @ android.widget.expandablelistview.setadapter(expandablelistview.java:470) 08-14 12:50:40.866: e/androidruntime(22739): @ com.pasquini.activity.routeactivity.onpostexecute(routeactivity.java:792) 08-14 12:50:40.866: e/androidruntime(22739): @ com.pasquini.fragment.getdirectionfragment$getdirectiontask.onpostexecute(getdirectionfragment.java:244) 08-14 12:50:40.866: e/androidruntime(22739): @ com.pasquini.fragment.getdirectionfragment$getdirectiontask.onpostexecute(getdirectionfragment.java:1) 08-14 12:50:40.866: e/androidruntime(22739): @ android.os.asynctask.finish(asynctask.java:631) 08-14 12:50:40.866: e/androidruntime(22739): @ android.os.asynctask.access$600(asynctask.java:177) 08-14 12:50:40.866: e/androidruntime(22739): @ android.os.asynctask$internalhandler.handlemessage(asynctask.java:644) 08-14 12:50:40.866: e/androidruntime(22739): @ android.os.handler.dispatchmessage(handler.java:99) 08-14 12:50:40.866: e/androidruntime(22739): @ android.os.looper.loop(looper.java:137) 08-14 12:50:40.866: e/androidruntime(22739): @ android.app.activitythread.main(activitythread.java:4895) 08-14 12:50:40.866: e/androidruntime(22739): @ java.lang.reflect.method.invokenative(native method) 08-14 12:50:40.866: e/androidruntime(22739): @ java.lang.reflect.method.invoke(method.java:511) 08-14 12:50:40.866: e/androidruntime(22739): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:994) 08-14 12:50:40.866: e/androidruntime(22739): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:761) 08-14 12:50:40.866: e/androidruntime(22739): @ dalvik.system.nativestart.main(native method).
here code in fragment:
public class getdirectionfragment extends fragment { private map<leg, list<step>> legscollection; private arraylist<object> legsandsteps; private list<leg> legs; private list<poi> pois; private list<latlng> polyz; /** * callback interface through fragment report * task's progress , results activity. */ public static interface taskcallbacks { void onpreexecute(); void onpostexecute(); list<poi> getlistpoibyroute(); void setlegs(list<leg> legs, map<leg, list<step>> legscollection); void setpolyline(list<latlng> polyz); } private taskcallbacks callbacks; private getdirectiontask getdirectiontask; /** * hold reference parent activity can report * task's current progress , results. android framework * pass reference newly created activity after * each configuration change. */ @override public void onattach(activity activity) { super.onattach(activity); try { callbacks = (taskcallbacks) activity; } catch(classcastexception e) { throw new classcastexception(activity.tostring() + " must implement taskcallbacks"); } pois = callbacks.getlistpoibyroute(); } /** * method called once when retained * fragment first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // retain fragment across configuration changes. setretaininstance(true); // create , execute background task. getdirectiontask = new getdirectiontask(); getdirectiontask.execute(); } /** * set callback null don't accidentally leak * activity instance. */ @override public void ondetach() { super.ondetach(); callbacks = null; } private class getdirectiontask extends asynctask<void, integer, void> { @override protected void onpreexecute() { if (callbacks != null) { callbacks.onpreexecute(); } } /** * note not call callback object's methods * directly background thread, result * in race condition. */ @override protected void doinbackground(void... ignore) { list<string> lats = new arraylist<string>(); list<string> longs = new arraylist<string>(); for(poi poi: pois) { lats.add(poi.getcoordinates().getlatitude()); longs.add(poi.getcoordinates().getlongitude()); } string stringurl = "http://maps.googleapis.com/maps/api/directions/" + "json?"; //if(actuallanguage.equals("en")) { // stringurl += "language=en_en"; //} else { stringurl += "language=it"; //} stringurl+="&mode=walking&units=metric&origin=" + lats.get(0) + "," + longs.get(0); stringurl += "&destination=" + lats.get(pois.size()-1) + "," + longs.get(pois.size()-1) + "&" + "waypoints="; for(int = 1; i<=lats.size()-2 && i<=longs.size()-2; i++) { stringurl += lats.get(i)+","+longs.get(i); if(i==(lats.size()-2) && i==(longs.size()-2)) { stringurl += "&sensor=false"; } else { stringurl +="|"; } } log.i("urlgoogle", stringurl); stringbuilder response = new stringbuilder(); try { url url = new url(stringurl); httpurlconnection httpconn = (httpurlconnection) url .openconnection(); if (httpconn.getresponsecode() == httpurlconnection.http_ok) { bufferedreader input = new bufferedreader( new inputstreamreader(httpconn.getinputstream()), 8192); string strline = null; while ((strline = input.readline()) != null) { response.append(strline); } input.close(); } string jsonoutput = response.tostring(); jsonobject jsonobject = new jsonobject(jsonoutput); // routesarray contains routes jsonarray routesarray = jsonobject.getjsonarray("routes"); // grab first route jsonobject route = routesarray.getjsonobject(0); jsonarray legsarray = route.getjsonarray("legs"); legs = new arraylist<leg>(); legsandsteps = new arraylist<object>(); string htmlinstructions; legscollection = new linkedhashmap<leg, list<step>>(); for(int i=0; i<legsarray.length(); i++) { list<step> steps = new arraylist<step>(); leg leg = new leg(); //int idleg = 0; jsonobject legjson = legsarray.getjsonobject(i); leg.setdistance(legjson.getjsonobject("distance").getstring("text")); leg.setduration(legjson.getjsonobject("duration").getstring("text")); leg.setendaddress(legjson.getstring("end_address")); leg.setstartaddress(legjson.getstring("start_address")); leg.setidleg(pois.get(i).getid()); leg.setstartpoiname(pois.get(i).getname()); leg.setendpoiname(pois.get(i+1).getname()); legsandsteps.add(leg); jsonarray stepsarray = legjson.getjsonarray("steps"); for(int j=0; j<stepsarray.length(); j++) { step step = new step(); jsonobject stepjson = stepsarray.getjsonobject(j); step.setdistance(stepjson.getjsonobject("distance").getstring("text")); step.setduration(stepjson.getjsonobject("duration").getstring("text")); htmlinstructions = android.text.html.fromhtml(stepjson.getstring("html_instructions")).tostring(); step.setinstructions(htmlinstructions); //step.setidleg(idleg); //aggiunto per exp steps.add(step); legsandsteps.add(step); } legscollection.put(leg, steps); legs.add(leg); } jsonobject poly = route.getjsonobject("overview_polyline"); string polyline = poly.getstring("points"); polyz = decodepoly(polyline); callbacks.setlegs(legs, legscollection); callbacks.setpolyline(polyz); } catch (exception e) { } return null; } @override protected void onpostexecute(void ignore) { if (callbacks != null) { callbacks.onpostexecute(); } } } /* method decode polyline points */ private list<latlng> decodepoly(string encoded) { [code...] }
}
here code in activity:
@override public void onpostexecute() { explistview = (expandablelistview) findviewbyid(r.id.lv_routepoi); listrouteexpandableadapter explistadapter = new listrouteexpandableadapter( getapplicationcontext(), legs, legscollection); explistview.setadapter(explistadapter); setgroupindicatortoright(); explistview.setchilddivider(getresources().getdrawable(r.drawable.divider_route)); [code...] dialog.dismiss(); } @override public void setlegs(list<leg> legs, map<leg, list<step>> legscollection) { this.legs = legs; this.legscollection = legscollection; } @override public void setpolyline(list<latlng> polyz) { this.polyz = polyz; }
edit #2: tried new solution of kingfisher there npe in doinbackground method. if don't change orientation of screen during loading, app doesn't crash , show data on listview.
08-14 17:27:44.897: i/asynctask(30604): java.lang.nullpointerexception 08-14 17:27:44.897: e/androidruntime(30604): fatal exception: main 08-14 17:27:44.897: e/androidruntime(30604): java.lang.nullpointerexception 08-14 17:27:44.897: e/androidruntime(30604): @ com.pasquini.activity.routeactivity.onpostexecute(routeactivity.java:847) 08-14 17:27:44.897: e/androidruntime(30604): @ com.pasquini.fragment.getdirectionfragment$getdirectiontask.onpostexecute(getdirectionfragment.java:253) 08-14 17:27:44.897: e/androidruntime(30604): @ com.pasquini.fragment.getdirectionfragment$getdirectiontask.onpostexecute(getdirectionfragment.java:1) 08-14 17:27:44.897: e/androidruntime(30604): @ android.os.asynctask.finish(asynctask.java:631) 08-14 17:27:44.897: e/androidruntime(30604): @ android.os.asynctask.access$600(asynctask.java:177) 08-14 17:27:44.897: e/androidruntime(30604): @ android.os.asynctask$internalhandler.handlemessage(asynctask.java:644) 08-14 17:27:44.897: e/androidruntime(30604): @ android.os.handler.dispatchmessage(handler.java:99) 08-14 17:27:44.897: e/androidruntime(30604): @ android.os.looper.loop(looper.java:137) 08-14 17:27:44.897: e/androidruntime(30604): @ android.app.activitythread.main(activitythread.java:4895) 08-14 17:27:44.897: e/androidruntime(30604): @ java.lang.reflect.method.invokenative(native method) 08-14 17:27:44.897: e/androidruntime(30604): @ java.lang.reflect.method.invoke(method.java:511) 08-14 17:27:44.897: e/androidruntime(30604): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:994) 08-14 17:27:44.897: e/androidruntime(30604): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:761) 08-14 17:27:44.897: e/androidruntime(30604): @ dalvik.system.nativestart.main(native method)
here code in fragment:
public class getdirectionfragment extends fragment { private map<leg, list<step>> legscollection; private arraylist<object> legsandsteps; private list<leg> legs; private list<poi> pois; private list<latlng> polyz; /** * callback interface through fragment report * task's progress , results activity. */ public static interface taskcallbacks { void onpreexecute(); void onpostexecute(); list<poi> getlistpoibyroute(); void setlegs(list<leg> legs, map<leg, list<step>> legscollection); void setpolyline(list<latlng> polyz); } private taskcallbacks callbacks; private getdirectiontask getdirectiontask; /** * hold reference parent activity can report * task's current progress , results. android framework * pass reference newly created activity after * each configuration change. */ @override public void onattach(activity activity) { super.onattach(activity); try { callbacks = (taskcallbacks) activity; } catch(classcastexception e) { throw new classcastexception(activity.tostring() + " must implement taskcallbacks"); } pois = callbacks.getlistpoibyroute(); } /** * method called once when retained * fragment first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // retain fragment across configuration changes. setretaininstance(true); // create , execute background task. getdirectiontask = new getdirectiontask(); getdirectiontask.execute(); } /** * set callback null don't accidentally leak * activity instance. */ @override public void ondetach() { super.ondetach(); callbacks = null; } private class getdirectiontask extends asynctask<void, integer, void> { @override protected void onpreexecute() { if (callbacks != null) { callbacks.onpreexecute(); } } /** * note not call callback object's methods * directly background thread, result * in race condition. */ @override protected void doinbackground(void... ignore) { list<string> lats = new arraylist<string>(); list<string> longs = new arraylist<string>(); for(poi poi: pois) { lats.add(poi.getcoordinates().getlatitude()); longs.add(poi.getcoordinates().getlongitude()); } string stringurl = "http://maps.googleapis.com/maps/api/directions/" + "json?"; //if(actuallanguage.equals("en")) { // stringurl += "language=en_en"; //} else { stringurl += "language=it"; //} stringurl+="&mode=walking&units=metric&origin=" + lats.get(0) + "," + longs.get(0); stringurl += "&destination=" + lats.get(pois.size()-1) + "," + longs.get(pois.size()-1) + "&" + "waypoints="; for(int = 1; i<=lats.size()-2 && i<=longs.size()-2; i++) { stringurl += lats.get(i)+","+longs.get(i); if(i==(lats.size()-2) && i==(longs.size()-2)) { stringurl += "&sensor=false"; } else { stringurl +="|"; } } log.i("urlgoogle", stringurl); stringbuilder response = new stringbuilder(); try { url url = new url(stringurl); httpurlconnection httpconn = (httpurlconnection) url .openconnection(); if (httpconn.getresponsecode() == httpurlconnection.http_ok) { bufferedreader input = new bufferedreader( new inputstreamreader(httpconn.getinputstream()), 8192); string strline = null; while ((strline = input.readline()) != null) { response.append(strline); } input.close(); } string jsonoutput = response.tostring(); jsonobject jsonobject = new jsonobject(jsonoutput); // routesarray contains routes jsonarray routesarray = jsonobject.getjsonarray("routes"); // grab first route jsonobject route = routesarray.getjsonobject(0); jsonarray legsarray = route.getjsonarray("legs"); legs = new arraylist<leg>(); legsandsteps = new arraylist<object>(); string htmlinstructions; legscollection = new linkedhashmap<leg, list<step>>(); for(int i=0; i<legsarray.length(); i++) { list<step> steps = new arraylist<step>(); leg leg = new leg(); //int idleg = 0; jsonobject legjson = legsarray.getjsonobject(i); leg.setdistance(legjson.getjsonobject("distance").getstring("text")); leg.setduration(legjson.getjsonobject("duration").getstring("text")); leg.setendaddress(legjson.getstring("end_address")); leg.setstartaddress(legjson.getstring("start_address")); leg.setidleg(pois.get(i).getid()); leg.setstartpoiname(pois.get(i).getname()); leg.setendpoiname(pois.get(i+1).getname()); legsandsteps.add(leg); jsonarray stepsarray = legjson.getjsonarray("steps"); for(int j=0; j<stepsarray.length(); j++) { step step = new step(); jsonobject stepjson = stepsarray.getjsonobject(j); step.setdistance(stepjson.getjsonobject("distance").getstring("text")); step.setduration(stepjson.getjsonobject("duration").getstring("text")); htmlinstructions = android.text.html.fromhtml(stepjson.getstring("html_instructions")).tostring(); step.setinstructions(htmlinstructions); //step.setidleg(idleg); steps.add(step); legsandsteps.add(step); } legscollection.put(leg, steps); legs.add(leg); } jsonobject poly = route.getjsonobject("overview_polyline"); string polyline = poly.getstring("points"); polyz = decodepoly(polyline); setlegs(legs, legscollection); setpolyline(polyz); } catch (exception e) { log.i(tag, e.tostring()); } return null; } @override protected void onpostexecute(void ignore) { if (callbacks != null) { callbacks.onpostexecute(); } } } /* method decode polyline points */ private list<latlng> decodepoly(string encoded) { [code...] } public void setlegs(list<leg> legs, map<leg, list<step>> legscollection) { this.legs = legs; this.legscollection = legscollection; } public void setpolyline(list<latlng> polyz) { this.polyz = polyz; } public list<leg> getlegs() { return this.legs; } public map<leg, list<step>> getmap() { return this.legscollection; } public list<latlng> getpolyline() { return this.polyz; }
}
here code in activity:
@override protected void oncreate(bundle savedinstancestate) { [code...] fragmentmanager fm = getsupportfragmentmanager(); getdirectionfragment = (getdirectionfragment) fm.findfragmentbytag(task_fragment_tag); // if fragment non-null, being // retained across configuration change. if (getdirectionfragment == null) { getdirectionfragment = new getdirectionfragment(); fm.begintransaction().add(getdirectionfragment, task_fragment_tag).commit(); [code...] } @override public void onpostexecute() { legs = getdirectionfragment.getlegs(); legscollection = getdirectionfragment.getmap(); polyz = getdirectionfragment.getpolyline(); explistview = (expandablelistview) findviewbyid(r.id.lv_routepoi); listrouteexpandableadapter explistadapter = new listrouteexpandableadapter( getapplicationcontext(), legs, legscollection); explistview.setadapter(explistadapter); setgroupindicatortoright(); explistview.setchilddivider(getresources().getdrawable(r.drawable.divider_route)); [code...] }
check link: handling configuration changes fragments or can use asynctaskloader. recommend use retained fragment
handle configuration changes. read article carefully. edited: dont call callback.set
function in doinbackground
.you should find retained fragment
when activity re-created, , in onpost function
try use retained fragment
's function list result.
//activity recreated fragmentmanager fm = getfragmentmanager(); mtaskfragment = (taskfragment) fm.findfragmentbytag("task"); //onpost method yourlist = mtaskfragment.getlegsandmovelist(); // lisview data changing here
hope help.
Comments
Post a Comment