Reputation: 93
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
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:
Hope this helps you.
Upvotes: 1
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
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
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