在Android应用程序中非冻结睡眠

时间:2014-07-04 13:57:16

标签: android

我正在以编程方式创建一些视觉事件,即在单击按钮时显示图像,然后等待500毫秒,然后以滑动效果将图像扫出屏幕。但是,如果我尝试使用Thread.sleep,它在进入睡眠状态之前不会处理先前的UI事件,因此在这种情况下,图像应该设置为可见,然后它会休眠,但它会在图像变为可见之前休眠。移动视图的循环也太快了 - 我希望使用Thread.sleep来减慢它的速度,但看起来这样也无法工作。

有什么更好的方法可以做到这一点?

View passImage = frontView.findViewWithTag(SearchConstants.PassImageTag);
passImage.setAlpha((float) 1);
frontView.setRotation((float)-10);

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

for (float i = 0; i > 0 - halfScreenWidth; i--) {
    frontView.setX(i);
}

2 个答案:

答案 0 :(得分:4)

从不使用Thread.sleep()。如果您这样做,则会阻止当前Thread。这意味着,如果您要在用户界面Thread.sleep()上致电Thread,用户界面就会冻结,您无法再与之互动,就像您所经历的那样。有多种选择来安排将来的某项任务或事件。你可以:

  1. 使用Timer
  2. HandlerpostDelayed()
  3. 一起使用
  4. 使用AlarmManager

  5. 使用Timer

    Timer可用于安排TimerTask。它们最适合在几秒到几分钟内安排任务。

    首先你必须写一个TimerTask。该任务将在时间结束后执行。 TimerTask可能如下所示:

    private class ExampleTask extends TimerTask {
    
        @Override
        public void run() {
            // This method is called once the time is elapsed   
        }
    }
    

    您可以按照以下方式安排TimerTask

    Timer timer = new Timer();
    ExampleTask task = new ExampleTask();
    
    // Executes the task in 500 milliseconds
    timer.schedule(task, 500); 
    

    使用Handler postDelayed()

    使用Handler与使用Timer非常相似,但我个人更喜欢使用Timer,因为它们更适合这样的工作。 Handler最初旨在促进Threads与其他内容之间的沟通,但它们也可用于安排Runnable。首先,我们必须定义Runnable,这与TimerTask

    非常相似
    Runnable runnable = new Runnable() {
    
        @Override
        public void run() {
            // This method will be executed in the future
        }
    };
    

    现在我们安排Runnable以后postDelayed()执行Handler handler = new Handler(); // Execute the Runnable in 500 milliseconds handler.postDelayed(runnable, 500);

    AlarmManager

    使用AlarmManager

    Intent是一项系统服务,可用于在将来的某个时间点发送Intent。您可以使用AlarmManager将此AlarmManager计划在未来数月甚至数年,唯一的缺点是您必须在重新启动手机时重置所有闹钟。

    你可以像这样获得AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    Intent

    您还需要将您要发送的PendingIntent换成Intent intent = new Intent(SOME_ACTION); ... // Setup your intent PendingIntent pendingIntent = PendingIntent.getService(context, REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);

    Intent

    您可以安排Date以特定manager.set(AlarmManager.RTC, date.getTime(), pendingIntent); 的方式发送,如下所示:

    {{1}}

答案 1 :(得分:0)

您还可以使用AsyncTask

class ShowImageTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected Integer doInBackground( Void... args ) {
   Thread.sleep( 500 );
   showImage();
  }

}

void someMethod(){
  new ShowImageTask().executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR );
}