AsyncTask 类中的 getApplicationContext 方法?

13

我有一些私有的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);
      }

}

1
你应该在构造函数中传递一个上下文。 - Raghav Sood
你应该使用带有上下文参数的AsyncTask构造函数。 - Ashok
将上下文传递给构造函数不是首选方法,因为它会泄漏上下文对象。[https://dev59.com/SVYN5IYBdhLWcg3w2rWU] - Niaz Ahsan
3个回答

13

我在实例化AsyncTask时是否应该传入一个上下文并从中构建?

你别无选择,因为你无法以其他方式获取Context


@CommonsWare,您能详细说明一下吗?为什么getApplicationContext()AsyncTask的UI部分(例如onPreExecute()onPostExecute())中不起作用?这个链接“建议”它可以工作,但我的实际情况表明它无法编译(Sdk 8-17); http://www.daniweb.com/software-development/mobile-development/threads/449375/how-to-get-context-in-asynctask - donfede
2
@donfede:"为什么在AsyncTask的UI部分中getApplicationContext()无法工作?" -- 因为getApplicationContext()Context的一个方法,而AsyncTask并没有继承Context - CommonsWare
3
如果在异步任务完成之前销毁了活动,这不会导致泄漏吗? - MikeIsrael
2
@MikeIsrael:在任务持续期间,是的。 AsyncTask 适用于短操作。任何需要超过一秒钟的操作都应该由其他方式处理,例如 IntentService - CommonsWare
@CommonsWare 谢谢,一如既往地赞赏简明而精确的回答。 - MikeIsrael

1
您应该像这样做。在我的情况下它起作用:

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);
  }

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接