2017-08-12 40 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);' –