活动会启动在后台线程中运行的长时间运行的异步任务。此后台任务应在完成时将结果返回给活动(例如,通知用户操作成功或失败)
结果可以随时到达。问题在于: - 可以销毁活动的原始实例对象(例如,旋转屏幕) - 没有现成活动(旧活动被破坏,新活动尚未开始) - 用户更改了可见活动(按下后退按钮,或按下主页按钮等)
请为此类技术任务提供设计模式。
答案 0 :(得分:1)
结果可以随时到达。问题在于: - 活动的原始实例对象可能被破坏(例如,屏幕被旋转)
你可以实现一个轮换感知AsyncTask
,如Mark Murphy(“CommonsWare”)here所述。
没有现成活动(旧活动被破坏,新活动尚未开始)
如果您的意思是因为onRetainNonConfigurationInstance()
和onCreate()
之间的转换,请阅读上面的帖子,他解释了为什么这不应该是一个问题。
用户更改了可见活动(按下后退按钮,或按下主页按钮等)
否则,如果您的意思是Activities
,长期数据加载,我相信您可以实现自己的Loader(例如,AsyncTaskLoader
)并获得满意的结果,因为它们抽象了所有通常的生命周期你需要照顾的开销。
答案 1 :(得分:0)
有几种方法可以解决这个问题。
的AsyncTask:
public class AsyncTask<Void, Void, T extends Parcelable> {
private final Context mApplicationContext;
public MyAsyncTask(Context context) {
mApplicationContext = context.getApplicationContext();
}
public void onPostExecute(T result) {
Intent intent = new Intent(String.format("%s.DONE", mApplicationContext.getPackageName()));
intent.putExtra("Data", result);
mApplicationContext.sendBroadcast(intent);
}
}
然后在你的活动中:
public class FooActivity extends Activity {
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent data) {
if (TextUtils.equals(data.getAction(), String.format("%s.DONE", context.getPackageName()) {
Object o = data.getParacelableExtra("DONE");
// DO SOMETHING WITH IT
}
}
};
public void onCreate(Bundle b) {
...
registerReceiver(mReceiver, new IntentFilter(String.format("%s.DONE", getPackageName())));
}
public void onDestroy() {
...
unregisterReceiver(mReceiver);
}
}
OR
试试这个:
public class MYActivity extends Activity implements MyCustomAsyncTask.Listener {
private MyCustomAsyncTask<?, ?, ?> mTask;
public Object onRetainNonConfigurationInstance() {
if (mTask != null) {
mTask.setListener(null);
}
return mTask;
}
public void onCreate(Bundle b) {
mTask = getLastNonConfigurationInstance();
if (mTask == null) {
mTask = new MyCustomAsyncTask(....);
}
mTask.setListener(this);
}
MyCustomAsyncTask
public class MyCustomAsyncTask<Void, Void, Object> extends AsyncTask {
public interface Listener {
public void doSomethingWithThis(Object o);
}
private mListener;
public void setListener(Listener listener) {
mListener = listener;
}
public void onPostExecute(Object result) {
if (mListener != null) {
mListener.doSomethingWithThis(result);
}
}
...
}