Неопределенный прогрессBar не отображается во время операции AsyncTask

У меня есть файл GoogleTranslate.java, в котором есть класс, GoogleTranslate, который расширяет AsyncTask. Цель этой задачи - выполнять переводы Google.

У меня есть еще один класс MyVocab, который позволяет пользователю вводить слово для перевода в диалоговом окне предупреждения. Таким образом, нажав кнопку "Предупреждение", слово будет переведено на нужный язык, вызвав класс GoogleTranslate. Однако, когда я пропускаю индикатор выполнения от MyVocab до GoogleTranslate, он не работает. Когда операция выполняется (за наблюдаемое количество времени), индикатор выполнения не отображается. Я установил индикатор выполнения как VISIBLE в onPreExecute и установил его как GONE в onPostExecute.

Мне интересно, потому что у меня есть GoogleTranslate и MyVocab в двух разных java файлах, так как большинство примеров, которые я вижу, имеют класс async и класс, который вызывает его в том же java файле. Пожалуйста, дайте мне знать, если я что-то делаю неправильно, что вызывает эту проблему.

Вот связанный код:

GoogleTranslate.java

public class GoogleTranslate extends AsyncTask<String, Void, String>{

private ProgressBar mProgressBar;

public GoogleTranslate(ProgressBar progressBar) {
    super();
    mProgressBar = progressBar;
}

@Override
protected void onPreExecute() {
    mProgressBar.setVisibility(View.VISIBLE);
}

@Override
protected void onPostExecute(String s) {
    mProgressBar.setVisibility(View.GONE);
}

@Override
protected String doInBackground(String... params) {
    String vocab = params[0];
    String source = params[1];
    String target = params[2];

    String sourceQuery = "";
    String targetQuery = "&target=" + target;

    // "" means its
    if (!source.equals("Detect Language")) {
        sourceQuery = "&source=" + source;
    }

    try {
        String APIKey = "MY_API_KEY";
        String encodedQuery = URLEncoder.encode(vocab, "UTF-8");
        URL url = new URL("https://www.googleapis.com/language/translate/v2?key=" +
                APIKey +
                "&q=" +
                encodedQuery +
                sourceQuery +
                targetQuery);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            bufferedReader.close();
            return stringBuilder.toString();
        }
        finally {
            urlConnection.disconnect();
        }
    }
    catch (Exception e) {
        return null;
    }
}

}

Части метода из MyVocab:

protected void addVocabAlertDialog(final VocabDbHelper dbHelper, final String category,
                                 final VocabCursorAdapter cursorAdapter) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Add Vocab");

    LayoutInflater li = LayoutInflater.from(CategoryItem.this);
    View promptsView = li.inflate(R.layout.alert_dialog_add_vocab, null);
    final EditText vocabInput = (EditText) promptsView.findViewById(R.id.vocabInput);
    final EditText definitionInput = (EditText) promptsView.findViewById(R.id.definitionInput);
    final ProgressBar progressBar = (ProgressBar) promptsView.findViewById(R.id.progressBar);
    builder.setView(promptsView);

    final GoogleTranslate googleTranslate = new GoogleTranslate(progressBar);
    // Set up the buttons
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String vocab = vocabInput.getText().toString();
            String definition = definitionInput.getText().toString();
            dbHelper.insertVocab(category, vocab, definition, 0);
            if (!category.equals(VocabDbContract.CATEGORY_NAME_MY_WORD_BANK)) {
                dbHelper.insertVocab(VocabDbContract.CATEGORY_NAME_MY_WORD_BANK, vocab, definition, 0);
            }
            // Update Cursor
            Cursor cursor = dbHelper.getVocabCursor(category);
            cursorAdapter.changeCursor(cursor);
        }
    });
    final AlertDialog dialog = builder.create();

    dialog.show();

    dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String vocab = vocabInput.getText().toString();

            SharedPreferences sharedPreferences = getSharedPreferences("Translation", MODE_PRIVATE);
            int sourcePos = sharedPreferences.getInt("Source", 0); // 0 is for Detect Language
            int targetPos = sharedPreferences.getInt("Target", 19); // 19 is for English

            String source = LanguageOptions.FROM_LANGUAGE_CODE[sourcePos];
            String target = LanguageOptions.TO_LANGUAGE_CODE[targetPos];

            final AlertDialog.Builder builder = new AlertDialog.Builder(CategoryItem.this);
            builder.setMessage("Network is unavailable. Please try again later.");
            builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            AlertDialog dialog = builder.create();

            if (isNetworkAvailable()) {
                AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab, source, target);
                try {
                    String translatedJSON = asyncTask.get();
                    JSONParser jsonParser = new JSONParser();
                    String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
                    definitionInput.setText(translatedText);
                } catch (Exception e) {
                    dialog.show();
                }
            }
            else {
                dialog.show();
            }
        }
    });

}

