Updating UI from a service (using a handler?)
My 1st instinct is that you should instead have the Activity bind to your service and handle the UI update on its side instead of the Service directly modifying the Activity.
See more info here:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
And an example here:
Example: Communication between Activity and Service using Messaging
Why does runOnUiThread() not work inside Service?
So there's no need to do that, unless you're creating a Thread inside
of it
Gabe Sechan's answer is correct.
But if you are using a separate thread then instead of following code:
new MainActivity().runOnUiThread(new Runnable() {
public void run() {
OverviewFragment.refresh(getApplicationContext());
System.out.println("yay");
}
});
Try, this code:
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
OverviewFragment.refresh(getApplicationContext());
System.out.println("yay");
}
});
As per Android docs
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise).
Accessing UI component on Activity from the Service class's Thread in Android
And how can I get access to the Activity components from the run method of Thread class?
You don't. Use Messenger
to send Message
objects from the service to the activity's Handler
. The activity -- and only the activity -- can update its widgets, and that only from the main application thread.
Here is a sample application demonstrating this.
Communication between UI thread and other threads using handler
You can pass anything from the parameters if you don't want to use static concepts. In the below codes, I have implemented two classes. As you asked, I used the common handler in both thread classes. I pass handler h1 as the parameters of Runnable object and start() method there to trigger the run() method of another thread class. The thread which contains run() method is the UI (Main) thread. We must use UI thread to update UI. Worker (Background) threads can't do UI update. The communication between worker with UI is done via handler. So, I define handler h2 in UI thread class. When UI thread class constructor is called from background thread class, I get my h2 values from h1 that come from the constructor. And I use h2 for my the communication. In fact, h2 and h1 belong to the same memory space in the system.
I made below two classes and did thread communication for your reference.
First class
public class MainActivity extends AppCompatActivity {
Handler h1;
Thread t;
EditText editText;
private Bundle bb = new Bundle();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
h1 = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
bb = msg.getData();
String str = bb.getString("udd");
editText.setText(str);
System.out.println(str);
}
};
t = new Thread(new MyRunnable(h1)); //I pass Runnable object in thread so that the code inside the run() method
//of Runnable object gets executed when I start my thread here. But the code executes in new thread
t.start(); //thread started
try {
t.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Second class
public class MyRunnable implements Runnable {
private Handler h2;
public MyRunnable(Handler h) {
this.h2 = h;
}
@Override
public void run() {
//everything inside rum method executes in new thread
for(int i=0;i<10;i++) {
Message m = Message.obtain(); //get null message
Bundle b = new Bundle();
b.putString("udd", "daju");
m.setData(b);
//use the handler to send message
h2.sendMessage(m);
}
}
}
Note: when thread.start() happens, it triggers the run of the Runnable class, it creates a separate thread. So every time, you call start(), there is a new thread with the same priority of callee thread.
Hope, this helped you.
Running code in main thread from another thread
NOTE: This answer has gotten so much attention, that I need to update it. Since the original answer was posted, the comment from @dzeikei has gotten almost as much attention as the original answer. So here are 2 possible solutions:
1. If your background thread has a reference to a Context
object:
Make sure that your background worker threads have access to a Context object (can be the Application context or the Service context). Then just do this in the background worker thread:
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
2. If your background thread does not have (or need) a Context
object
(suggested by @dzeikei):
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
Making changes to Main Activity UI from thread in Service
All you have to do is to create a Handler
on the UI thread:
private Handler serviceHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
someFunctionInTheUIThread();
}
};
And then pass this through to your service. You could have a function in the Service like this:
public void registerHandler(Handler serviceHandler) {
handler = serviceHandler;
}
and then pass the handler through like this:
theService = ((LocalBinder) service).getService();
theService.registerHandler(serviceHandler);
then to send a message back:
Message msg = handler.obtainMessage(IDENTIFIER, "Message or data");
handler.sendMessage(msg);
Related Topics
Android N Requires the Ide to Be Running with Java 1.8 or Later
How to Know When the Recyclerview Has Finished Laying Down the Items
Auto-Scrolling Textview in Android to Bring Text into View
Set Android Ip,Dns,Gateway Setting Programmatically
Android: Why Is There No Maxheight for a View
Difference Between Ontouch and Onclick Android
How to Make the Text Direction from Right to Left
What's Better? Notifydatasetchanged or Notifyitemchanged in Loop
Android Gcm: Same Sender Id for More Application
Android Webview Loading Data Performance Very Slow
Share Image and Text Through Whatsapp or Facebook
Session 'App': Error Launching Activity
Android Vector Drawable App:Srccompat Not Showing Images
How to Get the Current Location in Google Maps Android API V2
Apk Location in New Android Studio
Creating a PDF File in Android Programmatically and Writing in It