Android 异步任务问题

Android 异步任务问题,android,android-activity,android-asynctask,Android,Android Activity,Android Asynctask,我在读关于AsyncTask的东西。这对我来说是可以理解的,但我立刻想到两个问题: 假设我有一个类和一个接口: public MyInterface<T> { void done(T result); } public MyActivity extends Activity implements MyInterface<String> { public void onCreate(Bundle savedInstanceState) {

我在读关于
AsyncTask
的东西。这对我来说是可以理解的,但我立刻想到两个问题:

假设我有一个类和一个接口:

public MyInterface<T>
{
    void done(T result);
}

public MyActivity extends Activity implements MyInterface<String>
{
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        R.getViewByID(R.....);

        //...

        beginTask(urls);
    }

    private void beginTask(URL[] urls)
    {
        ATask task = new ATask(this);
        task.execute(urls);
    }

    @Override
    void done()
    {
        System.out.println("done!");
    }
}
一切都很好。但我担心的是:

1.)

如果由于某些原因调用
异步任务的
活动
MyActivity
),该怎么办 (
ATask
)被销毁,当
ATask
完成后,调用done();在被摧毁的活动中?我们如何预防 这是不可能发生的,还是有办法重建被摧毁的世界
活动
?这里的最佳做法是什么

(二)

另一个场景:如果后台任务需要很长时间(尽管是预期的),该怎么办 应用程序不再在视图中)在
doInBackground
中?那么,它是否会继续持有一种货币 在出于内存的原因应该销毁活动(MyActivity)的时间(即需要调用onStop()的时间)内引用此活动(MyActivity)


在这两种情况下,您都必须重写应用程序onDestroy或activity onStop方法,并调用task.cancel()。因此,您需要根据文档保持对任务对象的引用。

1.):

onStop()
->当该活动对用户不再可见时调用,因为另一个活动已恢复并正在覆盖此活动

ondestroy()
->您在活动被销毁之前收到的最后一个呼叫。这可能是因为活动正在完成(有人对其调用finish()),或者是因为系统临时销毁活动的此实例以节省空间

因此,您需要决定何时调用
任务。取消()
,这可能取决于您的业务逻辑


2.)根据文档
AsyncTask
应仅用于运行几秒钟的操作。每当
异步任务
/
线程
正在运行且您的活动被破坏时,内存就会泄漏,因为它们仍然保存着您活动的引用。为避免任何泄漏,请将
异步任务
/
线程
声明为私有静态内部类并在
onDestroy()中
通过
t.close
关闭线程,如果是
AsyncTask
则将活动设置为
null
mActivity=null
,这样在这两种情况下,您的活动现在都可以进行垃圾收集。

感谢您的回复。但是对于案例2,有没有办法让后台任务运行,让活动被销毁(保存内存),当这个长任务完成时,动态地重新创建活动,然后在此活动上调用done()?我听说,如果我没有弄错的话,即使是方向更改也会导致活动被重新创建(但这不是我在问题中提到的情况。我只是在键入此注释时想到的)。在活动中创建静态布尔字段isRunning,并重写方法onStart(isRunning=true)和onStop(isRunning=false)活动()的名称。在AsyncTask的执行后检查活动是否未运行时,只需使用applicationContext创建意图(顺便说一句,您还需要通过在扩展应用程序的类中重写onCreate来保留applicationContext)和活动类,如applicationContext.startActivity(新意图(applicationContext,MyActivity.class)).你能在回答中详细说明一下吗?谢谢。我在某个地方读到“你的后台任务引用了你的上下文/活动!你在泄漏内存!”这就是问题所在。希望我没弄错。@Unheilig更新了答案,伙计。
public ATask extends AsyncTask<URL, Void, String>
{
    MyInterface<String> handler = null;
    private StringBuilder fetchedResult = new StringBuilder();

    ATask(MyInterface<T> handler)
    {
        this.handler = handler;
    }

    @Override
    protected String doInBackGround(URL urls...)
    {
        URL url = urls[0];
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(url.toString());
        ResponseHandler<String> handler = new BasicResponseHandler<String>();

        String result = null;

        try
        {
            result = client.execute(request, handler);
            fetchResult.append(result);
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        catch(ClientProtocolException e)
        {
            e.printStackTrace();
        }
        finally
        {
            client.getConnectionManager().shutdown();
        }
        return fetchResult.toString();
    }

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

    @Override
    protected void onPostExecute(String result)
    {
        super.onPostExecute(result);
        handler.done(result);
    }
}