在AsyncTask操作期间不显示ProgressBar

时间:2016-07-10 05:12:31

标签: android android-asynctask android-progressbar

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

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

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

6 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:4)

在执行<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="mcnumbers-ulinside"> <li id="mcnumbers-container"></li> <li id="mcnumbers-container"> <a href="#" class="mcndiv"> random link </a> </li> <li id="mcnumbers-container"></li> </div> <div id="mc-container"> <div id="mcnumbers-links"> <div id="mcnumbers-colours"></div> <div id="mcnumbers-colours"> <a href="#" class="b_dtl">a</a> </div> <div id="mcnumbers-colours"> <a href="#" class="b_dtl mcselected">b</a> </div> <div id="mcnumbers-colours"></div> </div> </div>

之前添加此项
googleTranslate

并在 progressBar.setVisibility(View.VISIBLE); progressBar.setProgress(0); AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab,source, target); 中实施onProgressUpdate

此链接可能有所帮助:

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

答案 2 :(得分:4)

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

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);

我希望它有所帮助。

答案 3 :(得分:3)

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

答案 4 :(得分:3)

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

答案 5 :(得分:2)

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

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