【问题标题】:Asynctask onpostexecute is not updating views if the screen is rotated while doinbackground is excuted如果在执行 doinbackground 时屏幕旋转,Asynctask onpostexecute 不会更新视图
【发布时间】:2015-07-19 07:57:05
【问题描述】:

我有一个简单的程序,我需要根据服务器响应更新列表和文本... 但是,如果在执行 doinbackground 时屏幕旋转,Asynctask onpostexecute 不会更新视图。

我开始知道,在重新创建活动时,onpostexecute 不会更新其视图的原因(同样的问题..这里是链接:Chek this link) 但我对答案并不满意,因为它只是建议限制重新创建活动(我想重新创建活动,因为在我的项目中我在横向模式下有一些额外的布局)。

请不要通过获取片段来建议setretaininstance(true),因为它不调用oncreateview(),这不适合我的项目。

可能作为最后一个选项,我可以在 onpreexecute 中以编程方式限制方向并在 onpostexecute 中释放它。但我认为这仍然不是一个好习惯。

public class MainActivity extends ActionBarActivity {

    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=(TextView) findViewById(R.id.textview);
        if(savedInstanceState==null)
        {
            new myAsync().execute();
        }
    }


    public class myAsync extends AsyncTask<Void, String, Void>
    {

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            textView.setText("started");
            Log.e("started", "started");
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @SuppressWarnings("deprecation")
        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            Log.e("executed", "executed");
        }

    }
}

这是我的示例程序。如果屏幕旋转,textview 不会更新。

请建议。提前致谢。

【问题讨论】:

  • 使用AsyncTaskLoader 而不是AsyncTask。它处理生命周期并提供取消/停止功能
  • 开始工作了..但文档说它受 api 11 支持。我的应用程序应该支持 api 9
  • 它在支持库中..Reference

标签: java android android-asynctask screen-orientation


【解决方案1】:

您可以为myAsyncTask 提供带有setter 的TextView 成员,并将当前任务存储为活动的静态成员。

class MyActivity extends Activity {
  private static AsyncTask myTask = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView textView = (TextView) findViewById(R.id.textview);

    if (myTask == null) {
      new myAsync(textView).execute();
    } else if(myTask.getStatus() != AsyncTask.Status.FINISHED) {
      myTask.set(textView);
    }
  }

  private class myAsync extends AsyncTask<Void, String, Void>
  {
     TextView textView;

     myAsync(TextView textView) {
       this.textView = textView;
     }

     synchronized void setTextView(TextView textView) {
       this.textView = textView;
     }

     ...

  }
}

您仍然需要处理竞争条件。例如。每当活动暂停/恢复时,您可能希望实施一种机制来暂停/恢复您的任务。 您还必须确保任务 textView 仍然有效,并且您在 onPostExecute 中清理您的静态任务。

【讨论】:

    【解决方案2】:

    您可以使用捆绑的概念在其中放入一些字符串。在轮换后重新创建活动时,在 oncreate 方法中检查保存的实例状态是否为空。如果不为空,则使用包检索字符串并更新文本视图。有关此轮换的更多信息,请查看 YouTube 上的 asynctask 和线程播放列表中的 slidenerd 的视频。希望对您有所帮助。

    【讨论】:

    • 因为我的异步还没有完成。我无法将其保存在 onsavedinstance 中..一旦异步完成,我就可以像你所说的那样得到 onsavedinstance 的结果...
    • 试试slidenerd上传器。在线程和异步任务播放列表中,在视频0.17到21中,他使用图像下载应用程序详细解释了这个旋转的事情。试试看,我想它对你很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多