java - Android: Async Task : doInBackground returns before an action callback -


i using mqtt android application. implemented mqtt connection in class extending asynctask. code:

public class mainactivity extends appcompatactivity {     string tag = "mqtt";     private context context;     string status;     @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);         toolbar toolbar = (toolbar) findviewbyid(r.id.toolbar);         setsupportactionbar(toolbar);          floatingactionbutton fab = (floatingactionbutton) findviewbyid(r.id.fab);         fab.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view view) {                 snackbar.make(view, "replace own action", snackbar.length_long)                         .setaction("action", null).show();             }         });          context = getapplicationcontext();         mqtt mqtt = new mqtt();         mqtt.execute();     }      @override     public boolean oncreateoptionsmenu(menu menu) {         // inflate menu; adds items action bar if present.         getmenuinflater().inflate(r.menu.menu_main, menu);         return true;     }      @override     public boolean onoptionsitemselected(menuitem item) {         // handle action bar item clicks here. action bar         // automatically handle clicks on home/up button, long         // specify parent activity in androidmanifest.xml.         int id = item.getitemid();          //noinspection simplifiableifstatement         if (id == r.id.action_settings) {             return true;         }          return super.onoptionsitemselected(item);     }     public class mqtt extends asynctask<string, void, string> {         @override         protected string doinbackground(string... params) {             string clientid = generateclientid();             mqttandroidclient client =                     new mqttandroidclient(context, "tcp://broker.hivemq.com:1883",                             clientid);              try {                 imqtttoken token = client.connect();                 token.setactioncallback(new imqttactionlistener() {                     @override                     public void onsuccess(imqtttoken asyncactiontoken) {                         // connected                         log.d(tag, "onsuccess");                         status = "true";                     }                      @override                     public void onfailure(imqtttoken asyncactiontoken, throwable exception) {                         // went wrong e.g. connection timeout or firewall problems                         log.d(tag, "onfailure");                         status = "false";                       }                 });             } catch (mqttexception e) {                 e.printstacktrace();             }             log.d(tag, "value of status " + status);             return status;         }          @override         protected void onpostexecute(string s) {             super.onpostexecute(s);             log.d(tag, s);           }     } } 

the problem facing here doinbackground() returns before onsuccess called. because of this, function returns status null. tried take log of returned value in onpostexecute(), shows null. whereas assigning value of status in onsuccess function inside doinbackground. there way can make sure doinbackground returns after onsuccess completed.

quick solution block until async task finishes, e. g. using semaphore:

protected string doinbackground(string... params) {     string clientid = generateclientid();     mqttandroidclient client = // ....                      semaphore s = new semaphore(0);     try {        imqtttoken token = client.connect();        token.setactioncallback(new imqttactionlistener() {            @override            public void onsuccess() {                // ...                status = "true";                s.release();            }             @override            public void onfailure() {                // ...                status = "false";                s.release();            }        });     } catch (mqttexception e) {          e.printstacktrace();          s.release();     }     s.acquire();   // blocks until `s.release()` invoked in callback     return status; } 

Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -