отримання контексту в 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/…
— Мангеш

Відповіді:


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
Утримання контексту у вкладеному статичному попередженні про витік пам'яті
— Amir Hossein Ghasemi

2
а також утримання нестатичного класу у вкладеному класі викликає попередження про витоки пам'яті цілого класу! так що ми повинні використовувати контекст без витоку пам’яті !?
— Amir Hossein Ghasemi

1
Знайдіть спосіб вирішити витік пам'яті, контекст повинен бути класом WeakReference.
— Amir Hossein Ghasemi

Це не буде вкладеним статичним класом. Його загальнодоступний клас і повинен бути визначений окремо від діяльності. Але так, для більш безпечної сторони ми можемо використовувати WeakReference.
— Chintan Rathod

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
Чи є користь передавати слабке посилання класу замість того, щоб передавати myActivity?
— lookingStillness

1
Слабкі посилання @seekingStillness все одно дозволять Діяльності збирати сміття, таким чином запобігаючи витоку пам'яті.
— Сай,

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

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

-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.