ProgressDialog не появляется при вызове потока внутри AsyncTask

117
13

У меня есть приложение, которое отправляет файл через сокет. Выполняя это, я хочу показать прогресс в 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.

спросил(а) 2021-01-25T15:08:16+03:00 4 месяца, 4 недели назад
1
Решение
99

Вы должны вызвать 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";
}

ответил(а) 2021-01-25T15:08:16+03:00 4 месяца, 4 недели назад
45

Вы создаете AsyncTask, который делает метод doInBackground() RUNS IN BACKGROUND. Там вы ничего не делаете, но начинаете новый поток... Теперь этот поток выполняет эту работу, но ваш AsyncTask заканчивается, потому что после запуска другого потока ничего не поделаешь... Итак, ваш ProgressDialog показан в течение нескольких миллисекунд, то ваш AsyncTask завершается, а ProgressDialog снова скрывается. Но поток, который выполняет эту работу, все еще работает, только ваш AsyncTask завершен.

Решение. Используйте либо AsyncTask OR, либо используйте поток.

ответил(а) 2021-01-25T15:08:16+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема