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
Post a Comment