java - Android : How to Pass the JSON object From AsncTask class to the Main Class -


i have jsonobject receiving api call within asynctask class. want pass json object mainactivity class show jsonobject data in gui. found solutions throughout searches , came close solution. when access mainactivity class says jsonobject null. have dont wrong here? best way ?

following asynctask class

import android.content.context; import android.os.asynctask; import android.util.log;  import org.apache.http.httpentity; import org.apache.http.httpresponse; import org.apache.http.client.httpclient; import org.apache.http.client.methods.httpget; import org.apache.http.impl.client.defaulthttpclient; import org.apache.http.util.entityutils; import org.json.jsonobject;  /**  * created nisal on 13-sep-17.  */  public class getstationsapicall extends asynctask<string, void, jsonobject> {      context ctx;     jsonobject responseobj;     string result;      public interface asyncresponse {         void processfinish(jsonobject output);     }      public asyncresponse delegate = null;      public getstationsapicall(asyncresponse delegate){         this.delegate = delegate;     }  //    getstationsapicall(context ctx){ //        this.ctx=ctx; //    }      @override     protected jsonobject doinbackground(string... params) {          string method = params[0];          if(method.equals("getstations")){              try {                 httpclient client = new defaulthttpclient();                 string geturl = "http://api.gate.com/?lang=en";                 httpget httpget = new httpget(geturl);                 httpget .setheader("authorization", "bearer 690");                  httpresponse response = client.execute(httpget);                 httpentity resentity = response.getentity();                 if (resentity != null) {                     //parse response.                     log.e("response", entityutils.tostring(resentity)); //                    return "successfully connected!";                 }else{ //                    return "connection failed!";                 }              } catch (exception e) {                 e.printstacktrace(); //                return "connection failed!";             }         }          return null;     }      @override     protected void onprogressupdate(void... values) {         super.onprogressupdate(values);     }      @override     protected void onpostexecute(jsonobject obj) {         delegate.processfinish(obj);     } } 

following mainactivity class

import android.app.activity; import android.os.bundle; import android.view.view; import android.widget.button; import android.widget.toast;  import org.json.jsonobject;  public class mainactivity extends activity implements getstationsapicall.asyncresponse{      button btnsearch;     string method = "getstations";      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          getstationsapicall getstations = new getstationsapicall(this);         new getstationsapicall(this).execute(method);     }      public void searchclicked(view view){         toast.maketext(mainactivity.this,"search clicked",toast.length_short).show();     }      @override     public void processfinish(jsonobject output) {         toast.maketext(mainactivity.this,"processfinish",toast.length_short).show();          if(output != null){             toast.maketext(mainactivity.this,"not null",toast.length_short).show();         }else{             toast.maketext(mainactivity.this," null",toast.length_short).show();         }     } } 

i can jsonobject within asynctask class, when try pass mainactivity class , use there. jsonobject becomes null. have done wrong here?

although i'm sure got working solution, wouldn't recommend making activity listener potentially leak (what happens if press home button before result back?). also, mentioned previously, main problem had returning null doinbackground function. let's address these 2 issues now:

mainactivity.java

import android.app.activity; import android.os.bundle; import android.view.view; import android.widget.button; import android.widget.toast; import android.content.broadcastreceiver; import android.content.intentfilter; import android.support.v4.content.localbroadcastmanager;  import org.json.jsonobject;  public class mainactivity extends activity {      button btnsearch;     string method = "getstations";     broadcastreceiver apilistener;      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          broadcastreceiver apilistener = new broadcastreceiver() {             @override             public void onreceive(context context, intent intent) {                 string output = intent.getstringextra("api_response); //getting string input earlier in asynctask.                 toast.maketext(mainactivity.this,"processfinish",toast.length_short).show();                  if(output != null){                     toast.maketext(mainactivity.this,"not null",toast.length_short).show();                 }else{                     toast.maketext(mainactivity.this," null",toast.length_short).show();                 }             }         };          //since starting asynctask here, might want set receiver prior calling task.         localbroadcastmanager.getinstance(this).registerreceiver(apilistener, new intentfilter(""));          getstationsapicall getstations = new getstationsapicall(this);         new getstationsapicall(this).execute(method);     }      public void searchclicked(view view){         toast.maketext(mainactivity.this,"search clicked",toast.length_short).show();     }      //registers receiver whenever acitivty being shown or to.     @override     public void onstart() {         super.onstart();         localbroadcastmanager.getinstance(this)             .registerreceiver(apilistener, new intentfilter("stationsapi")); //this intent filter receiver listening     }      //this stops receiver listening when activity no longer shown.     @override     public void onstop() {         super.onstop();         localbroadcastmanager.getinstance(this).unregisterreceiver(apilistener);     } } 

i made quite few changes comments describing them. important thing notice here activity no longer listener, i've replaced functionality localbroadcastmanager. using this, can register many broadcastreceiver objects wish handle response of asynctask, without worrying interrupting process of asynctask.

as can see, used intentfilter let manager know intents action ("stationsapi") should go receiver registered (apilistener). also, don't have situation potentially leak activity, unregister receiver activity no longer visible, , re-register when visible again.

getstationsapicall.java

import android.content.context; import android.os.asynctask; import android.util.log; import android.content.intent; import android.support.v4.content.localbroadcastmanager;  import org.apache.http.httpentity; import org.apache.http.httpresponse; import org.apache.http.client.httpclient; import org.apache.http.client.methods.httpget; import org.apache.http.impl.client.defaulthttpclient; import org.apache.http.util.entityutils; import org.json.jsonobject;  /** * created nisal on 13-sep-17. */  public class getstationsapicall extends asynctask<string, void, string> {      localbroadcastmanager localbroadcastmanager; //this manager send result activity      getstationsapicall(context ctx){         localbroadcastmanager = localbroadcastmanager.getinstance(ctx); //no matter call this, same object throughout app.     }      @override     protected string doinbackground(string... params) {          string method = params[0];          if(method.equals("getstations")){              try {                 httpclient client = new defaulthttpclient();                 string geturl = "http://api.gate.com/?lang=en";                 httpget httpget = new httpget(geturl);                 httpget .setheader("authorization", "bearer 690");                  httpresponse response = client.execute(httpget);                 httpentity resentity = response.getentity();                 if (resentity != null) {                     //parse response.                     string responsestring = entityutils.tostring(resentity);                     log.e("response", responsestring;                     return responsestring; //this parameter of onpostexecute method                 }              } catch (exception e) {                 e.printstacktrace();             }         }          return null;     }      @override     protected void onpostexecute(string obj) {         localbroadcastmanager             .sendbroadcast( //sending intent response!                 new intent("stationsapi") //remember intentfilter? here declare send intent.                     .putextra("api_response", obj)); //this data want send receivers.     } } 

as mainactivity class above, i've commented sections changes made. jsonobject class isn't parcelable, instead of creating , reconverting can place inside intent, left string object, , returned value in doinbackground method.

now whenever call getstationsapicall task, should response in mainactivity (or other receiver intentfilter "api_response"). although solution isn't perfect (what if user rotates device?), should avoid of pitfalls android has offer.


Comments

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -