Aymane Bo Aymane Bo - 5 months ago 18
Android Question

assign external variable to the result of a callback inside AsynckTask

private class exampleTask extends AsyncTask<String, Void, SomeResult>{
@Override
protected SomeResult doInBackground(String... urls) {
SomeResult res ;
someMethod(new CallBack<T>(){
@Override
public void onResponse(SomeResult something) {
res = something ;
}

@Override
public void onFailure() {
//
}
});

return res ;
}


@Override
protected void onPostExecute() {
//
}
}


Please I want to assign "res" to "something" witch is inside the callback in the onResponse method. In this code it's impossible to assign res inside the onResponse method.

Please any help is welcome.

Thank you :)

my original code : I'd like to assign "url" ;

private class GetBeaconInfosTask extends AsyncTask<String, Void, Call<Url>> {

Url url ;

@Override
protected Call<Url> doInBackground(String... urls) {
ProxService service = ProxService.Factory.makeProxService(ProxService.ENDPOINT);
return service.getUrlDetails(urls[0]);
}

// onPostExecute return the results of the AsyncTask.
@Override
protected void onPostExecute(Call<Url> call) {

call.enqueue(new Callback<Url>() {
@Override
public void onResponse(Call<Url> call, Response<Url> response) {
url = response.body();
}

@Override
public void onFailure(Call<Url> call, Throwable t) {
//
}
});

if(url == null){
Log.i("url is null", "url is null !!!!! ....");
}
else {
setShopLogo(url.icon) ;
setShopName(url.title);
setDescription(url.description);
setlongUrl(url.longUrl); }
}

}

Answer

Assuming the problem is due to the variable having to be declared as final to be accessible from the callback, you could move it out of the doInBackground method and declare it as a member of the exampleTask class.

    private class exampleTask extends AsyncTask<String, Void, SomeResult>{
            SomeResult res;

            @Override
            protected SomeResult doInBackground(String... urls) {

               someMethod(new CallBack<T>(){
                  @Override
                  public void onResponse(SomeResult something) {
                    res = something ; 
                 }

                @Override
                public void onFailure() {
                    //
                }
           });

         return res ;
        }


        @Override
        protected void onPostExecute() {
            //
        }
    }

While this should answer your question, it's hard to tell what you're trying to achieve. Further to @Gabe Sechan's answer - your variable may never get assigned, or it would be assigned after a certain length of time. Ordinarily you would carry out work in the doInBackground and when that has been carried out onPostExecute is called, but in your case you'll likely have onPostExecute called before hitting the onRespons of your callback. I don't think it's good practice to use a Callback in doInBackground the way you're trying to use it.

If you have other work that needs to be carried out asynchronously in doInBackground, do that, but move the someMethod call to onPostExecute and do whatever you need to do with res in there.

private class exampleTask extends AsyncTask<String, Void, SomeResult>{
    SomeResult res;

    @Override
    protected SomeResult doInBackground(String... urls) {

       // background work
    }


    @Override
    protected void onPostExecute() {
       someMethod(new CallBack<T>(){
              @Override
              public void onResponse(SomeResult something) {
                res = something ;
               // DO STUFF WITH RES HERE AFTER IT'S BEEN ASSIGNED OR YOU WON'T HAVE ACCESS TO IT
             }

            @Override
            public void onFailure() {
                //
            }
       });
    }

}

EDIT: Now that the question contains real code, I can provide a flow that should work for you. Note in the code I pasted above the comment in onResponse stating this is where you should have the code that uses the variable. Look at onResponse below for example using your code. The value doesn't exist until you get to the onResponse callback method, so you have to wait until it gets there. Your code below is being carried out before onResponse so the variable is inevitably null. The code isn't executed sequentially. I'd suggest studying callbacks to fully understand them :)

private class GetBeaconInfosTask extends AsyncTask<String, Void, Call<Url>> {

    Url url ;

    @Override
    protected Call<Url> doInBackground(String... urls) {
        ProxService service = ProxService.Factory.makeProxService(ProxService.ENDPOINT);
        return service.getUrlDetails(urls[0]);
    }

    // onPostExecute return the results of the AsyncTask.
    @Override
    protected void onPostExecute(Call<Url> call) {

        call.enqueue(new Callback<Url>() {
            @Override
            public void onResponse(Call<Url> call, Response<Url> response) {
                url = response.body();


                setShopLogo(url.icon) ;
                setShopName(url.title);
                setDescription(url.description);
                setlongUrl(url.longUrl); }
            }

            @Override
            public void onFailure(Call<Url> call, Throwable t) {
                //
            }
        });
}
Comments