Внешний класс AsyncTask с ProgressDialog [Обновление: и вернуться обратно?]

** Обновлено: (см. ниже) ** Я искал пару дней и не могу найти прямого ответа на этот вопрос. Некоторые говорят, что это возможно, некоторые говорят, что это возможно, некоторые говорят, что это невозможно. Я схожу с ума по этому поводу.

Я хочу, чтобы AsyncTaskTask показывал индикатор выполнения внешнего класса. Для этого я передаю контекст, как вы можете видеть в основном классе. Но что бы я ни пробовал, я получаю NullPointerException.

Примеры рабочего кода приветствуются. Спасибо

Кстати, на Android 2.2.

главный:

import android.app.Activity;
import android.os.Bundle;

public class AsyncDemo extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        new AsyncClass(this).execute();
    }
}

Асинккласс.java

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.SystemClock;

public class AsyncClass extends AsyncTask<Void, String, Void> {
    private Context context;
    ProgressDialog dialog = new ProgressDialog(context);

    public AsyncClass(Context cxt) {
        context = cxt;
    }

    @Override
    protected void onPreExecute() {
        dialog.setTitle("Please wait");
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... unused) {
        SystemClock.sleep(2000);
        return (null);
    }

    @Override
    protected void onPostExecute(Void unused) {
        dialog.dismiss();
    }
}

Обновление: У меня есть дополнительный вопрос: используя приведенный выше код, можно ли каким-то образом вернуть значение из метода onPostExecute обратно в основной класс? (Извините за нубизм) Я пробовал что-то вроде этого:

String result = new AsyncClass(this).execute();

а затем метод, который возвращает строку. Но я не могу этого сделать, потому что я получил:

Type mismatch: cannot convert from AsyncTask<String,Void,Void> to String

Что я могу сделать, чтобы решить эту проблему? Спасибо.


person droidgren    schedule 27.07.2010    source источник
comment
Меня интересует ваш дополнительный вопрос. У меня похожая ситуация, и я не знаю, как вернуть возвращаемое значение. Что я сейчас делаю, так это создаю field variable, а затем присваиваю результат onPostExecute, но я не уверен, что это правильный путь.   -  person Eugene van der Merwe    schedule 13.02.2011


Ответы (3)


Вы создавали ProgressDialog с нулевым контекстом. Следующий код работал для меня.

public class AsyncClass extends AsyncTask<Void, String, Void> {
    private Context context;
    ProgressDialog dialog;

        public AsyncClass(Context cxt) {
            context = cxt;
            dialog = new ProgressDialog(context);
        }

        @Override
        protected void onPreExecute() {
            dialog.setTitle("Please wait");
            dialog.show();
        }

        @Override
        protected Void doInBackground(Void... unused) {
            SystemClock.sleep(2000);
            return (null);
        }

        @Override
        protected void onPostExecute(Void unused) {
            dialog.dismiss();
        }
    }
person SSZero    schedule 27.07.2010
comment
Проблема в том, что экземпляр ProcessDialog создается до вызова конструктора. Поэтому контекст нулевой. Перемещение экземпляра ProcessDialog в конструктор таким образом гарантирует, что контекст содержит значение, переданное в cxt. Кроме того, в этом примере вам не нужно хранить контекст в виде поля. Просто передайте cxt конструктору ProgressDialog (т. е. диалог = новый ProgressDialog (cxt)). - person Emil H; 28.07.2010

хорошо, это то, что я сделал, когда использовал фрагменты. Вот как вы вызываете AsyncTask внутри фрагмента:

String result=new AsyncClass(getActivity()).execute();

и вот как выглядит мой внешний класс AsyncTask:

public class AsyncClass extends AsyncTask<Void, Void, String> {

    ProgressDialog pdialog;

    public AsyncClass(Context context) {
        pdialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        pdialog.setIndeterminate(true);
        pdialog.setCancelable(false);
        pdialog.setTitle("Loading Feed..");
        pdialog.setMessage("Please wait.");pdialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {
        String result=null;
        //do your task here and generate result String
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        if(pdialog.isShowing())
             pdialog.dismiss();
    }
}

@SSZero спасибо, отличный ответ, очень помог.

person SMR    schedule 29.01.2014

Я хотел бы ответить на этот дополнительный вопрос, т.е.

У меня есть дополнительный вопрос: используя приведенный выше код, можно ли каким-то образом вернуть значение из метода onPostExecute обратно в основной класс? (Извините за нубизм) Я пробовал что-то вроде этого:

String result = new AsyncClass(this).execute();

Я сделал это в своем коде, это сработало.

AsyncClass ac=new AsyncClass();
                    
ac.execute("");

String rslt=ac.get();

Вызывайте этот код везде, где хотите.

public class AsynchClass extends AsyncTask <String,Integer,String>
{

    public String result=null;


    @Override
    protected void onPreExecute() {
    // TODO Auto-generated method stub  
     
    }

    protected String doInBackground(String... params) 
    {

            // Do all your background task here

            return result;
                    
    }
    @Override
     
    protected void onProgressUpdate(Integer... values) {
    
      
    }

    protected void onPostExecute(String result) {
    
    }
}

                
             
person rishu    schedule 03.03.2013