Runnable Interface is parent of Thread Class and run() is method of Runnable Interface 
So normally we should prefer Runnable interface over extending thread class because  we don't want to change behavior of the class and we can also  extend another class .It also help in achieving loose coupling as well as we have a benefit of changing the User Interface from any other class.     
We Can  change Ui in 4 ways
1.By using Handler example
public class MainActivity extends AppCompatActivity {    
private Handler mainHandler=new Handler();
class ExampleRunnable implements Runnable {
        int seconds;
        public ExampleRunnable(int seconds) {
            this.seconds = seconds;
        }
        @Override
        public void run() {
            for (int i = 0; i < seconds; i++) {
 mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                        button.setText("50% process completed");
                        }
                    });
2.By Using runOnUIThread()  we have to attach runOnUIThread with post it can be easily understood with example
class ExampleRunnable implements Runnable {
        int seconds;
 public ExampleRunnable(int seconds) {
        this.seconds = seconds;
    }
    @Override
    public void run() {runOnUIThread.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText(" Runnable");
                    }
                });
            }
3.By using any View we can call by any view here i have called with switch
public class MainActivity extends AppCompatActivity {
 private Switch aSwitch;
@Override
    protected void onCreate(Bundle savedInstanceState) {
 aSwitch=findViewById(R.id.switch1);
class ExampleRunnable implements Runnable {
            int seconds;
     public ExampleRunnable(int seconds) {
            this.seconds = seconds;
        }
        @Override
        public void run() { aSwitch.post(new Runnable() {
                        @Override
                        public void run() {
                            button.setText(" Runnable");
                        }
                    });
                }
4.By making Handler in another Thread  we have to define Looper because by default it attach us to our thread looper
Handler threadHandler=new Handler(Looper.getMainLooper());
threadHandler.post(new Runnable()
{
                            @Override
                            public void run() {
                                button.setText(" Runnable");
                            }
                        });
                    }
This are 4 ways of implementing so I think from it you may now something about runnable thread and runOnUIThread() and Handler is written by other person beautifully.