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