App hangs after ending loop in Thread

Asked

Viewed 218 times

0

Hello, I made an app in Android Studio that breaks the phrases in words and stores in an array using split. Then I made a loop of repetition using while so that it displays word for word, but there was a problem, the application would freeze the screen, and after having done the whole loop would update it and only appeared the last word of the vector. To solve this I used a Thread, solved, it updates, but the app hangs when it ends. Can someone help me?

Code:

button.setOnClickListener(
                new View.OnClickListener(){
                    public void onClick(View view){
                        Thread t1 = new Thread(){
                            int wpm;
                            String frase;
                            int numbers;
                            int i;
                            @Override
                            public void run(){
                                numbers = Integer.parseInt(txt2.getText().toString());
                                wpm = 1000/(numbers/60);
                                frase = txt1.getText().toString();
                                final String palavras[] = frase.split(" ");
                                i = 0;
                                while(i++ < palavras.length){
                                    try {
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                label.setText(String.valueOf(palavras[i]));
                                            }
                                        });
                                        Thread.sleep(wpm);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        };
                        t1.start();
                    }
                }
        );

Logcat:

05-02 01:33:16.142 6738-6738/com.exsapps.readfast E/Androidruntime: FATAL EXCEPTION: main Process: com.exsapps.readfast, PID: 6738 java.lang.Arrayindexoutofboundsexception: length=122; index=122 at.exsapps.readfast.Main$1$1$1.run(Main.java:48) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.Activitythread.main(Activitythread.java:7409) at java.lang.reflect.Method.invoke(Native Method) at com.android.Internal.os.Zygoteinit$Methodandargscaller.run(Zygoteinit.java:1230) at com.android.Internal.os.Zygoteinit.main(Zygoteinit.java:1120)

  • 1

    This Sleep of yours, what value is there in wpm? Maybe it’s going a high value and you think the app is crashing

  • Put a Log to see what is the value of this wpm

  • This WPM is for minutes, the person informs as much of words per minute, and I turn there to milliseconds. And every word he shows, he gives an Sleep in milliseconds. The problem is not that, the application now runs normal, only that after it finishes displaying all the vector words slowly the application closes. " Application stopped." on mobile.

  • Oh yeah, it stops working, I thought it just got stuck, goes in the logcat and copies here what the error, there it shows, it is easier to help

  • I added the logcat to the question, att.

2 answers

1


I read Carlos' comment, and tried and went wrong, after that I added the loop control variable to be declared at the beginning of the code and in the loop I used only for(i = 0; i < words.length; i++){} and the problem was solved, the application runs, and after its execution, it does not lock.

Code:

    public class Main extends AppCompatActivity {
    Button button;
    EditText txt1;
    EditText txt2;
    TextView label;
    public int i; // < -- Essa foi a solução
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        label = (TextView)findViewById(R.id.label);
        txt1 = (EditText)findViewById(R.id.txt1);
        txt2 = (EditText)findViewById(R.id.txt2);
        button.setOnClickListener(
                new View.OnClickListener(){
                    public void onClick(View view){
                        Thread t1 = new Thread(){
                            int wpm;
                            String frase;
                            int numbers;
                            @Override
                            public void run(){
                                numbers = Integer.parseInt(txt2.getText().toString());
                                wpm = 1000/(numbers/60);
                                frase = txt1.getText().toString();
                                final String palavras[] = frase.split(" ");
                                for(i = 0; i < palavras.length; i++){
                                    try {
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run(){

  label.setText(String.valueOf(palavras[i]));
                                            }
                                        });
                                        Thread.sleep(wpm);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        };
                        t1.start();
                    }
                }
        );
    }

}
  • Why did you use a new thread instead of using an asynctask, or something that processes in the background ?

  • Sorry, it’s probably just that I started my studies 1 month ago, I’m learning about threads this week, but I’ll research about it! Thanks!

  • Opa without problems colleague ! I am also new in programming, so I asked to know the concept ! rs

1

The problem must be while(i++ < palavras.length) that is, i is being compared and afterward then within the loop the final value of i will end up being palavras.length which is an invalid entry.

I advise using a for as in (very conventional, every programmer will recognize):

for (int i = 0; i < palavras.length; i++) {
    final String palavra = palavras[i];
    ...
        label.setText(palavra);
    ...
}
  • I had already done so, but the following message appeared: "error: local variable i is accessed from Within Inner class; needs to be declared final" and the app did not even compile. I put it on the back burner and the other mistake, too. But seeing your answer, I tried again, and there’s the same mistake, so I thought I’d declare the loop control variable as public up there, and then use the for(i=0;i<words.lenght;i++) run the application, it ran as usual, And in the end it didn’t stop working the way it was. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.