等待一个 Runnable 完成,然后再运行另一个 Runnable

2022-09-02 02:59:24

我有一个带有主标签活动的Android应用程序,以及各个标签中的几个活动。在我的主要活动的onCreate()中,我有一个运行可创建列表的运行项,在各个活动中,我利用这个列表。

在各个活动的onCreate()中,我也有在列表中操作的Runnables。但是,我需要这些 Runnables 仅在主选项卡活动的 Runnable 完成创建列表时运行,否则我将获得一个空列表。我正试图找到一种优雅的方法来做到这一点。现在,在我的主要活动的 Runnable 中,我正在设置一个全局布尔变量 isDone,而在我的个人活动的 Runnable 中,我正在等待 isDone 通过 while 循环进行设置。这有效,但可能不是最好的方法。

有什么想法吗?

谢谢。

编辑:我正在尝试以下代码,但我收到运行时错误:

在我的 MainActivity's Runnable 中:

mainRunnable = new Runnable() {
  public void run() {
    try {
      generateList();
      synchronized(this) {
      listDone = true;
      notifyAll();
    }
  } catch (Exception e) {
      Log.e("BACKGROUND_PROC", e.getMessage());
    }
  }
};
Thread thread = new Thread(null, mainRunnable, "Background");
thread.start();

在我的OtherActivity的Runnable中:

otherRunnable = new Runnable() {
  public void run() {
    synchronized(MainActivity.mainRunnable) {
      if (!MainActivity.getListDone()) {
        try {
          wait();
        } catch (InterruptedException e) {
        }
      }
    }
  }
};
Thread thread = new Thread(null, otherRunnable, "Background");
thread.start();

mainRunnable似乎完全运行,但另一个Runnable似乎导致应用程序崩溃。我收到以下错误消息:

01-10 15:41:25.543: E/WindowManager(7074): Activity com.myapp.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40539850 that was originally added here
01-10 15:41:25.543: E/WindowManager(7074): android.view.WindowLeaked: Activity com.myapp.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40539850 that was originally added here

答案 1

您可以使用 和 方法。waitnotify

为此,需要有一些全局可访问的对象,其锁在此时间点未被程序中的其他任何内容使用。我假设列表创建本身可以扮演这个角色。Runnable

因此,您可以将类似如下的内容添加到列表创建类中:Runnable

private boolean listsDone = false;

boolean getListsDone() {
    return listsDone;
}

在创建列表完成后,它的方法会立即出现类似的东西:run()

synchronized (this) {
    listsDone = true;
    notifyAll();
}

对于其他 s' 方法,在它们需要等待的时候,情况也是如此:Runnablerun()

synchronized (listCreatingRunnableObject) {
    if (!listCreatingRunnableObject.getListsDone()) {
        try {
            listCreatingRunnableObject.wait();
        } catch (InterruptedException e) {
            // handle it somehow
        }
    }
}

更新:为了澄清,两个块需要在同一个对象上同步,并且您必须调用和该对象。如果对象是 ,则对于第一个对象,它可以是隐式的(如上面的代码中所示),但如果它是活动,则需要在这两种情况下显式使用活动对象。synchronizedwait()notifyAll()Runnable


答案 2

你可以使用如下:Queue

public class RunQueue implemements Runnable
{
  private List<Runnable> list = new ArrayList<Runnable>();

  public void queue(Runnable task)
  {
    list.add(task);
  }

  public void run()
  {
    while(list.size() > 0)
    {
      Runnable task = list.get(0);

      list.remove(0);
      task.run();
    } 
  }
}

这允许您使用一个线程而不是多个线程。您可以维护所有现有的“Runnable”对象,同时清理它们用于等待和联接的任何代码。


推荐