i want to send a Broadcast from a FromTowerThread with the following method:
void postToService(final String string){
Handler handler = new Handler();
handler.post(new Runnable(){
#Override
public void run() {
context.sendBroadcast(new Intent(string));
}
});
}
My context is 'this' (my service):
FromTowerThread ftt = new FromTowerThread(this);
(just for completeness my constructor in FromTowerThread):
public FromTowerThread(Context context){
this.context=context;
}
The Error i get is "Can't create handler inside thread that has not called Looper.prepare()".
I don't know how to fix this error, all threads i found about this topic could not help me to understand this.
Thanks in advance!
Chris
change the statement
Handler handler = new Handler();
to
Handler handler = new Handler(Looper.getMainLooper());
Post can only be done from a Handler in a thread that called Looper.prepare().
I'm assuming here that the thread that calls void postToService(final String string) is some type of background thread. Usually the UI thread does call Looper.prepare() meaning that you would have to create the Handler inside the UI thread.
but just as a general suggestion, I'm pretty sure you can just eliminate all of this and just call the broadcast straight away:
void postToService(final String string){
context.sendBroadcast(new Intent(string));
}
The Error i get is "Can't create handler inside thread that has not called Looper.prepare()".
If you are extending Thread, try extending HandlerThread instead. A HandlerThread has a Looper already. (Or you can call Looper.prepare() and Looper.loop() yourself in a regular Thread.)
Otherwise you can do a few things to use the main Thread's Looper. For instance create the Handler in the main Thread and pass it to your worker Thread or even pass a View from the UI Thread and call view.post(Runnable) to execute that Runnable on the UI Thread.
Related
This topic has been discussed many times so far, but still haven't managed got it working.
My MainActivity has a property called Handler mHandlerUi; which is initialized in its constructor
mHandlerUi = new Handler() {
#Override
public void handleMessage(Message msg){
onMessageArrive(msg);
}
};
Later on in the code, In another class, during construction time i initialize another Handler property
mHandlerToUi = new Handler(Looper.getMainLooper());
So during the thread's life time, the following code snippet is executed X times.
Message msg = mHandlerToUi.obtainMessage();
msg.what = ConstMessages.MSG_NEW_GPS_POINT;
msg.setData(bundleContet);
mHandlerToUi.sendMessage(msg);
Unfortunately the message never arrives the MainActivity's Looper, Both threads uses the same UI's looper,
What am i missing over here?
If I understand you correctly, you have initiated two handlers and you want to pass the message from one to another?
Perhaps you should pass the handler to the second class instead. So in your MainActivity you have
mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message inputMessage) {
onMessageArrive(msg);
}
}
and pass this mHandler to your second class via constructor or setter method.
Each Handler handle its messages. The Looper is used for running a Handler on a specific Thread.
If you create two Handler, there will not communicate. There will only share the same Looper that run on a Thread.
You can find good answers on What is the relationship between Looper, Handler and MessageQueue in Android?
I am using a ScheduledExecutorService to run a Runnable periodically. In the Runnable I have registered a SensorEventListener. I noticed that the SensorEventListener callbacks gets called on the main thread rather than a thread from the thread pool of the ScheduledExecutorService. I want to handle the callbacks for the sensor events off of the main thread. It looks like I am able to pass a Handler object when calling registerListener() of the SensorManager class and the callbacks will be run on the thread that the Handler is from.
Is there a way to get a reference to a Handler of a ScheduledExecutorService?
It's hard. A regular ExecutorService does not have a Looper and you can not have a Handler in such a thread.
A Looper is an infinite loop that dequeues and executes events. So if you schedule that your executor is blocked. You can probably implement your own executor based on the event handling of a Looper but I guess that's not what you want.
To use the sensor from the background you would create a HandlerThread. That's a background thread running a Looper and therefore it can have a Handler.
Small example
private HandlerThread mHandlerThread;
private Handler mBackgroundHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandlerThread = new HandlerThread("SomeNameHere");
mHandlerThread.start();
mBackgroundHandler = new Handler(mHandlerThread.getLooper());
mBackgroundHandler.post(new Runnable() {
#Override
public void run() {
// I can do blocking network here.
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quitSafely();
}
You can try Handler handler = new Handler(Looper.myLooper()); in the background thread (Where your ScheduledExecutorService is running) and then pass the instance to the SensorManager.
Handler always 'handles' thing in the thread it was created, so just create a new one in your ExecutorService. Just use default Handler constructor
While it is useful to run long standing tasks on their own thread running code in the UIThread is necessary in order to update the UI components. Otherwise your application will throw the CalledFromWrongThreadException during execution. How can you run code on the UIThread?
There are a number of ways this can be achieved:
Use runOnUiThread() method call
Use post() method call
Use the Handler framework
Use a Broadcasts and BroadcastReceiver (optionally with LocalBroadcastManager)
Use an AsyncTask's onProgressUpdate() method
Method 1:
runOnUiThread(new Runnable() {
#Override
public void run() {
// do something
}
});
Read more: http://www.intertech.com/Blog/android-non-ui-to-ui-thread-communications-part-1-of-5/#ixzz3hnx3hdS5
Yes you can use handler to communicate between Worker Thread and UI Thread, put below code snippet into worker thread from which you want to update your UI,
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("file", pdfPath);
message.setData(bundle);
handler.sendMessage(message); // pass handler object from activity
put Handler related code into Activity class
Handler handler = new android.os.Handler() {
#Override
public void handleMessage(Message msg) {
String filePath = msg.getData().getString("file"); // You can change this according to your requirement.
}
};
If you aren't familiar with Handler mechanism then first read following link, it will help you
https://developer.android.com/training/multiple-threads/communicate-ui.html
I am trying to understand how looper.loop works, and when to use it in my code.
I have a bound service that has a runnable. Inside I have a handler that is used to hold code that updates the Ui. Here is the code.
private Runnable builder = new Runnable() {
public void run()
{
while(isThreadStarted == true)
{
if (newgps == 1)
{
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
//some code that updates UI
}
}
}
}
}
looper.prepair
}
From what I read looper. prepare has to be called before the handler is made. But I noticed I didn’t do that but this code still works. How is this possible?
I want to fix this but im not sure where to put loper.loop. Because this handler is called many many times. Would it be ok if i put looper.loop right after .prepare? Then .quit when isThreadStarted == false?
The Handler is associated with the UI thread, since you attach it to Looper.getMainLooper(). The UI thread prepares its Looperon application start, so that is nothing the application has to do itself.
By using Looper.getMainLooper(), you get Handler of main thread and you are posting on main thread. Main thread has its looper prepared by system already when it is created.
I have an Android service which spawns a thread.This thread waits for network data and after receiving that data I want to show Ok Cancel Dialogbox.
I was getting exception can't create handle that should have Looper.prepare().I added Looper.prepare() and Looper.loop() then now I am not getting any exception but its waiting infinitely.
Instead of using a sole thread it's better to use an AsyncTask which is also a speacialized thread for Android.
You can wait for data in the AsyncTask's doInBackGround method and when you received data you can call publishProgress() which will invoke onProgressUpdate method of AsyncTask.
At onProgressUpdate you can update the UI without blocking the main thread and also this is the preferred way of doing long time operations in background like network listening etc.
Check AsyncTask for more info and how to use it.
http://developer.android.com/reference/android/os/AsyncTask.html
You can invoke the UI thread(showing alert dialog) in non-UI thread by using handlers as like below code
new Thread(new Runnable()
{ public void run()
{
try {
///do your stuff in
mHandlerShowDialog.post(mUpdateShowDialog);
///do your struff
}
} ).start();
final Handler mHandlerShowDialog= new Handler();
final Runnable mUpdateShowDialog = new Runnable() {
public void run() {
// show your dialog here
}
};