在我的小应用程序中,我从系统(不受我控制)收到一系列排队的onEventXXX()。
无法保证onEventXXX()的时间安排。唯一可以肯定的是,它们是以顺序收到的,并将它们放入队列中。
在onEventXXX()内部,我必须触发一个操作(O),无法在另一个进程(P)进行时启动。
但我不能放弃这个"解雇手术(O)"。我必须等到那个过程(P)完成,然后解雇它。
IOW,我必须排队或至少推迟"解雇手术"直到该过程(P)完成。
我实现这一点的直接想法是,不是触发操作(O),我会:
但是知道Android的丰富性,我怀疑有一种更好的方法可以做到这一点,已经内置到系统/ API中。
如果有更好的方法来实现上述目标,它会是什么?
答案 0 :(得分:3)
我会这样做:
,检查进程是否退出,如果是,立即执行您的操作(您也可以省略此步骤并执行第2步)
否则,创建AsyncTask,在doInBackground中调用Process.waitfor(),完成后,在onPostExecute中执行操作
使用这种方法,您可以尽快在UI线程上调用操作。
请勿使用计时器执行此任务。计时器是一种“轮询”方法。如果你的计时器滴答太快,你只会浪费CPU时间。如果它的速度太快,你的行动可能会被推迟。
答案 1 :(得分:3)
CountDownLatch将是最佳解决方案。
我没有详细的例子,但我认为你可以轻松使用它。
流程如下所示
如果你这样编码,你可以轻松处理很多情况。
我在asyc单元测试中使用CountDownLatch。您可以在此处查看我的代码:http://kingori.egloos.com/4554640
虽然它不像你的情况,但你可以从我的代码中获取提示。此外,CountDownLatch的javadoc提供了很好的示例。
答案 2 :(得分:2)
首先,我建议如果用户点击某些东西,他应该看到一些直接的结果,在你的情况下,如果按钮动作需要等待某事,立即在按钮上添加一个圆圈加载动画,向用户发出信号行动很快就会发生。
现在为行动本身, 如果在一个(或几个)可能的后台进程之后只有一个(或几个)这样的可能行为, 我将按钮同步引发一个标志(可能通过一个持久的类成员)并让长进程同步在完成它的进程并执行请求后检查该标志完成行动。
另一种可能的选择,如果使用wait和notify让按钮代码等待进程完成,这通常被认为是Java中非常高性能的解决方案:
例如(忽略拼写错误,这是现场的):
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
v.post(new Runnable() {
@Override
public void run() {
synchronized (lockObject) {
try {
lockObject.wait();
doAction();
} catch (InterruptedException e) {}
}
}
}
}
}
然后在完成时有一个很长的进程notify
。
请注意,new Runnable()
不创建新线程,只是将Runnable
添加到View
的线程队列
正如鼠标所建议的那样,按钮onClick处理程序应检查进程当前是否正在运行,如果是,则立即执行操作。
这样您就不需要创建新线程(或实际上是线程池的AsyncTask)