如何在Android UI线程异步中执行一些代码?

时间:2012-02-07 08:48:38

标签: android android-asynctask ui-thread

我是Android开发的新手。我已经在Swing和SWT工作了好几年。 Swing和SWT都有一个在UI线程同步和异步中执行代码的策略。典型的用法是在一个线程中做一些耗时人员,然后在UI线程异步中显示结果。

所以我的问题是,Android中是否有类似的策略?这是我的代码。参数runnable是一些耗时代码。此方法将在执行期间显示等待对话框,然后EXPECT在完成后显示Toast。但Toast需要在UI线程中显示。那怎么办?

    public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {

    if (StringUtils.isEmpty(msg)) {
        msg = "processing...";
    }

    final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);

    // execute in a new thread instead of UI thread
    ThreadPoolUtil.execute(new Runnable() {

        public void run() {
            try {
                // some time-consume operation
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                waitingDialog.dismiss();
            }
            // TODO: How to display a Toast message here? execute some code in UI Thread.

        }

    });

}

还有一些关于Android UI系统的话吗?比如线程安全,线程如何协同工作等等。非常感谢!

6 个答案:

答案 0 :(得分:7)

您可以像这样使用AsyncTask。

调用AsyncTask

new getAsynctask().execute("");

这里是geting结果的类。

class getAsynctask extends AsyncTask<String, Long, Integer> {

    protected void onPreExecute() {
        super.onPreExecute();
        loading = ProgressDialog.show(Pass.this, null, "Please wait...");
    }
    protected Integer doInBackground(String... params) {
        try {
            // do your coding
            return null;
        } catch (Exception e) {
            return null;
        }

    }

    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        try {
            if (loading != null && loading.isShowing())
                loading.dismiss();
        } catch (Throwable t) {
            Log.v("this is praki", "loading.dismiss() problem", t);
        }
    }
}

答案 1 :(得分:7)

有几种方法可以做到这一点,

  • AsyncTask -
  

AsyncTask可以正确,轻松地使用UI线程。这个班   允许执行后台操作并在UI上发布结果   线程,而不必操纵线程和/或处理程序。 Example for using AsyncTask

  • 服务 -
  

服务是表示一个的应用程序组件   应用程序希望执行更长时间运行的操作而不是   与用户交互或为其他人提供功能   要使用的应用程序Example for Using Service.

  • IntentService -
  

IntentService是处理异步的Services的基类   请求(表示为Intents)。客户端发送请求   通过startService(Intent)调用;该服务根据需要启动,   使用工作线程依次处理每个Intent,并自行停止   当它用完了。 Example for using IntentService.

答案 2 :(得分:2)

每当您使用不是您的UI线程的Separate线程时,最好的方法是使用Handler。每当你想从你的线程中亲密用户时,假设一个进度然后向Handler发送一条消息。在处理程序内部,您可以处理消息并编写代码片段以更改UI上的任何内容。这是Android的首选方式。请参阅这些link1link2&amp; link3

答案 3 :(得分:2)

您将此AsynTask用作活动的内部类。在后台执行做您想要执行的耗时任务,然后在postexecute上可以显示文本消息。 从您的主要活动中调用此

initTask = new InitTask();
initTask.execute(this);


 protected class InitTask extends AsyncTask<Context, Integer, String> {     
        @Override
        protected String doInBackground(Context... params) {
            // Do the time comsuming task here 
            return "COMPLETE!";
        }

        // -- gets called just before thread begins
        @Override
        protected void onPreExecute() {         
            super.onPreExecute();

        }

        // -- called from the publish progress
        // -- notice that the datatype of the second param gets passed to this
        // method
        @Override
        protected void onProgressUpdate(Integer... values) {

        }

        // -- called if the cancel button is pressed
        @Override
        protected void onCancelled() {
            super.onCancelled();            
        }

        // -- called as soon as doInBackground method completes
        // -- notice that the third param gets passed to this method
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // Show the toast message here
        }
    }

答案 4 :(得分:2)

使用处理程序:

static final int SHOW_TOAST = 0;
public static void showWaitingDialog(final Activity parent, final Runnable runnable, String msg) {

    if (StringUtils.isEmpty(msg)) {
        msg = "processing...";
    }

    final ProgressDialog waitingDialog = ProgressDialog.show(parent, "Please Wait...", msg, true);

    // execute in a new thread instead of UI thread
    ThreadPoolUtil.execute(new Runnable() {

        public void run() {
            try {
                // some time-consume operation
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                waitingDialog.dismiss();
            }
           handler.sendMessage(handler.obtainMessage(SHOW_TOAST));

        }

    });

}

public Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SHOW_TOAST:
                //Toast here
                break;
        }
    }
};

答案 5 :(得分:1)

来自android开发者资源的Painless threading article提供了不同的替代方案,具体取决于特定的SDK版本。

相关问题