Bigmac 412
Bigmac 412

Reputation: 33

How to use runOnUiThread for updating a TextView

I have two threads in my main activity from Runner and start them with clicking a button. The only thing thy do is count up. I want to update two TextViews wit the current count from ech thread. When i start my app and click my button, the app crashed.

The code run perfektly in the console.

The class Runner is only used for the counting. I want to Update the two TextViews after each passage in the methode running().

public class Runner extends Activity implements Runnable {

    int count = 0;
    String name;



    public Runner(String name) {
        super();
        this.name = name;
    }

    public void warten() throws InterruptedException {
        int zahl = (int) (Math.random() * 500) + 500;
        Thread.sleep(zahl);
    }

    public void running() throws InterruptedException {
        for(int i = 0; i < 10; i++) {
            warten();
            count++;
            System.out.println(name + " ist bei: " + count);

            if(count == 10) {
                System.out.println(name + " IST FERTIG");
            }

            runOnUiThread(new UiThread(name, count));

        }


    }

    public void run() {
        try {
            running();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

The class UiThread should be the main thread for updating the UI.

public class UiThread extends Activity implements Runnable {

    String name;
    int count;

    TextView textView1;
    TextView textView2;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView1 = findViewById(R.id.textView2);
        textView2 = findViewById(R.id.textView3);

    }


    public UiThread(String name, int count){
        this.name = name;
        this.count = count;
    }


    @Override
    public void run() {
        if(name == "thread1"){
            textView1.setText("thread1 ist bei: " + count);
        }else{
            textView2.setText("thread2 ist bei: " + count);
        }
    }
}

Upvotes: 0

Views: 584

Answers (1)

denniz crypto
denniz crypto

Reputation: 471

i would recommend you checkout this guide on android threading docs.

You can't initialize an activity class, you only add it to the manifest, doing so will lead to a null context. So remove the constructor in your UiThread class.

Also you do not need for your runner class to extend Activity. Pass an instance of Activity inorder to use the runOnUiThread() method.

Here is an example of how the UiTHread class should be.

public class UiThread extends Activity {

public TextView textView1;
public TextView textView2;


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    textView1 = findViewById(R.id.textView2);
    textView2 = findViewById(R.id.textView3);

    startThreads();
}

private void startThreads(){
    // Initialize the runnable class passing this activity context.
    Runner runner = new Runner(this);

    Thread thread1 = new Thread(runner, "thread1");
    Thread thread2 = new Thread(runner, "thread2");

    thread1.start();
    thread2.start();
}
}

the runner class

public class Runner implements Runnable {


private int count = 0;
private UiThread context;

public Runner(UiThread activityContext) {
    this.context = activityContext;
}

public void warten() throws InterruptedException {
    int zahl = (int) (Math.random() * 500) + 500;
    Thread.sleep(zahl);
}



public void running() throws InterruptedException {
    for(int i = 0; i < 10; i++) {
        warten();
        count++;
        System.out.println(Thread.currentThread().getName() + " ist bei: " + count);

        if(count == 10) {
            System.out.println(Thread.currentThread().getName() + " IST FERTIG");
        }

        // update text views from the main thread.
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(Thread.currentThread().getName().equals("thread1")){
                    context.textView1.setText("thread1 ist bei: " + count);
                }else{
                    context.textView2.setText("thread2 ist bei: " + count);
                }
            }
        });
    }


}

public void run() {
    try {
        running();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Hope this helps.

Upvotes: 0

Related Questions