ProgressDialog не появляется при вызове потока внутри AsyncTask
У меня есть приложение, которое отправляет файл через сокет. Делая это, я хочу показать прогресс в ProgressDialog. Приложение отправляет файл отлично, но я не могу заставить диалоговое окно появиться.
public class ProgressDialogActivity extends Activity {
private ProgressDialog downloadDialog = null;
private String filePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
filePath = getIntent().getExtras().getString("filePath");
downloadDialog = new ProgressDialog(this);
Task myTask = new Task();
myTask.execute(0);
}
private void showMessage(final String msg) {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), msg, `enter code here`Toast.LENGTH_SHORT).show();
}
});
}
private class Task extends AsyncTask<Integer, Integer, Boolean> implements Observer
{
private Thread t;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
downloadDialog.setTitle("SENDING");
downloadDialog.setMessage("................");
downloadDialog.setCancelable(false);
downloadDialog.setIndeterminate(false);
// downloadDialog.setMax(100);
downloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
downloadDialog.show();
}
@Override
protected Boolean doInBackground(Integer... params) {
SendFile send = new SendFile(filePath);
downloadDialog.setMax(0);
t = new Thread(send);
send.registerObserver(this);
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
t.start();
return true;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
int counter = values[0].intValue();
downloadDialog.setProgress(counter);
if(filePath != null)
{
downloadDialog.setMessage(filePath+"...");
}
}
@Override
public void update(Subject subject) {
// TODO Auto-generated method stub
if(subject instanceof SendFile)
{
SendFile e = (SendFile) subject;
if(e.getException() != null)
{
t.interrupt();
showMessage(e.getException());
} else
{
if(!e.isStarted())
{
initializeProgressBar(e.getNumIter());
} else
{
refreshProgressBar(e.getNumIter());
}
if(e.isSent())
{
t.interrupt();
showMessage("File sent");
}
}
}
}
public void initializeProgressBar(int max){
downloadDialog.setMax(max);
}
public void refreshProgressBar(int amount){
publishProgress(downloadDialog.getMax()-amount);
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(downloadDialog != null)
{
downloadDialog.dismiss();
}
finish();
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
super.onCancelled();
t.interrupt();
showMessage("TASK CANCELLED");
}
};
}
SendFile - это класс, который содержит сокет для отправки файлов.
Я думаю, что проблема связана с тем, что я вызываю поток внутри AssyncTask, потому что когда я делаю Thread.sleep(10000), я могу видеть ProgressDialog в это время, но я не знаю, как это исправить.
Кроме того, когда я запускаю отладчик, я вижу, что переменная 'counter' увеличивается каждый раз, когда я вызываю ее, но если я добавляю часы с помощью 'downloadDialog.getProgress()', прогресс всегда равен 0.
2 ответа
Вы создаете AsyncTask, метод doInBackground() которого запускается в фоновом режиме. Там вы ничего не делаете, но начинаете новый поток... Теперь этот поток выполняет свою работу, но ваш AsyncTask завершает работу, потому что он не имеет ничего общего после запуска другого потока... Итак, ваш ProgressDialog показан в течение нескольких миллисекунд ваш AsyncTask завершается, а ProgressDialog снова скрывается. Но поток, который выполняет работу, все еще работает, только ваш AsyncTask завершил работу.
Решение: либо используйте AsyncTask, либо используйте поток.
Вам нужно позвонить publishProgress
на doinBackground()
Пример:
protected String doInBackground(Void... params) {
try {
int i = 0;
Log.i("Thread","1");
Thread.sleep(1000);
publishProgress(i++);
Log.i("Thread","2");
Thread.sleep(1000);
publishProgress(i++);
Log.i("Thread","3");
Thread.sleep(1000);
Log.i("Thread","4");
Thread.sleep(1000);
Log.i("Thread","5");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "done";
}