XML файл, содержащий индикатор выполнения:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Vocab"
    android:id="@+id/vocabInput"
    android:inputType="textAutoComplete"/>

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Definition"
    android:id="@+id/definitionInput"
    android:inputType="textAutoComplete"
    android:layout_below="@+id/vocabInput"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone"
    android:indeterminate="true"
    android:id="@+id/progressBar"/>

Ответ 1

Попробуйте избежать метода get() AsyncTask и вместо этого используйте прослушиватель. Вы должны обновить свой код следующим образом:

1) В вашем классе googleTranslate добавьте прослушиватель:

private Listener listener;

    public interface Listener{
        void onTaskResult(String string);
    }

    public void setListener(Listener listener){
        this.listener = listener;
    }

и вызовите его в onPostExecute:

 @Override
    protected void onPostExecute(String s) {
        if (listener!=null){ listener.onTaskResult(s); }
                mProgressBar.setVisibility(View.GONE);

    }

2) обновите свой основной класс, заменив get на управление прослушивателем, заменив это:

AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab, source, target);
                try {
                    String translatedJSON = asyncTask.get();
                    JSONParser jsonParser = new JSONParser();
                    String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
                    definitionInput.setText(translatedText);
                } catch (Exception e) {
                    dialog.show();
                }

с этим:

googleTranslate.setListener(new GoogleTranslate.Listener() {
            @Override
            public void onTaskResult(String string) {
                    String translatedJSON = string;
                    JSONParser jsonParser = new JSONParser();
                    String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
                    definitionInput.setText(translatedText);
            }
        });
        googleTranslate.execute(vocab, source, target);

Я надеюсь, что это помогло.

Ответ 2

добавьте это перед выполнением googleTranslate:

 progressBar.setVisibility(View.VISIBLE);
 progressBar.setProgress(0);
 AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab,source, target);

а также реализовать onProgressUpdate в googleTranslate.

эта ссылка может помочь:

http://www.concretepage.com/android/android-asynctask-example-with-progress-bar

Ответ 3

Вместо этого я предлагаю использовать ProgressDialog.

Я переключился с ProgressBar, потому что столкнулся с аналогичной проблемой, даже после того, как программно создал ее в конструкторе по умолчанию моего AsyncTask.

public class GoogleTranslate extends AsyncTask<String, Void, String> {
    private ProgressDialog mProgressDialog;
    private Context mContext;

    public GoogleTranslate(Context context) {
        mContext = context;
    }

     @Override
     protected void onPreExecute() {

         mProgressDialog = ProgressDialog.show(
                mContext,
                "Please wait", // Title
                "Translating", // Message
                true           // Indeteriminate flag
         );
     }

     @Override
     protected String doInBackground(String... params) {
         ...
     }

     @Override
     protected void onPostExecute(String s) {
         if (mProgressDialog != null) {
              mProgressDialog.dismiss();
         }
         ...
     }
 }

Назовите это AsyncTask следующим образом:

new GoogleTranslate(getActivity() /* or getContext() */).execute(vocab, source, target);

Ответ 4

Попробуйте передать ProgressBar как аргумент конструктора класса GoogleTranslate.

Ответ 5

Добавьте индикатор выполнения в свой метод onPreExecute и спрячьте его в onPostExecute.

private class MyAsyncThread extends AsyncTask<Void, Void, String>
{
            @SuppressWarnings("finally")

            @Override
            protected String doInBackground(Void... params) {
                // TODO Auto-generated method stub
                try {

                // your code

                }
                catch (Exception e) {
                    // TODO: handle exception
                }
                finally
                {

                    return "OK";

                }

            }
            @Override
            protected void onPostExecute(String result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);

               if (progressDialog != null) {
                   progressDialog.dismiss();
                   progressDialog = null;
               }

                        }catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                        }
            }


            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                progressDialog = ProgressDialog.show(this, null, "Please wait....");
            }

Ответ 6

Это потому, что вы блокируете главный поток при вызове asyncTask.get(), поэтому никакие операции пользовательского интерфейса не могут выполняться до завершения asyncTask.

Удалите этот вызов и обработайте результаты asyncTask в его обратных вызовах onPostExecute(String s) and onCancelled().