When I run the application with eclipse it shows me an error: "can't create handler inside thread that hos not called looper.prepare()" and I do not understanding why.
This is a part of my code
public void execute_web_service() {
progressd = ProgressDialog.show(liste_voyage.this, "", "Chargement...", true,
false);
Thread thread = new Thread(liste_voyage.this);
thread.start();
}
public void run() {
get_liste_arrives();
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
progressd.dismiss();
afficher_liste_arrives();
}
};
You will get this error, with the above code, if the code that is creating an instance of this class is running on a thread other than the main application thread.
Related
when I use exoplayer I get a player is accessed on the wrong thread error. How can I solve this?
Non-fatal Exception: java.lang.IllegalStateException: Player is accessed on the wrong
thread.
Current thread: 'main'
Expected thread: 'ConnectivityThread'
See https://exoplayer.dev/issues/player-accessed-on-wrong-thread
The player is started as a service via my BackgroundAudioService.class.
exoPlayer = new ExoPlayer.Builder(getApplicationContext()
.build();
In the main thread my looper is running, the
which updates the UI via exoplayer.getCurrentPosition().
public final Runnable updatePosition = new Runnable() {
#Override
public void run() {
position = BackgroundAudioService.getCurrentPostion();
}
}
myHandler.postDelayed(updatePosition, myHandlerSleep);
I don't know how to solve this problem (which occurs just sometimes), please help.
Thanks
Alejandro
I solved this by calling the status via a handler in the player's event listener. Starting a runnable from the listener which runs only when player.isPlaying() == true.
player.addListener(new Player.Listener() {
#Override
public void onEvents(Player player, Player.Events events) {
Player.Listener.super.onEvents(player, events);
if (events.contains(Player.EVENT_IS_PLAYING_CHANGED)) {
if (player.isPlaying()) {
positionHandler.postDelayed(getCurrentPositionTask,CURRENT_POSITION_SLEEP);
} else {
positionHandler.removeCallbacks(getCurrentPositionTask);
}
}
}
});
public Runnable getCurrentPositionTask = new Runnable() {
#Override
public void run() {
if (exoPlayer != null) {
currentPostion = exoPlayer.getCurrentPosition();
positionHandler.postDelayed(getCurrentPositionTask,CURRENT_POSITION_SLEEP);
}
}
};
The UI calls the current position the same way in a runnable.
I can't say whether this is the best way. but it's going well.
GGK
I have a handler for a thread in my MainActivity that calls a method named UpdateGUI.
Both the handler/thread declaration and the method are within the MainActivity.
This is the handler Declaration:
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
And UpdateGUI is as follows:
public void UpdateGUI(){
Log.d("Updater", "STARTING UPDATE");
//Code that doesn't matter here}
}
From the logger I can see that UpdateGUI() is not being called from the thread. Can you explain why this is happening and how it can be fixed?
Just to clarify. The thread is running,but for some reason it doesn't make the call to UpdateGUI().
You need to atleast run handler once then only it will continuously called from the handler runnable method.
so call handler.post(runnableCode2); once in your code and that will be repeated
handlerData.postDelayed(runnableCode2, 1*6000);
hope this will resolved your issue.
I cant see you starting the Runnable.
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
// This part is missing
handlerData.postDelayed(runnableCode2, 1000);
I want to make downloader, which download data and then call function in UI thread. I have this in main activity
onCreate(){
...
dataRepository.downloadIfNewOrEmpty(new DownloadResponse() {
#Override
public void SuccessResponse(Response response) {
// do something in UI
}
});
}
My function downloadIfNewOrEmpty looks for now only simple with sleep()
public void downloadIfNewOrEmpty(final DownloadResponse response){
//final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
response.SuccessResponse(ResponseCode.SUCCESS);
/*handler.post(new Runnable() {
#Override
public void run() {
response.SuccessResponse(ResponseCode.SUCCESS);
}
});*/
}catch (Exception e){
// Log...
}
}
}).start();
}
If I run this code, it normally does the job and update my UI. I found this solution with Handler (android.os.Handler) but if I run it without or with Handler (commented version) it works same.
Although without handler function SuccessResponse is run in UI thread?
Thank you
Although without handler function SuccessResponse is run in UI thread?
Yes, because response is instance of DownloadResponse which is passed from UI Thread as parameter to downloadIfNewOrEmpty.
I have a method written in a main thread(UI thraed) in android service. In tht method I created a handler class like below
public void myMethod(){
public Handler _handler = new Handler(){
public void handleMessage(Message msg){
Log.v("LOG_TAG", "value of msg===>"+msg);
}
};
My question is how to call _handler object in another thread so that I can get data to handler class.
Thanks
Try,
public void myMethod(){
Handler _handler = new Handler(Looper.getMainLooper()){
public void handleMessage(Message msg){
// Call your method of UI thread here... it will work.
Toast.makeText(context, "UI test", Toast.LENGHT_SHORT).show();
Log.v("LOG_TAG", "value of msg===>"+msg);
}
};
_handler.sendEmptyMessage(0);
}
and one more alternative:
public void myMethod(){
Handler _handler = new Handler(Looper.getMainLooper());
_handler.post(new Runnable() {
// Call your method of UI thread here... it will work.
Toast.makeText(context, "UI test", Toast.LENGHT_SHORT).show();
});
}
and if you not able to call your ui methods inside myMethod (not in scope) then see:
https://stackoverflow.com/a/14444110/3582473
In the last days I have found myself using this approach for asynchronously performing some long operation (several seconds), and then return some value via a callback that must execute on the caller thread, which is typically but not necessarily the UI thread.
public abstract class DoSomethingCallback
{
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback)
{
// Instantiate a handler for the calling thread
final Handler handler = new Handler();
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(clearBytes);
}
});
}
}).start();
}
This seems to work pretty well and is very simple to use. However, I somehow suspect it might have some problems I'm not aware of. So the question is, what are the potential issues of this approach? What are better alternatives than manually creating and running a thread? I'm seeking for simplicity and robustness.
The only problem is that such approach breaks encapsulation: the second thread not only computes the result, but also dictates what the caller thread should do with it. So I'd better refactor your code as follows:
public abstract class DoSomethingCallback {
final Handler handler = new Handler();
public void post(final Object result) {
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(result);
}
});
}
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback) {
// Instantiate a handler for the calling thread
final DoSomethingCallback handler = new DoSomethingCallback () {
void done(Object result) {
...
}
};
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(result);
});
}
}).start();
}