I have a problem. I'm using a FileObserver, which moves new files from the watched directories to another, former specified directory. In my thoughts there should be shown a toast message that says 'File xy has been moved', as long as the observer watches the directory, also if the applications is only in the background. But I didn't get it working.
It always tells me, that there is a RuntimeException, and that it cannot been done without calling Looper.prepare().
05-11 13:21:28.484:
WARN/System.err(3397):
java.lang.RuntimeException: Can't
create handler inside thread that has
not called Looper.prepare()
I tried the way with using an handler too, but I also didn't get it to work.
Has someone else an idea?
Thanks in advance.
Best regards, Tobi
Before your Toast statement add the following :
runOnUiThread(new Runnable() {
public void run()
{
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
});
This will make it run on UI thread.
Hope this helps.
Obviously, your FileObserver runs(or is) another thread. You can not modify the UI from non-UI thread. Pass a Handler to your FileObserver and send messages from it. Read about Handlers.
What are you using for the context of the Toast message? That will have to have a way to display something on the screen.
Put the following code in your class:
// Need handler for callbacks to UI Threads
// For background operations
final Handler mHandler = new Handler();
// Create Runnable for posting results
final Runnable mUpdateResults = new Runnable() {
public void run() {
// Show the toast here.
}
};
and in your fileobserver's thread call place following fragment of code:
mHandler.post(mUpdateResults);
and don't use the getApplicationContext() instead try YourClassPhysicalName.java for the context of the Toast.
Related
I'm developing an android app, i have a separate class that extends Thread class, here i call a service and fetch data, now i need to know when this thread is completed and on completion its shows me a Toast.
Like
"Successful"
Is there any method like onPostExecute() in AsyncTask Thread?
Thanks
Display a toast is different that modify Views component because toast can be displayed from every thread while views need to be accessed only from the main thread.
So, if you need just to display a Thread just call Toast.makeToast(...).show() wherever you are.
Anyway, you can send messages from a backgrund thread to the main thread using the Handler class:
http://developer.android.com/reference/android/os/Handler.html
http://developer.android.com/guide/faq/commontasks.html#threading
i hope you are using thread like this..
.....
new Thread(new Runnable() {
public void run() {
YourMetod(); //you want to execute first
finishedHandler.sendEmptyMessage(0);//when first method is executed completly you need to call this
}
}).start();
....
create a handler in your class
like this
private Handler finishedHandler = new Handler() {
#Override public void handleMessage(Message msg) {
//create your toast here
}
};
try this hope help
I already have idea on how to use a Progress Dialog when background action is being performed. But my question is how do I show a progress Dialog when I am dynamically inflating a huge layout.
Since I can't inflate a view in another Thread, I am using the main UI thread. Due to this my progress dialog is not getting priority and it doesn't show up. My UI hangs for several seconds until it gets loaded fully. I tried several approcahes but none seems to work.
progress.show(context,"","inflating UI...");
setNewContent(R.layout.my_profile,R.id.my_profile_menu_button,R.id.my_profile_all_elements_layout);
populateProfileList(); //Dynamic nested layouts being inflated.
I am basically looking for dynamic layout changes based on user actions. So I dont have any other way other than creating dynamic views. Can anyone suggest me a helpful idea.
I had an similar problem with ui-thread. I wanted to add much views to my layout at runtime, I wanted to show a ProgressDialog to inform the user, that it could take a while. I had tried it with AsyncTask, but the only chance to do this, was to implement my ui-methods into the onPostExecute-Method of AsyncTask. But this just freezes the ProgressDialog, because ProgressDialog even works on ui-thread. I found a solution, maybe not the best, but it works. Before starting ui-action, I show a Toast. Then, I created a Thread with a handler and delayed the execution. After ui-action was done, I showed a new Toast. Delay the thread, gives the Toast enough time to get showed:
Toast.makeText(ActivityContext.this,
R.string.start_message,
Toast.LENGTH_SHORT).show();
final Handler uiHandler = new Handler();
final Thread uiThread = new Thread(new Runnable() {
#Override
public void run() {
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
yourUIAction();
Toast.makeText(
ActivityContext.this,
R.string.finish_message,
Toast.LENGTH_SHORT).show();
}
}, 100);
}
});
uiThread.start();
You need to use a handler to be able to talk to the UI thread
//in some thread
uiHandler.sendEmptyMessage(1);
...
Handler uiHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == 1) {
//do somestuff
}
}
};
Using Async Task is much better idea to me, when you have to do something in background, while progress dialog shows up on screen and then when background task completes, update UI... for reference please follow the link...
http://labs.makemachine.net/2010/05/android-asynctask-example/
hope this helps...:-)
How do I get the message queue of the main thread from another thread? Looper.getMainLooper() gets the main thread's looper but I am unable to find a way to get the MessageQueue for another thread's looper. Moreover, how do I get the handler for the main looper? I am unable to find any way to get it.
#r.v,
I had a similar need. I wanted to know when the MessageQueue is empty and when I post something for it to do and I want to know when it becomes empty with nothing remaining to do. I looked at the MessageQueue.IdleHandler and found that it didn't behave as I wanted to I came up with another solution.
In my case I wanted to use the Looper/Handler mechanism to sequentially execute file downloads. Basically each download I want to execute is wrapped in a Runnable. I only want one at a time to be running, so this pattern works well without having to dig into the nuts and bolts of a more involved threading solution. Additionally, I wanted to know when I first put something into the queue and it begins its work, and wanted to know when it was completely done (queue is empty).
I was able to use the handler's message mechanism to achieve this. The messages are handled in sequence with the Runnables, so you can strategically place messages in the queue to help you know the conditions of the queue. Unlike with Runnables in the Handler's queue, there are some query and removal abilities for messages that ultimately provide the solution.
What I do is each time I add a runnable to the Handler (via Handler.post), I also remove all instances of the custom QUEUE_EMPTY message, then add a fresh QUEUE_EMPTY message. This ensures that I have a QUEUE_EMPTY message at the end of the queue. Once I encounter the QUEUE_EMPTY message in my subclassed Handler, I know that I'm at the end of the queue. Additionally, if I don't find a QUEUE_EMPTY message in the queue when I go to add a runnable, I know that the queue was empty and the thread was idle.
As some will quickly point out, there are some real inefficiencies with this solution. Having to iterate through the queue for these "marker" messages could be a real performance issue if there were a large number of entries in the queue. In my case, I'm dealing with only a handful of file downloads at a time so any performance penalties are negligible. If you have a similar situation, I think this is a pretty reasonable solution. It would have been nice for the Android SDK to provide these basic abilities to the MessageQueue. I agree ideally you wouldn't want to mess with the MessageQueue, but knowing when it is idle/working/empty seem like reasonable things and I'm sure there are numbers of scenarios when there is value knowing these things.
class DownloaderThread extends Thread
{
private static final int QUEUE_EMPTY = 9999;
private MyHandler handler;
#Override
public void run()
{
try
{
Looper.prepare();
handler = new MyHandler();
Looper.loop();
}
catch (Throwable t)
{
Log.e(TAG, "halted due to an error", t);
}
}
public void post(Runnable r)
{
if(!handler.hasMessages(QUEUE_EMPTY))
{
Log.v(TAG, "Download queue was empty. First element being added.");
}
handler.post(r);
handler.removeMessages(QUEUE_EMPTY);
handler.sendEmptyMessage(QUEUE_EMPTY);
}
class MyHandler extends Handler
{
#Override
public void handleMessage(Message msg)
{
if(msg.what == QUEUE_EMPTY)
{
Log.v(TAG, "Download runnable queue is empty!");
}
}
}
};
After you get the main threads looper, you should just be able to call myQueue to get the main threads MessageQueue.
http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29
Use the Handler class to interact with a Looper's message queue.
To interact with the main thread's message queue,
Handler mainHandler = new Handler(Looper.getMainLooper(), new Callback() {
#Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
});
mainHandler.post(...);
mainHandler.sendMessage(...);
mainHandler.removeMessage(...);
Now you can send, remove and receive messages.
I am currently developing an Android app where I need to perform a method inside a thread. I have the following code in order to create the thread and perform the
new Thread(new Runnable() {
#Override
public void run() {
new DownloadSync(getApplicationContext());
}
}).start();
When I try to run this code it displays the error message in the log cat:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.Prepare().
How can I fix this problem?
Use AsyncTask. Your situation is the reason for its existence. Also, read up on Painless Threading (which is mostly using AsyncTask).
The issue with your code is that something is trying to use a Handler internally in your new Thread, but nothing has told the Looper to prepare.
I had an earlier answer that was not very helpful - I've removed it and kept the relevant bit:
Make sure your DownLoadSync object only communicates with the main UI thread via a handler (if you want to avoid using an AsyncTask)
Declare a runnable and a handler as shown:
final Runnable updateMainUIThread = new Runnable() {
public void run() {
Toast.makeText(getBaseContext(), "Communicating with the main thread!!", Toast.LENGTH_LONG).show();
}
};
private final Handler handler = new Handler();`
And use it like this:
handler.post(updateMainUIThread);
Well I've seen a wide variety of failures while trying to get this to work. I have a thread that is started via an Activity. The thread needs to create/display progress dialogs and dismiss them.
When I tried to directly display the ProgressDialog I got an error that my Looper wasn't prepared. I looked up with a Looper was an implemented it. However, I had to call Looper.loop for the progress dialog to show up. After it showed up the application froze on that point never to continue past the Looper.loop call.
I couldn't get it to work so looked for a whole new way using a HandlerThread and a Handler. I create a HandlerThread and start it. I get the looper from the thread and create a Handler with it. My ProgressDialog or Toasts won't show up at all.
Is there an easier way to go about doing this?
U can have an
private Handler stopProgressHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
setProgressBarIndeterminateVisibility(false);
}
};
private Handler startProgressHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
setProgressBarIndeterminateVisibility(true);
}
};
so that when u start the thread start the progressbar and after thread is completed u can stop the progressbar.
public void closeProgressbar(){
//bluetoothconnector.onDestroy();
stopProgressHandler.sendEmptyMessage(0);
}
public void openProgressbar(){
//bluetoothconnector.onDestroy();
startProgressHandler.sendEmptyMessage(0);
}
This will help to call the progressbar to start and stop.. This will be one of the solution..
Not sure about ProgressDialog, but all UI related stuff in Android, as far as I know, required to be updated in UI Thread. There's actually an easy helper class for implementing async task: http://developer.android.com/reference/android/os/AsyncTask.html
Alternatively, you can create a Handler (which would be on UI Thread) and create the dialog using that:
Handler uiHandler;
//Activity onCreate
onCreate(...){
uiHandler = new Handler();
}
// Somewhere in your other thread,
uiHandler.postRunnable(new Runnable(){
#Override
public void run(){
// Create or update dialog
...
}
});
The last answer is wrong....
it should be:
setProgressBarIndeterminateVisibility(Boolean.TRUE | Boolean.FALSE);