Android for loop and delay not synchronous

SUMMARY

I have a game game. User clicks image:

First level game

Second level game

The user has 5 seconds to click and select the correct one. After 5 seconds, the correct image will be displayed differently to attract attention, and again after 5 seconds the user will see the next level.

the user can click without waiting for 5 seconds, so when you click, you should go to the next level.

I create viewing and viewing images dynamically. Representations of images are enclosed in a local sqlite database as bytes.

My method creates the oncreate method inside. And I use a while or while loop. Each iteration is a game level. Each level has different image images and different image values.

Delay 5 + 5 seconds I had to use handlers, threads, countdowntimers. Each of them caused problems.

When using handlers, when the user pressed for up to 5 seconds, I could not end the current session.

I do not know if this is correct.

You can see my codes below:

LONG EXPLANATIONS AND CODES

Timer:

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 different threads, but not working. one of them made the screen go black. the other two did not block the loop.

 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 
+7
android
source share
2 answers

You can simply use the handler to achieve your goal, what you should do is create a runnable and declare it outside the handler, then use it by name inside the postDelayed handler, and if the user clicked, just delete all the handler callbacks:

 // 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 
+3
source share

To develop a game, you should use something more professional to implement your game, I recommend that you read this book Getting Games for Android 2nd Edition . It has the basics for 2D and 3D games with various options that you could learn. Now for your code, I suggest that you trace the time on an external thread and force it to send callbacks to the interface that you implement in your main game activity Example:

TimeThread.java

 import android.util.Log; public class TimeThread implements Runnable { Thread thread = null; TimeTickListener listener; volatile boolean running = false; public TimeThread(TimeTickListener listener) { this.listener = listener; } public void resume() { thread = new Thread(this); running = true; if (thread != null) thread.start(); } @Override public void run() { while (running) { // sending callbacks to the mainActivity listener.onTimeTick(); } } public void pause() { running = false; while (true) { try { thread.join(); Log.v("my", "joined "); break; } catch (InterruptedException e) { Log.v("my", "not joined cause : " + e.getMessage()); } } } } 

interface used:

 public interface TimeTickListener { public void onTimeTick(); } 

and here is an example of what mainActivity looks like:

MainActivity.java

 public class MainActivity extends Activity implements TimeTickListener { long startTime = System.nanoTime(); // the interface method that we implemented @Override public void onTimeTick() { // keep trace of the time untill it sums up to 1 sec then do an action // in your situation you can make it to count 5 sec // and make your action here if ((System.nanoTime() - startTime) / 1000000000 >= 1) { totalTime += 1; // this handler is because you should change the textView from its // original thread // and it is not allowed to be edited from another thread // in your case you should change the imageViews like this in the main thread mainHandler.post(new Runnable() { @Override public void run() { text.setText(totalTime + " seconds passed "); } }); startTime = System.nanoTime(); // and this is how to terminate the thread manually (optional) if (totalTime >= 10) { timeThread.pause(); } } } Handler mainHandler; TextView text; float totalTime = 0; TimeThread timeThread; TimeTickListener listener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); text = new TextView(this); text.setText("wait..."); setContentView(text); // initializing the handler with the main activity looper mainHandler = new Handler(getMainLooper()); //getting our implemented listener to pass it to the timeThread for the callbacks listener = (TimeTickListener) this; timeThread = new TimeThread(listener); // resume method will launch the thread and make it start calling the interface method (onTimeTick) timeThread.resume(); } @Override protected void onPause() { // don't forget to pause the thread here timeThread.pause(); super.onPause(); } } 

This code has been tested and received great success, the time is accurately and very well synchronized.

However, it is a bit more complicated and requires a bit of resources, because the while loop in the second thread has so many advantages and will allow you to properly manage your application.

This answer is all for getting the exact time, how to deal with the flow of time tracing and where to do it, but if you have problems with the game logic or time is hidden and the images are shown to the user in this case this is not the answer you want, so tell me and I will try to help you.

+2
source share

All Articles