【问题标题】:How to update UI when using AsyncTask使用 AsyncTask 时如何更新 UI
【发布时间】:2013-07-24 18:43:11
【问题描述】:

我的简单应用程序设置为在单击 Refresh 按钮时检索 RSS 提要。
单击刷新按钮会启动一个AsyncTask,它会检索提要。 AsyncTask 是主要活动的子类。

这是我的班级的样子:

public class NasaDailyImage extends Activity{
    public ProgressDialog modalDialog = null; //problematic
//------------------------------------------------------------------------------
    @Override
    protected void onCreate(Bundle savedInstanceState){
        //instantiate the ProgressDialog
        Button b = //get reference to button
        b.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                modalDialog.show(); // show modal
                Toast.makeText(getApplicationContext(), "Getting feeds", 500).show();
                new AsyncRetriever().execute(new IotdHandler()); // Get the feeds !!
            }
        });
    }
//------------------------------------------------------------------------------
    public synchronized void resetDisplay(boolean parseErrorOccured, 
        boolean imageErrorOccured,
        IotdHandler newFeeds){
        if(parseErrorOccured || imageErrorOccured){
            // make a Toast
            // do not update display
        }else{
            // make a Toast
            // update display
            // based on new feed
        }
    }
//------------------------------------------------------------------------------
    class AsyncRetriever extends AsyncTask<IotdHandler,Void,IotdHandler>{

        @Override
        protected IotdHandler doInBackground(IotdHandler... arg0) {
            IotdHandler handler = arg0[0];
            handler.processFeed(); // get the RSS feed data !
            return handler;
        }
//------------------------------------------------------------------------------    
        @Override
        protected void onPostExecute(IotdHandler fromInBackground){
            resetDisplay( // call to update the display
            fromInBackground.errorOccured,
            fromInBackground.imageError,
            fromInBackground);
        }
//------------------------------------------------------------------------------


}  

问题在于onCLickListener 中的modalDialog 中的show()。这导致我的应用程序崩溃。 为什么?我该如何解决?

【问题讨论】:

  • 没有show(),应用运行良好
  • 我看不到您在哪里创建任何类型的对话框。它是空的,所以你不能show()它。

标签: android android-asynctask toast


【解决方案1】:

您的ProgressDialognull,因此当您调用show() 时,您会得到NPE。在调用它的方法之前实例化它。

可能像这里这样的地方实例化它,然后在显示之前设置消息,标题,任何你想要的东西

 @Override
protected void onCreate(Bundle savedInstanceState){
    //instantiate the ProgressDialog

   // can set message, title, etc. here

    Button b = //get reference to button
   b.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) { 
    modalDialog = ProgressDialog.show(NasaDailyImage .this, "Enter Title", "Enter Message");

【讨论】:

  • 好吧,还有几个问题:当我在onClickListener 中创建Toast 时,为什么应用程序不会崩溃??那不是在 UI 线程上吗? AFAIK 只有 UI 线程可以对 UI 进行更改
  • 那是UI Thread。您还需要以静态方式调用show()
  • onClick 方法在 UI 线程中工作。您的 toast 有效,因为您使用以下方法对其进行了实例化:Toast.makeText(...)。当您的 modalDialog 为空时
  • 到目前为止我在您的代码中看到的所有内容都在UI Thread 上,doInBackground() 除外
【解决方案2】:

无法在后台线程上更新 ui。 doinBACKground 在后台线程上调用。您应该使用进度对话框来显示异步任务,然后您可以更改用户界面 (UI) 中的任何内容。

第 1 步:首先初始化您的进度对话框。

ProgressDialog progressDialog;

第 2 步:然后在进度对话框开始下方开始您的 doBackground 工作。

progressDialog = ProgressDialog.show(Activity1.this, "",
                        "Loading...");

第 3 步:完成工作后最后关闭进度对话框。

progressDialog.dismiss();

在进度对话框中,您可以更改任何 ui

【讨论】:

  • 等等,我还有一些关于更新 UI 的困惑。我将把它作为一个单独的问题发布。
  • 当然。请继续。
【解决方案3】:

你需要实例化 ProgressDialog:

modalDialog = ProgressDialog.show(this, null, "Please, wait...");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2021-04-04
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多