Ben Shabat
Ben Shabat

Reputation: 387

Run on UI thread from another class

I searched for a solution and couldn't find one so I'll ask here:

I'm trying to use setText command in the mainActivity, Until now I've used:

 MainActivity.this.runOnUiThread(new Runnable() {
                 public void run() {
                     textViewPrograss.setText(finalI + "");
                 }
             });

now I'm trying to do the same thing, but from another class so i cant use:MainActivity.this.

I was trying to use code i found on another question with no success,This is the code:

new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
    Log.d("UI thread", "I am the UI thread");
}});

Any suggestions?

Upvotes: 6

Views: 10913

Answers (5)

PmanAce
PmanAce

Reputation: 4303

This is my solution (using MVVM, so no business logic in activity), run this in your class (viewmodel in my case):

runOnUiThread(() -> methodToExecute());

here is the method implementation (I have this in my base viewmodel):

private Handler messageHandler;
protected void runOnUiThread(Runnable action) {
    messageHandler.post(action);
}

Don't forget to init messageHandler:

messageHandler = new Handler(Looper.getMainLooper());

Upvotes: 1

user2733760
user2733760

Reputation: 56

You can use this snippet

textView.post(new Runnable() {
        @Override
        public void run() {
            textView.setText("Text");
        }
});

Upvotes: 4

Massimo Milazzo
Massimo Milazzo

Reputation: 3522

I suggest you tu use a BroadcastReceiver in the MainActivity. Register a new receiver with a specific action and send an Intent with that action from "another class". The MainActivity will receive the notification and can edit the TextView content in a clean way

MainActivity:

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

    mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // update your text view
            String text = intent.getStringExtra("text");
        }
    };
    registerReceiver(mReceiver, new IntentFilter(MY_ACTION));
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mReceiver);
}

Another class:

Intent intent = new Intent(MY_ACTION);
intent.putExtra("text", "Your wonderful text");
// take a context reference (e.g. mContext) if you don't have a getContext() method
getContext().sendBroadcast(intent);

Upvotes: 1

Kelevandos
Kelevandos

Reputation: 7082

This (the second code sample from your question) is the correct way to access UI Thread from random location, although you should always try to have a Context to do this :-)

new Handler(Looper.getMainLooper()).post(
    new Runnable() {
        @Override
        public void run() {
            Log.d("UI thread", "I am the UI thread");
    }});

It does work, and if it does not, check if you have debug logs enabled in your debugger ^^

Upvotes: 5

Jagjit Singh
Jagjit Singh

Reputation: 1969

Try this just pass the context to other class and then use it like this

((Activity)context).runOnUiThread(new Runnable() {
                 public void run() {
                     textViewPrograss.setText(finalI + "");
                 }
             });

Upvotes: 3

Related Questions