So, I am working in android studio and trying to set a pause between two methods. In the first one, a gif is loaded and in the second one a pop-up message appears. I've tried to use Thread.sleep and the TimeUnit as bellow but both of them execute in a way that the time is waited before running everything else. In another words, my code down bellow waits 4 seconds and then runs gameGif() and gameFinish() simultaneously. Here is my piece of code:
gameGif();
{
try
{
TimeUnit.SECONDS.sleep(4);
}
catch(InterruptedException ex)
{}
}
gameFinish();
This is working for me
gameGif();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
gameFinish();
}
}, 4000);
What you are doing is setting the intention to update the UI. The actual UI updates are performed by the Android Looper separate to your code. In fact, by calling wait(), you're actually blocking the rendering thread from doing its update.
Using a Handler is the correct way to do it, as Matus posts. The Handler will organise the scheduling with the Looper and will still allow the Looper to run (i.e. is non-blocking). When the timeout elapses it will call the Runnable
The one thing you need to be careful with this approach, is to call the Handler on the UI loop (i.e. from one of the 'normal' Android methods). If you call it from your own Thread it won't interact with the Looper correctly.
Related
I am trying to understand how UI thread's event queue works. I'm trying to run a code that can be broken into many parts but unfortunately it must run on the UI thread. So, in order to not block the UI thread and receive a ANR I was wondering if I can break that code in many Runnable objects and run them using runOnUiThread from another thread.
My question is, will this block the UI thread? If, for example, I have a piece of code that definitely runs in over 5 seconds and I break this code into, let's say 1000 Runnable objects, and add them to the event queue of the UI thread, will other events get processed by the UI thread between them?
Edit: I think I found a better way to express myself in case the above explanation is confusing.
The 1000 Runnable objects was just an example, in actual code I want to have at most 10.
Basically, I want 10 Runnable objects, each one initialising an Ad network on the UI thread. I want these Runnable objects to run one after another, not in parallel. Also, I want the UI thread to be able to process other events between running these objects, so that I don't get an ANR in case running all 10 run methods will take more than 5 seconds.
NOTE: I don't know why initialising Ad networks must be done on the UI thread, but it must, otherwise the app crashes. It also states in some of the networks' sdks' documentation that initialisation must happen on the UI thread. This is why I need to run them one after another on UI thread and I can't run them in parallel in the background.
Also, the app is actually a OpenGl game, so calls to running the Runnable objects will be made from a GL thread, not the main thread, so they will be added to the event queue, and not executed immediately.
Well, Runnable inside your runOnUiThread is just operation in Main Thread.
Imagine that some simple action like
textView.setText("example");
will block Main Thread for 5 ms. Usually you will not see it.
Now imagine that you have like 1000 same operations for 5 seconds. And every blocks Main Thread for 5 ms. Simple calculating 5ms * 1000 = 5000ms = 5 seconds. So it will block Main Thread permamently. But if you have 10 operations you will block only 50 ms, in other words its just 1% of load that you will not feel.
So possible amount of calls depends on size of View, how hard render is and how fast is device.
P.S. For adepts of AsyncTask - there is no real difference between runOnUiThread and AsyncTask because those 1000 Runnables will execute in Main Thread by the same way.
Even if I do same thing inside onCreate method of Activity that will block UI hard
Yes. Runnable executing on UI thread will block main thread.
Check if below approach is useful for you.
Create a Handler with Looper from Main :requestHandler
Create a Handler with Looper for main thread : responseHandler and override handleMessage method
post a Runnable task on requestHandler
Inside Runnable task, call sendMessage on responseHandler
This sendMessage result invocation of handleMessage in responseHandler.
Get attributes from the Message and process it, update UI
Sample code:
/* Handler */
Handler requestHandler = new Handler(Looper.getMainLooper());
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Adwork task is completed:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
for ( int i=0; i<10; i++) {
// Start Adwork task
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
/* Your business logic goes here */
// Send some result after computation
String text = "" + (++rId);
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
System.out.println(text.toString());
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
}
Useful articles:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
android-looper-handler-handlerthread-i
What you are looking for is an AsyncTask.
These are designed to do some background processing, while the UI thread continues. It will NOT block the UI and will NOT cause ANR.
Within the AsyncTask, is an onPostExecute method, which allows you to post results back to the UI. So it is not completely detached from the UI Thread. And an onProgressUpdate for connection during the background processing
Yes, you will feel animation will stop or start shutter if You run heavy operations in Ui thread. It's also depends of how fast device is.
What I would suggest you is to break your code in two parts. One that can be done in background and second that need Ui thread and execute them in AsyncTask.
Use doInBackgroud method to execute heavy operation and onPostExecute to update UI.
Note: If you break code into 1000 threads and run them in one moment, then probably You will hit device queue limit. (Break them into 10-50 parts. )
I am coding an android game in Eclipse with java. The main goal is to wait for a thread to finish, then to set a boolean to true. The reason is that when a user clicks a button it will only run if the boolean is true. However, when I call a method, it creates a thread and does its thing, then when it is done, it sets the boolean to true. However, it automatically sets the boolean to true while the thread is still running, and so the user can click the button (which messes some things up). Is there a way to wait for a thread to finish without freezing the screen? (thread.join() seems to be freezing it)
Any help is appreciated.
Seems like you don't really need to wait until the thread is done to continue, the way I see it you only need to be notified once it's done, the simplest approach for it would be passing a "callback listener" object to the thread, and execute it when done, this will let you know that you are ready to continue, OR a better approacch would be an AsyncTask which will allow you to do everything in background and when done you can use the onPostExecute method, hope this helps.
This is the way you create and add a callback to be notified when your thread has completed:
//Create your callback listener interface...
public interface MyThreadListener{
public void threadFinished();
}
//This is the method that runs some functionality in a separate thread
public void executeTaskInSeparateThread(final MyThreadListener listener){
new Thread(new Runnable() {
#Override
public void run() {
// DO your long task here...
//Notify when done before leaving run method...
listener.threadFinished();
}
}).start();
}
//Use it like this
//Create the implementation of the listener you want (this is something like what you usually do for buttons or any other android listener)
MyThreadListener listener = new MyThreadListener() {
#Override
public void threadFinished() {
//Do whatever you want when notified...
//NOTE: This method will be called on a separated thread too, you cannot modify views...
}
};
executeTaskInSeparateThread(listener);
Once the thread completed it will execute the listener and will let you know is done...
Regards!
Q: Why not set the button to "disabled" when you start the thread (btn=.setEnabled(false);), then have the thread set the button to "enabled" just before it exits?
And yes, calling "thread.join()" (or ANY blocking call) from your UI thread will indeed "freeze" it :)
PS:
Are you using a Java thread, or an Android "Asynch Task"? Here's an excellent tutorial on the latter:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html
Use an AsyncTask. In onPreExecute() disable your button so the user cannot click it again.
In onPostExecute method enable the button again. Do the time consuming logic in the doInBackground method.
try to create a Task extends AsyncTask, override the doinBackground mothed,Then put "time-consuming operation" in it. When your task done,it'll goto "onPostExecute",just use an Interface call back to the Actiity and enable the Button . When you use the AsyncTask you should know that: The Default AsyncTask has got a "pool",System allow 5 instace of AsyncTask ,if you got more than 5 Task,you should create a no limit pool.
My English is so so bad,lol.
I'm developing an Android network application. I want to have one worker thread that will handle all incoming data over a socket). The thread will be active all the time.
I can start the thread from one of my activities, but how to handle it after the activity is changed?
By handle, I mean how to interact with the thread (passing data from thread to current UI or sending data to the thread from the current UI).
I'm looking at AsyncTask but I'm not sure if it can be used with my situation
I think you want to look at one of two models.
The first is to use a Service which will "own" the socket connection. The second is to spin up a HandlerThread to "own" the connection. Which you choose is based on what the socket is doing.
If the socket connection contains data that you need to receive, typically stuff you'll cache locally, then a Service is more appropriate, because running in a Service means that your work will get done eventually. On the other hand if you are doing something like downloading an image that is only ever displayed in your UI, then using a raw HandlerThread might be the right choice. The reasoning here is that the moment your UI goes away your socket connection might as well be closed. Put another way, the choice is based on how ephemeral the use of the data is.
Now, if you're going to use a Service, please, please, use an IntentService which will handle the grotesque details of shutting down the Service at the appropriate time. It will also put your processing code on the correct Thread. A command sent to a Service by default runs on the main/UI thread of your application. An IntentService marshals the work to a background thread.
If you're going to use a HandlerThread, I would make a class that extends HandlerThread and then use the singleton pattern to handle accessing the same HandlerThread from any Activity.
One important question to ask yourself though is when your Service or HandlerThread shuts down. When is the work done and how is this signaled? Is it just when no more data arrives? When your apps UI goes into the background?
For this requirement I suggest that you create and use JAX-WS or JAX-RS.Here are a lot of examples which fully describe that. In that case you can use AsyncTask easily. Look at this answer, I suppose that this solution can meet your needs.
I would go with this:
Handler mHandler = new Handler();
Thread t = new Thread(new Runnable(
#Override
public void run () {
while (true /* or your breaking condition */) {
//Here you put your socket algorithm
mHandler.post(new Runnable() {
#Override
public void run () {
//Here you put every change you want to do on UI thread
}
}
//This is necessary to reduce process consumption
try {
Thread.sleep(30L);
} catch (Exception e) {
e.printStackTrace();
}
}
}));
t.start();
How to know on which UI
Each handler you create is attached to the class on which it was created.
As you can see here Android | Handler
For example, if you have a class that extends Activity and you create a Handler there, it'll work on that UI thread.
Sometime I feel that using AsyncTask is quite overkill for the task, I am looking for similar function like SwingUtilities.invokeLater in android. Because I just want to execute one line of code, no point to create a new class for that.
Maybe you're looking for:
Activity.runOnUiThread(Runnable action)
Activity.runOnUiThread(Runnable action);
The above method is slightly different than invokeLater of java because it checks if you are already on ui thread then it will run your Runnable immediately.
There is another way to make sure your Runnable gets called later and not immediately even if you are on UI thread. To do that you write following code while you are on the main thread.. if you call this when on backend thread your runnable will be exected on backend thread..
Handler h = new Handler();
h.post(new Runnable() {
#Override
public void run() {
//your code..
}
);
I don't remember exactly what invokeLater() does, but if you want to execute something delayed, you can use postDealayed(). That goes on the UI thread, so not fit for long running tasks, naturally.
I have an app and want to put the main thread to sleep for 1500ms, so I can show a ProgressDialog, but I don't know how to do it. It's possible to stop an app main thread? I can achieve the same goal using another thread right?
Stopping the main thread is usually a bad idea as it would also stop all UI interaction processing.
Try making the progress dialog modal. This will prevent the user from doing anything on your UI until the dialog is gone. I think this will achieve what you want to do and is compatible with how Android works
not a good idea to do this, but if you have to use this
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
//handle
}
Don't stop main UI thread! It will freeze UI. I can imagine that you show progress dialog during some background operation. Once this operation is complete just post something to update UI via handler.
The point of progress dialog is to interact with user while something long is executing. Otherwise you would not even need background operation and progress dialog. You would just do you operation in main UI thread and wait for UI to unfreeze.
What you're asking for should be unnecessary and as Carsten said, is a bad idea. It's a cardinal rule that you both never interrupt the UI thread and also only update elements of the UI on that thread. While a Dialog and any of it's subclasses are shown, nothing in the background will receive any input, so while it's up... though the main thread is running, nothing should be happening besides what is going on in the Dialog.
What you're probably looking to do is use something like an AsyncTask() to show your ProgressDialog, do some work, then dismiss it when that work is done.
To do something like this, you'll want to use "Runnables" along with a "Handler." As others mentioned, you don't want to stop the main UI thread. Since there is only one, you won't be showing ANY updates if you make it sleep or wait. See a small sample below of running code on another thread.
The main thing to take out of this is that sleeping the main thread means stopping any and all visual updates.
// Class Variables
private Handler mHandler;
#Override
public void onCreate(){
// Create a Handler Object
// In Layman's terms, Handlers can run processes off the main
// User interface thread.
mHandler = new Handler();
// Post a "Runnable" after a delay in milliseconds
// On a separate thread, the progressDialog_Runnable
// will call the function "createProgressDialog"
mHandler.postDelayed(progressDialog_Runnable, 250);
}
// Runnables (Process to run on separate thread)
private Runnable progressDialog_Runnable;
{
progressDialog_Runnable = new Runnable(){
#Override
public void run() {
createProgressDialog();
}
};
}
// Method you create to make the progress dialog
private void createProgressDialog(){
//... Run this code on a separate thread via Runnable
}
Sleep 10s on a thread in Kotlin
try {
Thread.sleep(10000)
} catch (e: InterruptedException) {
//handle
}