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

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -