2013-06-04 4 views
58

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

 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' –

+0

. Это выглядит как ответ https://stackoverflow.com/questions/45653121/passing-context-from-service-to-asynctask -without-leaking-it – Mangesh

ответ

139

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

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

Пример

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(..); 
+13

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

+0

Холдинг контекста во вложенном статическом классе throw memory leak warning –

+1

, а также нестационарный класс в вложенном классе вызывают предупреждение об утечке памяти всего класса! так что мы должны использовать контекст без утечки памяти !? –

-1

Вы можете написать 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(); 
} 
+0

Это не имеет никакого отношения к AsyncTask. –

11

Поскольку только один 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

+1

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

+0

@SapuSeven Помните, что это * просто предупреждение *. Я лично не думаю, что это должно быть проблемой при правильном использовании, поскольку «AsyncTask» предназначены для коротких операций и часто для обновления представлений в «Деятельности». Часто бывает неплохо отменить их в 'onPause()', если они все еще запущены. Возможно, я ошибаюсь, но это всегда были моими мыслями. [Вот еще несколько статей по этому вопросу] (https://stackoverflow.com/questions/14374682/whats-the-correct-way-to-implement-asynctask-static-or-non-static-nested-class). – codeMagic

11

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

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

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

Смежные вопросы