在 AsyncTask 操作期间未显示不确定的 ProgressBar

Indeterminate ProgressBar not showing during AsyncTask operation

我有一个 GoogleTranslate.java 文件,其中包含 class、GoogleTranslate,它扩展了 AsyncTask。此任务的目的是执行 Google 翻译。

我有另一个 class,MyVocab,它允许用户输入要在警告对话框中翻译的单词。因此,单击警报对话框按钮后,将通过调用 GoogleTranslate class 将单词翻译成所需的语言。但是,当我将进度条从 MyVocab 传递到 GoogleTranslate 时,它​​不起作用。当操作为 运行 时(对于可观察的时间量),进度条不显示。我在 onPreExecute 中将进度条设置为 VISIBLE,并在 onPostExecute 中将其设置为 GONE。

我想知道这是不是因为我在两个不同的 java 文件中有 GoogleTranslate 和 MyVocab 因为我看到的大多数示例都有异步 class 和 class 在同一个 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"/>

在执行 googleTranslate 之前添加:

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

并在 googleTranslate 中实施 onProgressUpdate

这个link可能有帮助:

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

我建议改用 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);

尝试将 ProgressBar 作为 GoogleTranslate 的构造函数参数传递 class。

那是因为您通过 asyncTask.get() 调用阻塞了主线程,所以在 asyncTask 完成之前,UI 操作不能 运行。

删除此调用并改为在其 onPostExecute(String s) and onCancelled() 回调中处理 asyncTask 的结果。

尽量避免使用 AsyncTask get() 方法并改用侦听器。 您应该这样更新您的代码:

1) 在您的 googleTranslate class 中,添加一个侦听器:

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) 更新您的主要 class 将 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);

希望对您有所帮助。

在你的 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....");
            }