Thread.sleep() inside android application [duplicate] - android

I'm working on a memory game for Android and I'm having a problem. When the user taps the second image - if the images are not the same I want the second image to show for 1, 2 seconds.
What I've tried is to sleep for 1-2 sec. the UI thread after the second image is activated - but this doesn't seem to work - the second image doesn't seem to show! (only the first images is showed)
Here's my code:
public void whenTapedImage(View v, int position)
{
i++;
ImageView imgV=(ImageView)v;
if(i%2!=0)
{
firstClick=position;
imgV.setImageResource(im.images.get(firstClick));
}
else
{
secondClick=position;
imgV.setImageResource(im.images.get(secondClick));
try {
Thread.currentThread().sleep(1000);
if(!(im.images.get(firstClick).equals(im.images.get(secondClick))))
{
Toast.makeText(easyGame.this, "Try Again!", Toast.LENGTH_SHORT).show();
im.notifyDataSetChanged();
gridview.setAdapter(im);
gridview.invalidate();
aux=player1Turn;
player1Turn=player2Turn;
player2Turn=aux;
}
else{
done=done+2;
ImageAdapter.keepVisibleViews.add(firstClick);
ImageAdapter.keepVisibleViews.add(secondClick);
if(player1Turn==true)
{
player1Score++;
String score=Integer.toString(player1Score);
score1.setText(score);
}
if(player2Turn==true)
{
player2Score++;
String score=Integer.toString(player2Score);
score2.setText(score);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
What am I doing wrong?

You must not sleep the UI thread as this would prevent android from delivering any other events to your activity's UI.
Instead, do something such as use a timer and have the timer's method use the run on ui thread facility to make the desired postponed change.
For robustness you may need to implement a state machine (either formally, or in effect) to keep track of what is supposed to be happening - you'll need to decide if the current delay should be aborted or enforced if another button is pushed, and make the state machine treat that appropriately.

This is similar to Waiting in android app
Try following the solution posted there and use the Timer Class

Related

performClick() not working because it's in a different thread

So essentially I want to simulate a button click in my android app, using a timer.
When the timer goes off, I do find the button then try using performClick() which crashes and closes the app.
The log of course made the problem quite clear: "Only the original thread that created a view hierarchy can touch its views." Which makes total sense. Duh!
But I assume that since it's all my app there is a way to properly do this?
You can use runOnUiThread() in a background Thread in order to update the UI Thread:
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Run your functions here
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}

How to change android screen during function

I am trying to change the screen of an app during a function is running.
public void StartRecording(View view)
{
start_button.setEnabled(false);
stop_button.setEnabled(true);
recording = true;
while(recording==true)
{
// Here is a code that changes many views on the screen
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
function StartRecording() is called by clicking the start_button in the xml file.
recording is set to false when clicking the stop_button.
The views on the screen should change, wait a second, change again, wait a second and so on.
But what happens is that the function waits until the loop is finished and then shows only the final screen change. What am I doing wrong?
Thanks ahead : )
Edit:
I tried using Handler and it has the same result..
private final Handler mHandler = new Handler(Looper.getMainLooper())
{
public void handleMessage(Message msg)
{
tv.setText((String) msg.obj);
}
};
tv is a textView. Instead of using tv.setText just above the try{} in the code above, I sent a message to mHandler to change the text, and it still changes it only after the whole startRecording function is over.
Now, what am I doing wrong? :/
What am I doing wrong
you are calling sleep wait the UI Thread, that is responsible for drawing your views and handle events. If you want to schedule 10 different redrawing of your views, you can use and Handler and its postDelayed method

What may prevent the UI in android to be updated on time?

I'm developing an Android app that has to update it's UI depending on receiving and processing some server responses, I'm using runOnUiThread for that. I have like five activities in that app, all is working very well but one requires me to relaunch the Activity(like going to another one and then returning to it) or interacting with it in order to that update takes place, and that is the way i'm using with all the Activities including the infected one:
runOnUiThread(new Runnable() {
public void run() {
try {
response_received(response);
} catch (Exception e) {
e.printStackTrace(); // never catch any Exceptions
}
}
});
private static void response_received(JSONObject response) throws Exception{
try {
int volume_setted = response.getInt(volume);
Normal_Activity.volume_value.setText(String.valueOf(volume_setted)); // the Volume TextView updated efficiently
Infected_Activity.volume_value.setText(String.valueOf(volume_setted)); // has the problem mentioned above
} catch (JSONException ex) {
}
}
I'm pretty sure the problem is not in the TextView as all the Activity UI has this problem but i just posted an example.
Do not directly set values in a Activity from another Activity. If you want to pass data to Another activity always use Intents. check the below link
pass data from intent to an other intent
If you want to start another activity and get result back check the below link
http://developer.android.com/training/basics/intents/result.html

Count time(seconds) the button remained clicked in Android

I want to make a program which will tell me the number of seconds I kept holding the button.
for example if I clicked the button for 5 seconds, it should tell me the button remained pressed for 5 seconds.
is this achievable in android?
This is how I tried, didn't work because when I put the while loop in, the button stays clicked even I press it for just one second. The program doesn't crash but the button remains clicked and I think it freezes.
thread = new HandlerThread("");
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
while(btn.isPressed())
{
try {
thread.sleep(1000);
total = total++;
temp = temp++;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(MainActivity.this, ""+temp+" "+total, 0).show();
}
});
You could use time stamps, and an OnTouchListener to achieve this.
When your OnTouchListener receives an ACTION_DOWN event, store the first time stamp. When it receives an ACTION_UP event, store the second time stamp and calculate the difference between the two.
As mentioned by Raghunandan, you should never block on the UI thread using calls such as thread.sleep, as this will cause the UI to stop responding, and in some cases can cause the program to be killed because of this.
Here is an example of what I've outlined above. Please note, this code was written from memory, and has not been tested, but you should get the general gist of it.
btn.setOnTouchListener(new OnTouchListener() {
private long firstTouchTS = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
this.firstTouchTS = System.currentTimeMillis();
} else if (event.getaction()==MotionEvent.ACTION_UP) {
Toast.makeText(MainActivity.this,((System.currentTimeMillis()-this.firstTouchTS)/1000)+" seconds",0).show();
}
}
});
References: OnTouchListener MotionEvent
thread.sleep(1000);
Calling sleep on the ui thread hence it freezes. Do not call sleep on the ui thread. It blocks the ui thread.
Read
http://developer.android.com/training/articles/perf-anr.html.
Use a Handler if you want to repeat some task

Puzzle: Bluetooth data send interval shortened by half after each reconnect

I modified the standard Bluetoothchat example to send 4 bytes of data at a time to a bluetooth device every half a second. It works fine if I start the App fresh. However, there is a problem if I reconnect as follows:
While Bluetooth is connected, I click the connect button again on the menu and select the same device. This disconnects the bluetooth (not sure whether this is the right procedure to disconnect). Then, I connect again by selecting the device, and it will be reconnected. After reconnection, a very strange problem appears: instead of sending the data every half a second, it will send the data every quarter a second. If I go through the process again and reconnect, the time interval will become even shorter. It gets to a point that the bluetooth device on the receiving end can't keep up with the data. At this point, the only way out is to kill the app and restart again. Then everything becomes normal, till next time I try to reconnect again.
I have tried different things but nothing appear to fix this. For example, I made sure the thread sending the data is killed when disconnected so no multiple threads are sending the data. I was wondering whether the baud rate changed when reconnected, but then why would the baud rate affect the Thread.sleep(500); statement (which is responsible for controlling the half a second data send). Any help would be greatly appreciated.
Here is the code, the SendClass is created under the MainActivity:
class SendClass implements Runnable {
public void run() {
bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
while (!Thread.currentThread().isInterrupted()) {
if (mChatService==null || mChatService.getState()
!=BluetoothChatService.STATE_CONNECTED) {
continue;
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mChatService.write(bytearr);
}
}//end of run
}//end of runnable
Then under STATE_CONNECTED:
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to,mConnectedDeviceName));
/*
if(sendingThread!=null){
//sendingThread.stop();
sendingThread.interrupt();
if(D) Log.i(TAG, "after sendingThread");
sendingThread = null;
}*/
sendingThread = new Thread(new SendClass());
sendingThread.start();
break;
As you can see, I tried to kill the thread before creating a new one but that didn't make any difference. Any suggestions?
You are creating a thread that never actually stops, even after you create a new thread and assign to the same variable that particular thread wont stop running.
You need to make sure that the thread will stop after it disconnects.
Here is my suggestion
Change your SendClass to:
class SendClass implements Runnable {
private boolean stopped = false;
public void setStopped(boolean s){
this.stopped = s;
}
public void run() {
bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
while (!Thread.currentThread().isInterrupted() && !stopped) {
if (mChatService==null || mChatService.getState() !=BluetoothChatService.STATE_CONNECTED) {
continue;
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mChatService.write(bytearr);
}
}//end of run
}//end of runnable
Then when you start your thread keep the reference to the Runnable so you can call the setStopped(true); like this
SendClass sc = new SendClass();
sendingThread = new Thread(sc);
sendingThread.start();
When you disconnect the bluetooth dont forget to call sc.setStopped(true); so your thread will finish by not going into the while.

Categories

Resources