我可以在处理程序/可运行对象内执行网络操作(UI 阻止)吗?



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

我对处理程序及其运行位置有一些误解。

查看代码

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 线程中运行,并且我将无法在那里进行任何网络调用没有?
  • 如果是,我该怎么办?创建并使用单独的线程?
  • 如果我创建了一个新线程,如何运行延迟后方法?线程没有开机自检延迟?
  • 不使用处理程序/可运行和使用 TimerTask 和 Runnable 是更好的方法吗?或者,就像上面的处理程序/可运行一样,它也将在 UI 线程上运行,除非在单独的线程中创建。

当你构造一个处理程序时,它绑定到构造它的线程。

onCreate()在 UI 线程上运行,因此

此处理程序将绑定到主线程上的 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
          }
      };
      synchronized (this) {
          this.notifyAll();
      }
      Looper.loop();
  }
}

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

mLooperThread = new LooperThread();
mLooperThread.start();
synchronized (mLooperThread) {
  while (null == mLooperThread.mHandler) {
    mLooperThread.wait();
  }
}
mLooperThread.mHandler.postDelayed(r , 5000);

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

对于需要与 UI 交互的任务,AsyncTask 可能更好,因为它包含一种机制,用于在 UI 线程上完成任务时运行接触视图的内容,因为任何接触视图的内容都必须在 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.runnnable, long(](https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable, long((

或者要求活动在 UI 上运行它:

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

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

最新更新