【问题标题】:getApplicationContext in AsyncTask class?AsyncTask 类中的getApplicationContext?
【发布时间】:2013-03-07 18:22:21
【问题描述】:

我有几个私有 AsyncTask 方法,我想将它们分解为公共外部类。在我的应用程序中,我有一个扩展 Application 的公共类,它包含一些我想从应用程序的不同部分访问的共享例程。但是,当我分解 AsyncTask 类时,我不再能够调用 getApplicationContext() 来获取对我的应用程序库的引用(该类现在不从 Activity 继承任何东西)。 getBaseContext() 也会有问题。当它被实例化并从那里构建时,我是否应该将上下文传递给 AsyncTask?不确定这是否安全。

import java.util.ArrayList;
import android.os.AsyncTask;

public class DlTask extends AsyncTask
{
    long totalbytes = 0;
    long totalread = 0;
    ArrayList <String> data;

    @Override
    protected void onPreExecute ()
    {   
        AppLib lib = (AppLib) getApplicationContext();

        lib.saveStatusText ("Contacting " + lib.getServerAddress () + ":" + lib.getServerPort () + "...");
       super.onPreExecute ();
    }

      @Override
      protected Object doInBackground (Object... params)
      {
        data = lib.sendCommand (CMD_LIST);
         return true;
      }

      @Override
      protected void onPostExecute (Object result)
      {

         if (data != null)
         {
                    lib.saveStatusText (data.size () + " files found");
         }
         else
         {
            Log.d (TAG, "data is null");
            Toast.makeText (getBaseContext(), msg, Toast.LENGTH_SHORT).show ();                     
         }

         super.onPostExecute(result);
      }

}

【问题讨论】:

  • 你应该在构造函数中传递一个上下文。
  • 你应该使用带有上下文的 AsyncTask 构造函数。
  • 在构造函数中传递上下文不是首选,因为它会泄漏上下文对象。 [stackoverflow.com/questions/46797916/…

标签: android android-asynctask


【解决方案1】:

当 AsyncTask 被实例化并从那里构建时,我是否应该将上下文传递给它?

您别无选择,因为您将无法通过任何其他方式获得Context

【讨论】:

  • 你能详细说明@CommonsWare 吗?为什么 getApplicationContext() 不能从 AsyncTask 的 UI 部分工作? (例如:onPreExecute()onPostExecute())此链接“建议”它可以工作,但我的现实表明它不会编译(Sdk 8 -- 17); daniweb.com/software-development/mobile-development/threads/…
  • @donfede:“为什么 getApplicationContext() 在 AsyncTask 的 UI 部分不起作用?” -- 因为getApplicationContext()Context上的一个方法,而AsyncTask不继承自Context
  • 如果 Activity 在异步任务完成之前被销毁,这不会导致泄漏吗?
  • @MikeIsrael:在任务期间,是的。 AsyncTask 专为短期操作而设计。任何需要超过一秒左右的时间都应该通过其他方式处理,例如IntentService
  • @CommonsWare 谢谢,一如既往的简洁但准确的答案受到赞赏。
【解决方案2】:

你应该这样做。就我而言,它有效:

public class DlTask extends AsyncTask {
     private Context context;

     public DlTask(Context context) { this.context = context; }

     @Override
     protected void onPreExecute() {
         super.onPreExecute();
         ..........
     }

     @Override
     protected Object doInBackground (Object... params)
     {
        data = lib.sendCommand (CMD_LIST);

        return true;
     }

     @Override
     protected void onPostExecute (Object result)
     {

        if (data != null)
     {
         lib.saveStatusText (data.size () + " files found");
     }
     else
     {
        Log.d (TAG, "data is null");
        Toast.makeText (context, msg, Toast.LENGTH_SHORT).show ();              
        //You can use the CONTEXT like this (passing the context variable like parameter
     }

     super.onPostExecute(result);
  }

【讨论】:

    【解决方案3】:

    要么在 AsyncTask 的构造函数中传递 Context,要么在 Application 类中使用静态变量来访问它(设置 sMyInstace = this;)。不过,第一种解决方案更可取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多