2017-08-12 36 views
3

我有一個Service從我開始AsyncTask從給定的計時器做後臺任務。我的需要需要短暫的網絡任務,這就是爲什麼我堅持Asynctask從服務傳遞上下文而不泄漏它

Asynctask我在做一些操作(如啓動通知),需要context。現在,當我在我的AsyncTask初始化context我得到一個警告「這個領域泄漏上下文對象。

我已經看到了關於同一問題的數量,但他們都被有關Activity/Fragment。所以我的問題是,我如何在我的AsyncTask(頂級課程)中使用context而不會漏水

回答

3

我有一個服務,我從一個給定的定時器啓動AsyncTask來完成後臺任務。

請勿使用AsyncTask。使用線程。或者,更好的是,使用ScheduledExecutorService作爲定時組件,因爲它將在後臺線程上執行任務。 AsyncTask僅適用於適合於在完成後臺部分時需要在主應用程序線程上工作的情況,這對服務很少需要。

另外,請記住,一旦進程終止,您的計時器將停止工作。

所以我的問題是,我怎樣才能在我的AsyncTask(頂級類)中使用上下文而不會泄漏它?

致電getApplicationContext()Service並使用Context

+0

我也在做一些'Jsoup'調用,這就是爲什麼我嚴重依賴'onPostExecute'(來檢查結果是否爲null)。調用'getApplicationContext()'將是最佳實踐還是持有'服務上下文'的'弱引用'? –

+0

@ Michal_196:解析HTML與主應用程序線程無關;你不需要'onPostExecute()'來解析HTML。關於'Context',請使用'getApplicationContext()'。這將返回一個單獨的'Context'('Application'的子類),一個初始化爲啓動過程的一部分。實際上,這個單例實際上是「預泄漏」的,你不能通過持有引用來進一步泄漏它。 – CommonsWare

4

您可以嘗試對您嘗試訪問的對象使用WeakReference和您的AsyncTask的靜態內部類。 事情是這樣的:

class MyServiceWhichDoesNotLeak extends Service { 

    View view; 
    AsyncTask task; 

    //Your onCreate and stuff 


    private static class BackgroundTask extends AsyncTask<Void, Void, String> { 

     private final WeakReference<View> viewReference; 

     public BackgroundTask(View view) { 
      this.viewReference = new WeakReference<>(view); 
     } 

     @Override 
     protected String doInBackground(Void... params) { 
      // Background stuff 
      return "something"; 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      View view = viewReference.get(); 
      if (view != null) { 
       //Use your view 
      } 
     } 
    } 
} 
3

你可以在你的AsyncTask傳遞WeakReference,例如:

public class MyAsynctask extends AsyncTask<Void, Void, Void> { 

    private WeakReference<Context> mWeakContext; 

    public MyAsynctask (WeakReference<Context> reference) { 
     mWeakContext = reference; 
    } 

    // when you need context use mWeakContext.get(); 
} 

希望這有助於。

+0

如何將片段中的WeakReference傳遞給AsyncTask –

+0

我明白了。 'WeakReference weakTextView1 = new WeakReference(textView1);' –