在 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....");
}
我有一个 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....");
}