简短摘要
我有一个 Activity 游戏。用户将点击图像:
用户有 5 秒的时间点击并选择正确的选项。 5 秒后,正确的 ImageView 将以不同的方式显示以引起注意,5 秒后,用户将再次看到下一个级别。
用户无需等待 5 秒即可点击,因此点击后应立即进入下一级别。
我正在动态创建 View 和 ImageView 。 ImageView 以字节形式从本地数据库 sqlite 中获取。
我的方法是在 oncreate 方法中创建。我使用 for 或 while 循环。每次迭代都是一个游戏级别。每个级别都有不同的 ImageView 和不同的 ImageView 数。
为了延迟 5 + 5 秒,我不得不使用处理程序、线程、倒计时计时器。每一个都造成了问题。
在使用处理程序时,当用户在 5 秒前单击时,我无法终止当前 session 。
不知道这样对不对
你可以在下面看到我的代码:
详细说明和代码
计时器:
nCreate() {
for (int i = 0; i < 2; i++) {
handler.postDelayed(new Runnable() {
public void run() {
imageAnswer.setImageBitmap(bmp);
imageAnswer.setId(R.id.imgAnswer);
//adding image to screen
finalRLayout.removeAllViews();
finalRLayout.addView(imageAnswer, rLayParams);
//starting timer, if no answer in 5 seconds, run again timer
startTimer();
//clicklisterner
imageAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//if clicks true, cancel timer and go to next iteration of for loop
if (view == findViewById(R.id.imgAnswer)) {
Log.d(TAG, "clicked");
//PUT IN CODE HERE TO GET NEXT IMAGE
cancelTimer();
} else { //if not true, run again timer for last chance
Log.d(TAG, "nonclick");
cancelTimer();
startTimer();
}
}
});
}
}, 2000 * i);
} //for end
} //oncreate end
//start timer function
void startTimer() {
cTimer = new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
Log.d(TAG, "ontick");
}
public void onFinish() {
Log.d(TAG, "timer onfinish");
}
};
cTimer.start();
}
//cancel timer
void cancelTimer() {
Log.d(TAG, "canceltimer");
if (cTimer != null)
cTimer.cancel();
}
3 个不同的线程操作但没有工作。其中一个使屏幕进入黑屏。另外两个没有阻止循环的进行。
runnable version
for ( int i = 0; i< 20 ; i++) {
Log.d(TAG, "for i2="+ i);
final int finalI = i;
final RelativeLayout finalRLayout = rLayout;
final Runnable r=new Runnable() {
@Override
public void run() {
Log.d(TAG, "for finali2="+ finalI);
TrainingObject trainingObject = new TrainingObject();
trainingObject = trainingObjectList.get(finalI);
objectCount = 2;
//test icin
Log.d(TAG,"testicin trainingobjectid: "+trainingObject.getTrainingobjectID());
object = dbHandler.getObjectObject(trainingObject.getTrainingobjectAnswer());
RelativeLayout.LayoutParams rLayParams = new RelativeLayout.LayoutParams(140,140);
rLayParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rLayParams.addRule(RelativeLayout.CENTER_IN_PARENT);
imgBytes = object.getObjectImageBlob();
bmp = BitmapFactory.decodeByteArray(imgBytes, 0, imgBytes.length);
imageAnswer.setImageBitmap(bmp);
imageAnswer.setTag(trainingObject.getTrainingobjectAnswer());
imageAnswer.setId(R.id.imgAnswer);
finalRLayout.removeAllViews();
finalRLayout.addView(imageAnswer,rLayParams);
}
};
Log.d(TAG, "3000i2 sonrasi");
handler.postDelayed(r, 6000 * i);
imageAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view == findViewById(R.id.imgAnswer)) {
Log.d(TAG, "clicked");handler.removeCallbacks(r); handler.postDelayed(r, 0);
//PUT IN CODE HERE TO GET NEXT IMAGE
}
else{
Log.d(TAG, "nonclick");
handler.removeCallbacks(r); handler.postDelayed(r, 6000);
}
}
});
}//for end
最佳答案
您可以简单地使用处理程序来实现您的目的,您应该做的是创建一个可运行的并在处理程序外部声明它,然后在 postDelayed 处理程序中通过它的名称使用它,如果用户点击,只需删除所有处理程序回调:
// first create runnable
Runnable r = new Runnable{
public void run(){
//do what you need to do after 5 seconds
}
}
// then create handler
Handler mHandler = new Handler();
// then in your onCreate method
nCreate() {
for (int i = 0; i < 2; i++) {
handler.postDelayed(new Runnable() {
public void run() {
imageAnswer.setImageBitmap(bmp);
imageAnswer.setId(R.id.imgAnswer);
//adding image to screen
finalRLayout.removeAllViews();
finalRLayout.addView(imageAnswer, rLayParams);
//starting handler, if no answer in 5 seconds, run again timer
mHandler.postDelayed(r, 5000);
//clicklisterner
imageAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//if clicks true, cancel timer and go to next iteration of for loop
if (view == findViewById(R.id.imgAnswer)) {
Log.d(TAG, "clicked");
//PUT IN CODE HERE TO GET NEXT IMAGE
myHandler.removeCallbacks(r);
} else { //if not true, run again timer for last chance
Log.d(TAG, "nonclick");
// stop the handler
myHandler.removeCallbacks(r);
// run a new one
mHandler.postDelayed(r, 5000);
}
}
});
}
}, 2000 * i);
} //for end
} //oncreate end
关于Android for循环和延迟不同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37234426/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对
是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述
A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(
有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子