AsyncTask无法在线程android中工作

时间:2011-10-22 04:12:27

标签: android thread-safety android-asynctask

我使用AsyncTask来改变TextView的文本,如下所示:

    private class LongOperation extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        for (String url : urls) {
            response += url;
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        textView.setText(result);
    }
}

如果我在OnClick事件中调用它,一切都会好的:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    textView = (TextView) findViewById(R.id.txt);
    Button button = (Button)this.findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
          new LongOperation().execute(new String[]{"Hello"});
        }
      });
   }

但问题是当我在我的帖子中调用它时,程序被强制关闭

this.closeButton.setOnClickListener(new OnClickListener() {
         @Override
        public void onClick(View v) {
          Thread t= new Thread(){               
           @Override
             public void run(){                                     
              try{
                    //Do something
                    //Then call AsyncTask
                new LongOperation().execute(new String[]{"Hello"});

               }catch(Exception e){}
         }
        };      
         t.start();
        }
      });

我哪里错了?我不明白差异如何在线程中调用AsyncTask。

3 个答案:

答案 0 :(得分:8)

我建议您咨询AsyncTask documentationProcesses and Threads,以便更好地了解其工作原理。基本上,您应该在主线程上创建AsyncTask子类。

当您致电AsyncTask.execute()时,您在主线程上调用了您提供的AsyncTask.onPreExecute,因此您可以进行UI设置。

调用下一个AsyncTask.doInBackground方法,并在其自己的线程中运行。

最后,当您的AsyncTask.doInBackground方法完成时,会在主线程上调用AsyncTask.onPostExecute,您可以进行任何UI清理。

如果您需要在AsyncTask.doInBackground方法中更新用户界面,请拨打AsyncTask.publishProgress,这将在主线程中调用onProgressUpdate

答案 1 :(得分:2)

当您从UI线程调用它时,关联的Context正在运行Activity。当您从常规线程调用它时,没有与该线程关联的有效ContextAsyncTask在自己的线程中执行,你不应该创建自己的线程。如果那是实际代码,那么你就会误解AsyncTask的观点。搜索有关如何使用它的教程。

答案 2 :(得分:1)

添加其他人所说的内容:我认为您可以使用AsyncTask在另一个线程中启动任务,即使您从不同于UI的线程启动AsyncTask也是如此。

但是在这种情况下,唯一的方法是你只能间接修改UI,例如:以某种方式将当前Activity的处理程序传递给此AsyncTask实例,并向其发送消息(处理程序消息得到处理) UI线程)。或者使用活动捕获的广播意图并相应地更新UI等。但这些解决方案似乎有些过度。