这是一个我不确定如何去做的人。 基本上我有一个ASyncTask类,它在后台照常开展业务。我想在完成后做点什么。现在,在你跳到前面并说'#34;只需使用onPostExecute()"之后,就会有一个问题。我需要运行的方法是在activity而不是Task类。
我看到它的方式,我有两个选择。
CustomTask task = new CustomTask();
task.execute(passedParams);
//when(task.execute is finished)
{
doX();
}
我希望我可以这样做,因为它非常简单,让我检查任务何时完成,而不必经常轮询活动和getStatus()活动。 我不认为我会幸运,但如果有人有办法,那就太棒了
将活动作为参数传递给ASyncTask。这很乱,我对使用它不满意,但除了那个和对象参考,我不知道它是否会起作用
CustomTask task = new CustomTask();
task.execute(passedParams,MyActivity);
然后在Tasks onPostExecute中,我可以让它调用MyActivity.doX();
第三种方法是使asynctask成为活动本身的私有类,但我真的希望将它保持独立。可重复性和什么不 -
对此有何想法?
总结一下,在task.execute完成后需要doX()。任何想法都赞赏。
好的,我知道我在这里滚动。我一直在想新的解决方案。可以从任何位置调用的类方法或静态方法。
public class ProfileSettings extends Activity
{
public static void doX()
{
//Logic...
}
}
来自AsyncTask
MyActivity.doX();
答案 0 :(得分:6)
选项B应该有效,有时是一个不错的选择,但有时我会使用匿名类。当您从活动中调用它时:
CustomTask task = new CustomTask() {
@Override
protected void onPostExecute(Long result) {
super.onPostExecute(result);
MyActivity.this.doX();
}
}.execute();
答案 1 :(得分:2)
选项A:
Android API已经为此提供了内置功能AsyncTask.get():
CustomTask task = new CustomTask();
task.execute(passedParams);
Result result = task.get(); // <- Block UI thread and waiting for AsyncTask finish.
this.doX(result);
正如您所看到的,这是一个不好的做法,因为它阻止了UI线程并可能导致ANR异常。通过这样做,您实际上牺牲了AsyncTask的好处,并使其与UI线程同步运行。
选项B和C :
两者都是正确的做法,通过在onPostExecute()方法中调用doX()方法,
AsyncTask,正如其名称所述,与UI线程异步运行后台线程,一旦后台线程完成,就在UI线程上调用onPostExecute方法。在项目构建时,没有办法确切地告诉onPostExecute方法何时被调用(即当doInBackground方法完成时),因为它是在应用程序运行时确定的,我们唯一知道的是onPostExecute方法保证在UI线程上调用在未来的某个时刻,换句话说,在项目构建时编写代码时,我们永远不知道doInBackground何时完成,代码执行跳转到onPostExecute方法之外的UI线程(除非你在代码中实现一些等待机制,如Option一个)。因此onPostExecute方法的目的是在doInBackground方法完成后处理所有内容,这也是为什么onPostExecute方法的唯一参数是doInBackground方法返回的结果。
选项B和C之间的区别在于是将AsyncTask实现为内部类还是单独的类。这已在StackOverflow中多次讨论和讨论过。大多数人认为将它们分开以获得可重复使用的原因是好的。从我的观点来看,我不同意它。 Java编程语言有其原因提供内部类语法以适应某些特殊的编码情况,当从OOP角度讨论代码重构时,更多地考虑问题抽象级别,而不是简单地从代码级别的Activity类中删除内部类。正如您在示例中所看到的,通过将AsyncTask与Activity隔离,您不会获得任何实际好处,而是增加代码复杂性(需要在类之间传递活动上下文引用)来解决问题。
我认为你真正的问题是我们是否应该从Activity中隔离AsyncTask内部类实现。要获得更好的OOP代码重构(可重用性,可测试性等),请在此StackOverflow question中查看我的答案,了解如何正确地将业务层与应用程序UI层隔离。
答案 2 :(得分:1)
我能够通过界面实现此功能:
http://howcanisolve.com/38646/android-java-equivalent-of-ios-block-callbacks
public interface ICallbacks {
public void onResponse(JSONObject response);
public void onError(VolleyError error);
}
然后在您的例程代码中添加一个新的Callbacks实例:
public static void getPassagesForFirebaseUser(FirebaseUser user,
Context context, ICallbacks events) {
//here code and call ICallbacks methods
if(result){ events.onResponse(response); }
if(error){ events.onError(err); }
}
最终你可以用以下方法调用方法:
getPassagesForFirebaseUser(user, context, new ICallbacks(){
@Override
public void onResponse(JSONObject response){
//Success !!!
}
@Override
public void onError(VolleyError response){
//Error !!!
}
});
答案 3 :(得分:0)
选项B通常更安全。但即便如此,你还需要小心。您需要在Activity
中存储ASyncTask
(不仅仅是类)的实例。如果Activity
在任务运行时被破坏(如果用户按下后退按钮怎么办?),则需要通知任务,以便任务不会尝试在死亡Activity
上调用方法。
如果Activity
恢复生机(例如,在屏幕旋转后),则需要将新Activity
重新附加到正在运行的任务中。
这些事情很繁琐。