AsyncTaskでコンテキストを取得する


83

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
Torben Kohlmeier 2013年

回答のようなこのルックス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 2017

8
ネストされた静的クラスでコンテキストを保持すると、メモリリークの警告がスローされます
Amir Hossein Ghasemi 2017

2
また、ネストされたクラスに非静的クラスを保持すると、クラス全体のメモリリーク警告が発生します。では、メモリリークのないコンテキストを使用する必要があります!?
Amir Hossein Ghasemi 2017

1
メモリリークを解決する方法を見つけてください。ContextはWeakReferenceクラスである必要があります。
Amir Hossein Ghasemi 2017

これはネストされた静的クラスにはなりません。そのパブリッククラスであり、アクティビティとは別に定義する必要があります。しかし、はい、安全のために、WeakReferenceを使用できます。
Chintan Rathod 2017

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
アクティビティを切り替えて(asyntaskの停止と再開)、その後戻ってきた場合はどうでしょうか。weakreferenceはまだアクティブですか?
d4rWiNS 2017

1
myActivityを渡す代わりにweakReferenceをクラスに渡す利点はありますか?
seekStillness 2018

1
@seekingStillness弱参照でも、アクティビティをガベージコレクションできるため、メモリリークを防ぐことができます。
サイ

13

Activityこのタスクを使用するのは1つだけなので、それをその内部クラスにします。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
AsyncTaskクラスが静的でない場合、Lintはメモリリークに関する警告を表示します。
SapuSeven 2017

@SapuSevenそれは単なる警告であることを忘れないでください。個人的にAsyncTaskは、短期間の操作や、のビューの更新のように正しく使用すれば、問題になるとは思いませんActivityonPause()それらがまだ実行されている場合は、キャンセルすることをお勧めします。たぶん私は間違っていますが、それはいつも私の考えです。 これは、この主題に関するもう少しの読み物です。
codeMagic 2017

-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(); 
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.