我可以在处理程序/ runnables中进行网络操作(UI阻止)吗?

时间:2013-09-25 15:17:44

标签: java android multithreading android-handler

在我的mainActivity中,这是我的应用程序的唯一活动,我正在创建下面的处理程序并在其中运行runnable。

我对处理程序及其运行方式存在一些误解。

参见代码

Handler handler;

    @Override
    protected void onCreate(Bundle bundle)
    {
      handler = new Handler();
      handler.postDelayed(r , 5000);
    }

    Runnable r = new Runnable()
    {
         @Override 
         public void run() {
              FetchServerAndUpdateStatus(); //network stuff in here
              handler.postDelayed(r , 5000);
         }
    }
  • 我假设这个代码仍然会在UI线程中运行,我将无法进行任何网络调用吗?
  • 如果是,我该怎么办?创建并使用单独的线程?
  • 如果我创建了一个新线程,我该如何运行postdelayed方法?帖子没有帖子延迟?
  • 不使用handler / runnable并使用TimerTask和Runnable而不是更好的方法吗?或者,就像上面的处理程序/ runnable一样,它也将在UI线程上运行,除非在单独的线程中创建。

2 个答案:

答案 0 :(得分:2)

构造Handler时,它将绑定到构造它的线程。

onCreate()在UI线程上运行,因此该处理程序将绑定到主线程上的Looper,因此将在该线程上运行。

如果你想要一个可以在另一个线程上使用的处理程序,你可以构造一个。 请参阅looper文档:https://developer.android.com/reference/android/os/Looper.html

哪个有这个块:

class LooperThread extends Thread {
  public Handler mHandler;

  public void run() {
      Looper.prepare();

      mHandler = new Handler() {
          public void handleMessage(Message msg) {
              // process incoming messages here
          }
      };

      Looper.loop();
  }
}

添加此课程,然后在onCreate中执行以下操作:

mLooperThread = new LooperThread();
mLooperThread.start();
mLooperThread.mHandler.postDelayed(r , 5000);

这将导致runnable不在UI线程上运行,这可能是你想要的。

对于需要与UI交互的任务,AsyncTask可能会更好,因为它包含一种在UI线程上完成任务时运行触摸Views的内容的机制,因为触摸View的任何内容都必须在UI上完成线程。

在UI线程上执行的其他机制是发布到视图本身:

https://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable) 要么 [https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable,long)](https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable,long))

或者要求Activity在您的UI上运行它:

https://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

答案 1 :(得分:0)

  1. 这取决于你对处理程序的处理方式,你没有显示,你想如何获得m_handler。如果使用new Handler(Looper.getMainLooper())创建它,它将在UI线程上运行。
  2. 如果要在后台运行代码(网络操作),则应使用AsyncTask