I am trying to build a short memory game and I want a list of words to be shown.
At the start of the activity, the first word, then every second the next word and after the last word is shown the activity changes without user proc. I have tried some things but the closest I've been is just the last word being shown. Any thoughts?
Java file:
package com.example.pc.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Random;
public class Game1Round1 extends Activity {
String[] round1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game1round1);
round1 = getResources().getStringArray(R.array.round1);
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateTextView();
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
Proceed();
}
private void updateTextView() {
int i= 0;
while ( i <13) {
TextView textView = (TextView) findViewById(R.id.randomTextView);
textView.setText(round1[i]);
i = i + 1;
}
}
public void Proceed() {
Intent intent1 = new Intent(this, Game1Start.class);
startActivity(intent1);
}
}
And my strings.xml:
<resources>
<string name="app_name">My Application</string>
<string-array name="round1">
<item>Cinnamon</item>
<item>Apple</item>
<item>Milk</item>
<item>Detergent</item>
<item>Cheese</item>
<item>Shampoo</item>
<item>Butter</item>
<item>Tangerine</item>
<item>Coffee</item>
<item>Marmalade</item>
<item>Cabbage</item>
<item>Meat</item>
<item>Sugar</item>
</string-array>
delete the updateTextView() method and change your Thread like this
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted() && i < 12) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView)findViewById(R.id.randomTextView)).setText(round1[i]);
i++;
}
});
}
Proceed();
} catch (InterruptedException e) {
}
}
};
t.start();
In your run() method after try, catch use finally and put proceed() method in that like below
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateTextView();
}
});
}
} catch (InterruptedException e) {
}
finally{ Proceed(); }
}
};
then you should start the thread
t.start();
Hope this solves your issue
You can use this:
textView.postDelayed(new Runnable() {
#Override
public void run() {
lastCommentText.setText(...);
}
}, 1000);
Related
At the below code i try to take the user's current location each second as x and y axises.At the first time of loop,the code works.But second and so on it doesnt work.What is the missing thing on this code.What should i do.Thanks..
new Thread(new Runnable(){
#Override
public void run() {
while (true) {
runOnUiThread(new Runnable() {
public void run() {
textViewXAltitude.setText(String.valueOf(gps.getLatitude()));
textViewYAltitude.setText(String.valueOf(gps.getLongitude()));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
you should do this by Handler;for example:
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
textViewX.setText(String.valueOf(i++));
textViewY.setText(String.valueOf(j++));
}
}
};
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Timer().schedule(new TimerTask() {
#Override
public void run() {
handler.sendEmptyMessage(0x123);
}
}, 0, 1000);
}
});
I want to make an quiz application in which the questions will be displayed every ten seconds. But when the user answers the question, I need to display the next question. For this I use threads. I have accomplished displaying questions in regular intervals, but when the user answers the question, it wait for the thread to complete. I want to stop the thread and start a fresh one on a button click. My code is given below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int i = 0;
while (i++ < 10) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Display questions here
}
});
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
public void buttonOnClick(View view)
{
//I want to display new question here
}
How can I call the run method inside the thread. Any help is appreciated. Thank you.
You can use t.interrupt() to stop the thread. Here is the code.
Thread t ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generateQuestions()
}
public void generateQuestions()
{
t = new Thread(new Runnable() {
#Override
public void run() {
int i = 0;
try {
while (i++ < 10 & !Thread.currentThread().isInterrupted()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Display questions here
}
});
Thread.sleep(6000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
public void buttonOnClick(View view)
{
//I want to display new question here
t.interrupt();
generateQuestions();
}
In my application I have a button and when it gets clicked I start a new thread and change the text of button. If I press the button again it will start changing its text faster.
I would like to interrupt the thread when the button is pressed in the second time. What's the correct way to do it?
public class TestActivity extends Activity {
Button btn;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
In this case, just keep a reference to your thread and use Thread.interrupt():
private Thread runThread() {
return new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Then:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (myThread != null) myThread.interrupt();
myThread = runThread();
myThread.start();
}
});
Read this post for more info and options:
How to properly stop the Thread in Java?
In my opinion, the best way would be using a variable to control this.
Something like:
while(i++ < 1000 && keepRunning)
I see that as a good solution because it cant cause unexpected behavior, as you are sure the exactly moment your thread would exit.
extra--
As a suggestion, I also would recommend you to set your thread non-Damon (setDaemon(false)) because it makes layout changes
Also it is a good practice to give thread a name (setName()) to make it easy on debugging.
Right now you start a new Thread each time you press the button.
Something like this should work.
public class TestActivity extends Activity {
Button btn;
int i = 0;
Thread countThread = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
countThread = new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread() {
if(countThread != null) {
if(countThread.isAlive()) {
countThread.stop();
} else {
countThread.start();
}
}
}
I only had a text editor so I can't guarantee if this solves your problem.
You can use thread.interrupt() to interrupt the thread.
Try this, Just take another variable j and it will handle your code:-
public class TestActivity extends Activity {
Button btn;
int i = 0,j=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
j=1;
runThread();
}
});
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(j==1){
btn.setText("#" + i);
j=0;
}
else
Thread.interrupted();
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
You can use normal Thread in Android (and call interrupt() for your use case) but frameworks provides other better options by providing helper classes around Threads. You can refer to official documentation page for other options.
HandlerThread is preferred option. You can call quitSafely() or quit() for your use case if you go for HandlerThread
Related post:
Why use HandlerThread in Android
I would like to write a real time counter. I tried to use thread, but android warned me that only activity thread may touch the view. I found a solution with runOnUiThread, but it does not work too
public class CounterInRealTimeExampleActivity extends Activity {
private TextView textView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
textView = new TextView(this);
textView.setTag(new Integer(0));
layout.addView(textView);
setContentView(layout);
runOnUiThread(new Runnable() {
#Override
public void run() {
//while(true)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
increment();
}
}
});
}
public void increment() {
textView.setTag(new Integer((Integer)textView.getTag())+1);
textView.setText(Integer.toString((Integer)textView.getTag()));
}
}
i am pasting code here. may this help you..
class UpdateTimeTask extends TimerTask {
public void run() {
String time = DateUtils.now("hh:mm:ss'T'a");
String[]arrValues = time.split("T");
if(arrValues.length>0) {
String strValue= arrValues[0];
String []arrTimeValues = strValue.split(":");
String strValue1= arrTimeValues[2];
setTimertext(strValue1);
}
}
public void setTimertext(String strValue) {
runOnUiThread(new Runnable() {
public void run() {
FinalTime=timer_time--;
btnTimer.setText(String.valueOf(FinalTime));
}
});
}
}
Thread.sleep(3000);
is definitely a problem. You aren't allowed to block the UI-thread, which is exactly what sleep does. You have to execute the code to update the UI from within runOnUiThread solely.
working one, found solution after Hasmukh tip
package com.android.examples;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
public class CounterInRealTimeExampleActivity extends Activity {
private TextView textView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
textView = new TextView(this);
layout.addView(textView);
setContentView(layout);
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
updateTime();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
private void updateTime() {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(Integer.toString((int) (Calendar.getInstance()
.getTimeInMillis() / 1000) % 60));
}
});
}
}
I am trying to update a textview after 3 seconds, and i want to do that in a loop for which i am using thread .....what should i do in order to start background thread so that exactly after 3 seconds background1 thread starts ... and it should be done in a loop ?
package com.edu.math;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class EduMath extends Activity {
TextView txt;
TextView tv;
TextView num;
String x;
int time = 3000;
float z ;
int random;
int random1;
int random_operator =1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
tv = (TextView)findViewById(R.id.randomNumber);
background.start();
}
// our handler
Handler handler = new Handler() {
public void handleMessage(Message msg) {//display each item in a single line
random = (int)Math.ceil(Math.random()*10);
random1 = (int)Math.ceil(Math.random()*10);
if(random1>random)
{
txt.setText(/*txt.getText()+*/""+random1+" "+>+" "+random+" "+
System.getProperty("line.separator"));
}
else
{
txt.setText(/*txt.getText()+*/""+random+" "+>+" "+random1+
System.getProperty("line.separator"));
}
}
};
Handler handler1 = new Handler() {
#Override
public void handleMessage(Message msg) {//display each item in a single line
txt.setText(/*txt.getText()+*/""+random1+" "+x+" "+random+System.getProperty("line.separator"));
}
};
Thread background1 =new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(time);
// send message to the handler with the current message handler
handler1.sendMessage(handler1.obtainMessage());
background.stop();
Log.d("EduMath-enclosing_method", "thread started");
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
Thread background=new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(time);
// send message to the handler with the current message handler
handler.sendMessage(handler.obtainMessage());
background1.start();
} catch (Exception e) {
Log.v("Error", e.toString());
}
}
}
});
}
You must use AsyncTask for changing any views in layout, but at now I have very little experience with AsyncTask.
Try to use a java.util.Timer ( http://download.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html )
public class HandlerDemo extends Activity {
ProgressBar bar;
Handler handler=new Handler() {
#Override
public void handleMessage(Message msg) {
//add your text
}
};
AtomicBoolean isRunning=new AtomicBoolean(false);
public void onStart() {
super.onStart();
Thread background=new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
handler.sendMessage(handler.obtainMessage());
}
catch (Throwable t) {
// just end the background thread
}
}
});
isRunning.set(true);
background.start();
}
public void onStop() {
super.onStop();
isRunning.set(false);
}
}
Try the solution on this post...seems to be what you looking for http://androidgenuine.com/?p=707