ys d
ys d

Reputation: 93

Android - simple Thread loop doesn't work

I want a thread loop that changes String each time. (e.g. d -> dd -> ddd -> dddd...) I expected it to update the view as well as the Thread is excuted , but the screen stops at the first run() excution (which is "dd"). What is wrong? Thanks!

package com.example.name.app;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                thread t1 = new thread();
                t1.start();
            }
        });
    }

    private class thread extends Thread {

        TextView textView = (TextView) findViewById(R.id.tv);

        @Override
        public synchronized void run() {

            String text = "d";
            while (true) {
                try {
                    text += "d";
                    textView.setText(text);
                    sleep(5000);
                } catch (Exception e) {
                    return;
                }
            }
        }
    }

}

Upvotes: 0

Views: 283

Answers (4)

InsaneCat
InsaneCat

Reputation: 2161

MainActivity.java

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        final Button button = (Button) findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                thread t1 = new thread();
                t1.start();
            }
        });
    }

    private class thread extends Thread {

        String text = "d";

        @Override
        public synchronized void run() {

            while (true) {
                try {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(text);
                        }
                    });
                    sleep(5000);
                    text += "d";
                } catch (Exception e) {
                    return;
                }
            }
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="digitdemo.com.myapplication.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Count"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Press"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Output:

enter image description here

Hope this helps you.

Upvotes: 1

Sharath kumar
Sharath kumar

Reputation: 4132

Instead of extending the thread class for simple task of incrementing and updating UI use handler.Handler runs in the same main thread with different execution environment.

create a simple handler and update main thread if you want.

TextView textView = (TextView) findViewById(R.id.tv);
String text = "d";

Runnable runnable=null;
Handler newHandler=null;

private void runTask() {
    newHandler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            try {
                //update UI
                text += "d";
                textView.setText(text);
                newHandler.post(runnable);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    newHandler.post(runnable);
   }
}

and to stop the handler use

newHandler.removeCallbacks(runnable);

Upvotes: 0

Harshad Prajapati
Harshad Prajapati

Reputation: 830

Try this..it will give same output as you want.

public class TestActivity extends AppCompatActivity {
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        textView = (TextView) findViewById(R.id.tv);
        final Button button = findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                thread t1 = new thread();
                t1.start();
            }
        });
    }

    private class thread extends Thread {

        String text = "d";

        @Override
        public synchronized void run() {

            while (true) {
                try {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(text);
                        }
                    });
                    sleep(5000);
                    text += "d";
                } catch (Exception e) {
                    return;
                }
            }
        }
    }

Upvotes: 1

Rahul Kumar
Rahul Kumar

Reputation: 348

All the ui elements are handled on main thread. Hence to update any ui element you must do it from the main thread (UI Thread). you can use runOnUiThread to switch to UI thread:

TextView textView;
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        final Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                thread t1 = new thread();
                t1.start();
            }
        });
    }

 private class thread extends Thread {

        @Override
        public synchronized void run() {

            String text = "d";
            while (true) {
                try {
                    text += "d";
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(text);
                        }
                    });

                    sleep(5000);
                } catch (Exception e) {
                    return;
                }
            }
        }
}

Upvotes: 1

Related Questions