получение контекста в AsyncTask


83

Я пытаюсь получить контекст в своей AsyncTask класса Opciones (этот класс - единственный, который вызывает эту задачу), но я не знаю, как это сделать, я видел такой код:

      protected void onPostExecute(Long result) {

    Toast.makeText(Opciones.this,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
}

Но у меня это не работает, там написано: "No enclosing instance of the type Opciones in scope"


4
Opciones - это деятельность? Если нет, вам нужно передать контекст этому классу, а затем использовать его вAsyncTask
— Torben Kohlmeier

Это выглядит как ответ stackoverflow.com/questions/45653121/...
— Mangesh

Ответы:


176

Вам нужно сделать следующее.

  • если вы хотите использовать AsyncTask , расширьте это в другом классе, например MyCustomTask .
  • в конструкторе нового класса передать Context

пример

public class MyCustomTask extends AsyncTask<Void, Void, Long> {

    private Context mContext;

    public MyCustomTask (Context context){
         mContext = context;
    }

    //other methods like onPreExecute etc.
    protected void onPostExecute(Long result) {
         Toast.makeText(mContext,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
    }
}

И создайте экземпляр класса следующим образом.

MyCustomTask task = new MyCustomTask(context);
task.execute(..);

36
обратите внимание, что было бы намного лучше использовать невложенный или статический класс и удерживать mContext в WeakReference, чтобы избежать утечек памяти
— BamsBamx

8
Удержание контекста во вложенном статическом классе
— Амир Хоссейн Гасеми

2
а также сохранение нестатического класса во вложенном классе вызывает предупреждение об утечке памяти всего класса! так что мы должны использовать контекст без утечки памяти !?
— Амир Хоссейн Гасеми

1
Найдите способ решить проблему утечки памяти. Контекст должен быть классом WeakReference.
— Амир Хоссейн Гасеми

Это не будет вложенный статический класс. Его публичный класс и должны быть определены отдельно от Activity. Но да, для большей безопасности мы можем использовать WeakReference.
— Чинтан Ратод 08

59

Слабая ссылка на активность хоста предотвратит утечку памяти.

static class MyTask extends AsyncTask<Void, Void, Void> {
    // Weak references will still allow the Activity to be garbage-collected
    private final WeakReference<Activity> weakActivity;

    MyTask(Activity myActivity) {
      this.weakActivity = new WeakReference<>(myActivity);
    }

    @Override
    public Void doInBackground(Void... params) {
      // do async stuff here
    }

    @Override
    public void onPostExecute(Void result) {
      // Re-acquire a strong reference to the activity, and verify
      // that it still exists and is active.
      Activity activity = weakActivity.get();
      if (activity == null
          || activity.isFinishing()
          || activity.isDestroyed()) {
        // activity is no longer valid, don't do anything!
        return;
      }

      // The activity is still valid, do main-thread stuff here
    }
  }

1
Как насчет того, когда мы переключаемся между действиями (остановка и возобновление выполнения задачи), а затем возвращаемся, активна ли слабая ссылка?
— D4rWiNS

1
Есть ли преимущества передать weakReference классу вместо передачи myActivity?
— seekStillness

1
@seekingStillness Слабые ссылки по-прежнему позволяют Activity собирать мусор, предотвращая утечку памяти.
— Сай

13

Поскольку только один Activityиспользует эту задачу, просто сделайте ее внутренним классом этогоActivity

public class Opciones extends Activity
{
     public void onCreate()
     {
         ...
     }

    public class MyTask extends AsyncTask<>
    {
        ...

         protected void onPostExecute(Long result) {
        Toast.makeText(Opciones.this,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
     }
}

Затем у вас есть доступ к переменным-членам Activityи егоContext


2
Lint показывает предупреждение об утечках памяти, если класс AsyncTask не является статическим.
— SapuSeven 07

@SapuSeven Помните, что это всего лишь предупреждение . Я лично не думаю, что это должно быть проблемой при правильном использовании, как AsyncTaskдля краткосрочных операций и часто для обновления представлений в файле Activity. Часто бывает полезно отменить их, onPause()если они все еще работают. Может я ошибаюсь, но я всегда так думал об этом. Вот еще кое-что по этому поводу .
— codeMagic 07

-6

Вы можете писать getApplicationContex(). Или определите глобальную переменную.

Activity activity;

И на onCreate()функции

activity = this;

тогда,

 protected void onPostExecute(Long result) {

    Toast.makeText(activity,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.