Android AsyncTask更好的访问Activity上下文方式

6

我花了很长时间才让它正常工作,但这显然不是最佳实践。简而言之,我需要在我的AsyncTask完成时显示一个对话框,但getApplicationContext()无法使用,创建AsyncTask时也无法将其作为参数传递。因此,我已经在我的AsyncTask类中声明了一个公共变量来存储上下文,并在执行之前设置它:

    private OnClickListener clickLoadRefs = new OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d("H","Clicked Load Refs");
        RefreshRefPoints refreshRefPoints = new RefreshRefPoints();
        refreshRefPoints.myCtx=v.getContext();
        refreshRefPoints.execute(v.getContext());
    }
};

private class RefreshRefPoints extends AsyncTask<Context, Integer, Integer> {

    private Integer nPoints=0;
    public Context myCtx;
    private ProgressDialog pd;

    protected Integer doInBackground(Context... ctx) {
        Log.d("H","doInBackground()");
        dbHelper.clearRefPoints();
        requestRefPoints();
        nPoints = parseRefPointsCSV();

        return nPoints;
    }

    protected void onProgressUpdate(Integer... progress) {
    }

    protected void onPreExecute() 
    {
        pd = ProgressDialog.show(myCtx, "Refreshing Reference Points", "Loading...", true,false);
        Log.d( "H", "onPreExecute()" );
    }
    protected void onPostExecute(Integer result) {
        pd.dismiss();
        AlertDialog.Builder builder = new AlertDialog.Builder(myCtx);
        builder.setTitle("Reference points refresh complete");
        builder.setMessage(result+" records loaded");
        builder.setPositiveButton("OK",null);
        builder.show();
        Log.d("H","onPostExecute()");       
    }...etc

有人能向我展示传递上下文的正确方法吗?

谢谢。

3个回答

12

定义一个构造函数并将上下文作为参数传递。这样会更好。

这是我的意思:

private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> {

    private Integer nPoints=0;
    private Context myCtx;
    private ProgressDialog pd;

    public RefreshRefPoints(Context ctx){
        // Now set context
        this.myCtx = ctx;
    }

}

就是这样。


1
但是它会导致内存泄漏。 - Naga Lokesh Kannumoori

10

您还可以使用 YourActivityName.this 来引用活动的 Context。因为活动扩展了 Context,所以这样做是有效的。


1
请注意,如果您的活动未实例化或已终止,调用此答案中的代码将导致空指针异常。 - Dzhuneyt

2

在构造函数中传递上下文

private OnClickListener clickLoadRefs = new OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d("H","Clicked Load Refs");
        RefreshRefPoints refreshRefPoints = new RefreshRefPoints(Your_ActivityName.this);
        refreshRefPoints.myCtx=v.getContext();
        refreshRefPoints.execute(v.getContext());
    }
};


private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> {

    private Integer nPoints=0;
    public Context myCtx;
    private ProgressDialog pd;

public RefreshRefPoints (Context ctx) {
    myCtx = ctx;
}

感谢您的建议,但是我现在遇到了问题。我已经按照您的示例将“extends AsyncTask<Context”更改为“extends AsyncTask<Void>”,但是Eclipse现在对doInBackground提出了抱怨。 - Hein du Plessis
1
在受保护的 Integer doInBackground(Void...) 中放置 Void - Chintan Raghwani
在现代使用片段进行所有操作的背景下,这个答案的价值正在降低。 - ed209

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