1

When I debug my app I see that onPostExecute starts after onPreExecute and only when it is finished doInBackground method start running, so I don't have results on UI. Why it could be? AsyncTask code:

class TranslateYandex extends AsyncTask<Void, Void, Void> {
    String translate = "";
    //        YandexTranslation yandexTranslation;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        enterWord.setEnabled(false);
        getTranslateButton.setEnabled(false);
        translate = enterWord.getText().toString();
    }
    @Override
    protected Void doInBackground(Void... voids) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://translate.yandex.net")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        YandexService service = retrofit.create(YandexService.class);

        Call<YandexTranslation> call = service.getTranslation(translate, API_KEY, LANG);
        call.enqueue(new Callback<YandexTranslation>() {
            @Override
            public void onResponse(Call<YandexTranslation> call, Response<YandexTranslation> response) {
                if (response.body() != null){
                    Log.i("Response", response.body().getTranslation().get(0));
                    translation = response.body().getTranslation().get(0);
                    int donothing = 1;
                }

                else {
                    Log.i("Response", " is null");
                   }
            }

            @Override
            public void onFailure(Call<YandexTranslation> call, Throwable t) {
                Log.i("Failure", t.toString());
            }
        });

        return null;
    }

    protected void onPostExecute(Void voids) {
        enterWord.setEnabled(true);
        getTranslateButton.setEnabled(true);
        enterTranslation.setText(translation);
    }
}
Paco de la Vega
  • 131
  • 3
  • 15
  • 3
    Because the things you're doing in `doInBackground()` are themselves asynchronous. That is, you don't need to put them in an `AsyncTask`. – Mike M. Jul 26 '16 at 09:02
  • 1
    You aren't putting `@Override` annotation on that `onPostExecute` – Kevin Murvie Jul 26 '16 at 09:11
  • @KevinMurvie The `@Override` annotation isn't required in Java. The signature is correct for the given type argument. – Mike M. Jul 26 '16 at 09:13
  • @MikeM. Whoa really?! I've been putting `@Override` everywhere there's a superclass which has its own method to change it into mine lol – Kevin Murvie Jul 26 '16 at 09:14
  • @KevinMurvie It's definitely good practice to put it there, so your IDE can yell at you if something isn't right, but it's not required in Java. – Mike M. Jul 26 '16 at 09:16
  • 1
    @MikeM. Thanks for that info, this is the kind of small info which I miss in my College days – Kevin Murvie Jul 26 '16 at 09:20
  • 1
    @Mike M. Thanks, that was the problem, I forgot that Call enqueue is asynchronous by ityself. So I need to replace it with synchronous Call execute or get rid of AsyncTask. – Paco de la Vega Jul 26 '16 at 09:24

2 Answers2

3

i think there is no need to use an async task simply create a method like below i have demonstrated you will achieve what you want.

public void methodName(){

    enterWord.setEnabled(false);
    getTranslateButton.setEnabled(false);
    translate = enterWord.getText().toString();

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://translate.yandex.net")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    YandexService service = retrofit.create(YandexService.class);

    Call<YandexTranslation> call = service.getTranslation(translate, API_KEY, LANG);
    call.enqueue(new Callback<YandexTranslation>() {
        @Override
        public void onResponse(Call<YandexTranslation> call, Response<YandexTranslation> response) {
            if (response.body() != null){
                Log.i("Response", response.body().getTranslation().get(0));
                translation = response.body().getTranslation().get(0);
                int donothing = 1;
            }

            else {
                Log.i("Response", " is null");
               }
        }

        @Override
        public void onFailure(Call<YandexTranslation> call, Throwable t) {
            Log.i("Failure", t.toString());
        }


        /* Here i am adding this code global because it seems you do not have any specific condition for translation object in onResponse. You can also write this in onResponse with specific condition*/
        enterWord.setEnabled(true);
        getTranslateButton.setEnabled(true);
        enterTranslation.setText(translation);
    });
}

Now Simply call this function from where you want.

Let me know if you are facing any issue with this solution.

If you can resolve your query with this solution kindly mark this as answer.

Happy Coding!

Shrenik Shah
  • 1,900
  • 1
  • 11
  • 19
  • Thanks, it worked, but I've moved UI update (last 3 lines) to onResponse method of call.enqueue because it's asyncronous so I need to disable buttons while it's running and update after it's finished. – Paco de la Vega Jul 26 '16 at 09:21
  • Welcome! if you found it helpful kindly mark it as answer so that it can be helpful to other developers who will face same kind of issue. – Shrenik Shah Jul 26 '16 at 09:27
0

Because you're not using annotation, it means you're going to execute the mentioned methods as a new one. in order to execute them as normal. you have to add @Override before the method declaration.

@Override annotation is used when we override a method in a subclass. Generally, novice developers overlook this feature as it is not mandatory to use this annotation while overriding the method. Here we will discuss why we should use @Override annotation and why it is considered a best practice in java coding.

Let's take an example first to understand how it is used then we will discuss it in detail:

class ParentClass{
          public void displayMethod(String msg){
              System.out.println(msg);
                }
              }
   class SubClass extends ParentClass{
    @Override
    public void displayMethod(String msg){
            System.out.println("Message is: "+ msg);
            }
    public static void main(String args[]){
        SubClass obj = new SubClass();
        obj.displayMethod("Hey!!");
      }
 } 

here, there is brief information if you need

Sarwar Sateer
  • 395
  • 3
  • 16
  • 1
    please update with at least a quote, lest the reference change or go and the solution is lost. – Mr R Mar 24 '21 at 20:50
  • I did it. hope it is more useful now. – Sarwar Sateer Mar 25 '21 at 08:13
  • In all cases the `@Override` does not impact which method is called - it's just for documentation purposes (@Sateer). The reference has a better quote about causing complie errors if the wrong clase name is given (which is great) - however I don't understand how this solves the OP though. – Mr R Mar 25 '21 at 08:16
  • It's not only for documentation purpose, if you add the @Override notations then you will be forced to exactly override the same method and the same signature, you will also get a compilation error if you don't add that. but without Override, you are free to use the same method with your own declaration. can show me a source which I'm wrong? – Sarwar Sateer Mar 25 '21 at 08:24
  • Since one only puts @Override (which my IDE always nags about so I do !!) when you intend to override, AND you can't put it on a method that isn't an override (because you will get an error) - it's likely to only catch only a small fraction of errors (that possibly good unit tests will actually catch) [morale of that story - use an IDE, javac doesn't catch everything]. So how does your answer solve the OP question - it's interesting but off topic unless you can show how it fixes their problem. – Mr R Mar 25 '21 at 08:42