отримання контексту в 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.