我使用的代码如下:
_thread = new Thread(){
@Override
public void run() {
try {
while (true) {
operate();
Thread.sleep(DELAY);
}
} catch (InterruptedException e) {
// Doesn't matters...
}
}
};
操作函数如下所示:
// does things....
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// adds an ImageView to the screen
}
});
// does other things...
在底线,我想要实现的是偶尔发生的操作,不会中断主线程和UI,比如游戏循环。
在运行()的前2次运行中,它添加了ImageView,一切正常,但是在2或3次后它停止添加ImageViews,但UI仍然照常运行。当我调试问题时,我发现3次之后不再调用Runnable的run()方法,甚至认为操作函数被调用了。
有线的东西(对我而言)是当我删除Thread.sleep时,一切正常(当然要快得多......)。我尝试用很长的for循环替换它(仅用于检查)并且它有效,但当然它不适合解决问题。
我读到了这个问题,大多数提出这个问题的人在主线程上做了一个thread.sleep或一个无限循环,但是,正如我所看到的,我没有做过这样的事情。很多人写道你应该用Handler.postDelayed替换Thread.sleep。我试图这样做,但它没有用,也许我做错了。我甚至尝试用我在互联网上找到的其他选项替换runOnUiThread,但所有这些选项都给了我相同的结果。我试图替换我将视图添加到活动的方法,但所有这些方法再次给出了相同的结果。
等待对此应用程序至关重要。我必须找到一种方法来等待某个时间然后在UI线程上执行一个函数,因为这个模式在我的应用程序中至少返回了几次。
答案 0 :(得分:2)
听起来你想要一个帖子延迟,以便你可以在延迟一段时间后在UI线程上执行代码。 Handler Post Delay
private static final int DELAY = 500;
private Handler mHandler;
private Runnable mRunnable;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start();
}
private void start()
{
mHandler = new Handler();
mRunnable = new MyRunnable(this);
mHandler.postDelayed(mRunnable, DELAY);
}
private void stop()
{
mHandler.removeCallbacks(mRunnable);
}
private void doSomething()
{
// Do your stuff here.
// Reschedule.
mHandler.postDelayed(mRunnable, DELAY);
}
创建Runnable的推荐方法。
private static class MyRunnable implements Runnable
{
private WeakReference<MainActivity> mRef;
// In here you can pass any object that you need.
MyRunnable(MainActivity activity)
{
mRef = new WeakReference<MainActivity>(activity);
}
@Override
public void run()
{
// Safety check to avoid leaking.
MainActivity activity = mRef.get();
if(activity == null)
{
return;
}
// Do something here.
activity.doSomething();
}
}
答案 1 :(得分:0)
可能有几个原因导致UI Runnable没有被执行。可能activity
变量有些东西搞砸了,或者它错误地引用了上下文,或者正如你所说Thread.sleep()
可能导致问题。此时需要查看更多代码部分以更好地解决问题。
实现逻辑的更好方法是使用预定的Timer
,而不是使用带有Thread.sleep()
的无限循环。它将在后台线程中执行代码。然后使用Handler
更新UI而不是activity.runOnUiThread()
。这是一个例子:
// Global variable within the activity
private Handler handler;
// Activity's onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
handler = new Handler(getMainLooper());
Timer timer = new Timer("ScheduledTask");
// Timer must be started on the Main UI thread as such.
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
operate();
}
}, 0L, DELAY);
}
private void operate() {
// does things in background....
handler.post(new Runnable() {
@Override
public void run() {
// adds an ImageView to the screen from within the Main UI thread
}
});
// does other things in the background...
}