получение контекста в 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"

D4rWiNS
источник
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

codeMagic
источник
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(); 
}
yahya.can
источник