从AsyncTask或服务通知UI组件的最佳实践

时间:2013-05-16 19:01:36

标签: android android-asynctask android-service

我一直在阅读使用AsyncTask类来执行更短的后台操作和服务以实现持久的操作。

那么在使用AsyncTask类时,Android中通知UI有关后台进程更改的最佳做法是什么?我应该使用经典的MVC模型并创建一个监听器(最好是在扩展Application类的类中),还是有一种在Android中执行此操作的标准方法?

我已阅读AsyncTask reference并且似​​乎onProgressUpdate()方法仅在例如任务本身中使用ProgressDialog时才有用。

谢谢!

3 个答案:

答案 0 :(得分:4)

如果要更新的组件是启动更新作业的组件(通过AsyncTask或Service),则应该使用内部AsyncTask

AsyncTask为您提供两个更新UI的位置:

  • 要与doInBackground()中执行的任务并行更新UI(例如更新ProgressBar),您必须在doInBackground()方法中调用publishProgress()。然后,您必须在onProgressUpdate()方法中更新UI。
  • 要在任务完成时更新UI,您必须在onPostExecute()方法中执行此操作。

见:
doInBackground()
publishProgress()
onProgressUpdate()
onPostExecute()

编辑:

public class Home extends Activity implements OnClickListener {
    private Button mButton;
    private TextView mTextView;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);
        mButton   = (Button) findViewById(R.id.myButton);
        mTextView = (TextView) findViewById(R.id.myTextView);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.myButton:
            (new MyAsyncTask()).execute();
            break;
        default:
            break;
        }
    }

    private class MyAsyncTask extends AsyncTask<String, int[], Boolean> {

        /** This method runs on a background thread (not on the UI thread) */
        @Override
        protected String doInBackground(String... params) {
            for (int progressValue = 0; progressValue  < 100; progressValue++) {
                publishProgress(progressValue);
            }
        }

        /** This method runs on the UI thread */
        @Override
        protected void onProgressUpdate(Integer... progressValue) {
            // TODO Update your ProgressBar here
            mTextView.setText("Updating : " + progressValue + "/100");
        }

        /**
         * Called after doInBackground() method
         * This method runs on the UI thread
         */
        @Override
        protected void onPostExecute(Boolean result) {
           // TODO Update the UI thread with the final result
           mTextView.setText("Update complete !");

        }
    }
}

您可以找到另一个示例here

答案 1 :(得分:0)

OnProgressUpdate是要走的路。当您声明实现AsyncTask时,您可以定义要通过onProgressUpdate发回的对象,可以对其进行处理以向UI发送更新。否则,如果在尝试更改UI时实现侦听器,则会因为AsyncTask在应用程序主线程外部的线程中执行而导致线程违规。 onProgessUpdate中的任何代码都在调用者主线程中执行,因此它可以毫无问题地更新UI

答案 2 :(得分:0)

AsyncTask vs service-当结果是您的活动的本地时 - 当其他活动不需要您的任务结果时,使用AsyncTask。他们这样做时使用服务。

使用onPorgressUpdate在AsyncTask中提供增量状态通知 - 任务尚未完成时的任何通知。有关任务何时完成的通知,请使用onPostExecute。监听器也可能是合适的,但前提是您需要通知在编译时不一定知道的特定类,而不是通知发布状态更新的通用方法。