App crashing after strings are displayed in sequence using Threads - java

I want to display some words(Strings) in sequence , each for some time, I am using this code but after all the words are shown, the app crashes, i want it to return to previous page after all words have been shown, please help, thanks in advance.
final TextView textView=(TextView)findViewById(R.id.textid);
Thread t=new Thread(){
#Override
public void run(){
while(!isInterrupted()){
try {
Thread.sleep(1000); //1000ms = 1 sec
runOnUiThread(new Runnable() {
#Override
public void run() {
count++;
textView.setText(words[count]);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};

You are not checking to see if count is within the bounds of words.
You need to change
count++;
textView.setText(words[count]);
To
count++
if (count < words.length){
textView.setText(words[count]);
}else{
// Assuming you are inside an activity called MyActivity
MyActivity.this.finish();
}

Related

Change the textview text color when button is clicked in android

I have a code for a Quiz Game in Android Studio. I need to change the color of text in textview when my answer is correct, but in my code the button color change when the question is the next. I click to the correct answer but the color put in the next question. Can you help me?
respuesta1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(respuesta1.getText() == respuestaCorrecta){ //if the answer is correct
puntos += 3;
puntuacion.setText("Puntuacion: " +puntos);
Toast.makeText(MainActivity.this, acertado, Toast.LENGTH_SHORT).show();
acierto.start(); //this is de sound
respuesta1.setBackgroundColor(Color.parseColor("#76FF03")); //change color to green
try {
sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
} //wait for change to other question
if(numeroPregunta<9){
numeroPregunta+=1;
preguntaMostrar(numeroPregunta); //show the next question
}else if(numeroPregunta == 9){
pantallaImagen.putExtra("puntuacionActual", puntos);
startActivity(pantallaImagen); //go to the final activity
}
what does the acierto.start(); do?
i think you should put respuesta1.setBackgroundColor(Color.parseColor("#76FF03")); before that.
Can you put more code in the question. Assuming respuestaCorrecta is of type String and respuesta1 is a radioButton with choice on it. respuesta1.getText() will give you CharSequence, Can you try
String choiceSelectedByUser = respuesta1.getText().toString();
if(choiceSelectedByUser == respuestaCorrecta){
assuming the respuestaCorrecta matches the correct answer's case (case sensitivity)
Found the Solution after test and Debug .
if(respuesta1.getText().equals(respuestaCorrecta)){
final Handler handler = new Handler();
new Thread(new Runnable() {
public void run() {
handler.post(new Runnable() {
public void run() {
// This Code will execute Directly onClick
puntos += 3;
puntuacion.setText("Puntuacion: " +puntos);
Toast.makeText(MainActivity.this, acertado, Toast.LENGTH_SHORT).show();
acierto.start(); //this is de sound
respuesta1.setBackgroundColor(Color.parseColor("#76FF03"));
}
});
try {
// Sleep for 200 milliseconds.
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
// This code will execute after 800 milliseconds
if(numeroPregunta<9){
numeroPregunta+=1;
preguntaMostrar(numeroPregunta); //show the next question
}else if(numeroPregunta == 9){
pantallaImagen.putExtra("puntuacionActual", puntos);
startActivity(pantallaImagen); //go to the final activity
}
}
}).start();
}
And also use .equals() instead of == to compare Strings

Android Java: Update a TextView every x seconds without user input

I'm making an app in Android Java, using Android Studio.
Every 0.1 seconds I want to update the text within a certain TextView.
I already managed to use a Handler to execute a method every 0.1 seconds (100 ms), but it doesn't automatically update the TextView.
It only updates the TextView to what I want when the user interacts with the app. It only updates it when, for example, the user slides the SeekBar or presses a button. It doesn't update when the user clicks on the screen, and not automatically without input either.
How can I make it such that it will update the value automatically, without user input?
Thanks in advance.
P.S: I'm new to Android and Java, and I'm using threads to get the value, in xml format, from a website.
Should I post any code, and if so, what exactly?
you can try updating the value of text view on the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
//update TextView here
}
});
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
You can update your textview using thread also, like this.
int prStatus = 0;
new Thread(new Runnable() {
public void run() {
while (prStatus < 100) {
prStatus += 1;
handler.post(new Runnable() {
public void run() {
tv.setText(prStatus + "/");
}
});
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(prStatus == 100)
prStatus = 0;
}
}
}).start();

Activity start too long

Hello I have a problem with opening Activity.
I'm calling startActivity() with Intent by clicking Button.
I need to wait 4-5 seconds before Activity shows up on the screen.
I know how to do.
itemimg = new ItemsInPacagesImageView(imglist1, this, nazovtripu, 0);
I have 17 times similar code (with other ImageViews) I have this in Method with name InitItemimg();
I tried put this method on OnStart activity with this thread
#Override
public void onStart() {
super.onStart();
timer = new Thread() { // new thread
public void run() {
Boolean b = true;
try {
sleep(20);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
InitItemimg();;
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
};
timer.start();
}
But is no resolve my problem, please do you have some ideas? Thanks
excuse me, I figured so in this method (ItemsInPacagesImageView(imglist1, this, nazovtripu, 0);) on start id deserialization if is some deserialization in row is "fast" but if it's more in row (now 17) with deserialization program spend more time some seconds.
I resolve this problem with put explicit, class which i deserialization in method.
Now i deserialization once instead 17 times. and I safe more miliscond-seconds.

In run(), how can I call a method without my app crashing (Java/Android)?

I'm trying to make a simple little program that will increment a number once a second. In this case, I'm implementing a thread that should loop once per second and add 1 to "potato" each time it loops. This works fine until it gets back to the display method potatoDisp(). For some reason this causes my app to crash. Removing potatoDisp() from run() fixes the problem, but the display is not updated as "potato" increases.
public int potato = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
potatoDisp();
start();
}
public void potatoDisp() {
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("You currently have " + potato + " potatoes");
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
potatoDisp();
}
}
I'm doing this for an Android app, if that helps. I've tried searching for an answer but I'm pretty lost when it comes to the proper way to work threads.
You need a runnable / handler like this:
private Runnable potatoRun = new Runnable() {
#Override
public void run () {
potatoDisp();
}
};
then change
potatoDisp();
to:
runOnUiThread(potatoRun);
You can't update the views when you're not on the UI thread.
You are probably getting an exception for updating the UI in the background. Since, potatoDisp(); is called from a background Thread but that function updates the UI it will give you problems. You need to call it with runOnUiThread().
#Override
public void run() {
while (true) {
try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
#Override
public void run()
{
potatoDisp();
}
});
}
}
Something like this should work.
The issue is that you are trying to update the UI (calling text.setText(...)) on a thread other than the main UI thread.
While I would suggest using a TimerTask instead of calling Thread.sleep(...), there are two main ways to edit your current code to work as expected.
-- Use a Handler
Define a Handler class that will accept messages and update your UI as needed. For example:
private final String POTATO_COUNT = "num_potatoes";
Handler handler = new Handler() {
public void handleMessage(Message msg) {
int numPotatoes = msg.getData.getInt(POTATO_COUNT);
mText.setText("You currently have " + numPotatoes + " potatoes");
}
}
Then in your code where you want to call your handler to update your text view, whether or not you are on the main UI thread, do the following:
Bundle bundle = new Bundle();
bundle.putInt(POTATO_COUNT, potato);
Message msg = new Message();
msg.setData(bundle);
handler.sendMessage(msg);
-- Call runOnUiThread(...)
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
public void run()
{
potatoDisp();
}
}
}
}
I think you should be using Async Task to update the UI from a thread: http://developer.android.com/reference/android/os/AsyncTask.html

What's the best way to count clicks? and play sound according to corresponding click counts

I have an ImageView named Gun, if I click on it, it'll play Drawable Animation named gunShot.
so I declared an int
int gunCount = 0;
The first time you click Gun, it'll play soundReload and set the gunCount to 1, so it'll never play soundReload anymore.
Then click on it once, it'll play soundA, click on it twice, it'll play soundB, three times, soundC.
So every time I click on it, it'll start a Thread called gunThread, this Thread will check how many clicks and count it, and it'll play the sound according to how much click, after that it'll reset the int gunCount back to 0, and start the count again.
Here is my code:
First I declared my thread
final Thread Slash = new Thread(){
public void run(){
try{
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (gunCount == 3){
gunShot.start();
soundA.start();
gunCount = 1;
} else if (gunCount == 4){
gunShot.start();
soundB.start();
gunCount = 1;
} else if (gunCount == 5){
gunShot.start();
soundC.start();
gunCount = 1;
}
}
}
};
Then this is the onClick
Gun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(gunThread.isAlive()){
gunThread.stop();
}
if(gunShot.isRunning()){
gunShot.stop();
}
if(gunCount == 0){
gunShot.start();
soundReload.start();
gunCount = 1;
}
else if(gunCount >= 1){
sengokuState += 1;
gunShot.start();
gunThread.start();
}
}
});
The point is, if you click on it twice simulatenously it would play soundB
click it three times, it would play soundC
click it once, soundA would play
the first click would be soundReload
I set a thread so it would wait the user input for how many gunCount in the sleep(2000).
Are there any better way to do this? Please tell me, this doesn't seem to work well.
Thanks.
Here is the edit:
I insert this final Thread playSound = new Thread(new Runnable() {
#Override
public void run() {
//play the sound here with respect to clickCount
if(clickCount == 2){
soundA.start();
clickCount = 2;
}
else if (clickCount == 3){
soundB.start();
clickCount = 2;
}
else if (clickCount == 4){
soundC.start();
clickCount = 2;
}
}
});
the clickCount == 3 and clickCount == 4 doesn't work, any clues, anyway thanks.
you should consider something else rather than threads try this code
private void CountDown() {
CountDownTimer timer = new CountDownTimer(3000,1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
}
}.start();
}
Well having a delay at the start seems a good way to do it. If it wasn't, I would not have problems with passing to the next song with my EarPods :)
Edit:
Handler handler = new Handler();
Thread playSound = new Thread(new Runnable() {
#Override
public void run() {
//play the sound here with respect to clickCount
}
});
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
handler.removeCallbacks(playSound);
handler.postDelayed(playSound, 2000);
clickCount++;
}
});

Categories

Resources