Currently I'm using the following construction:
while(continue)
{
if(somethingChanged)
{
draw();
}
}
Is this way of waiting efficient, or is there a better way to do this?
--
As requested, more info:
I'm drawing on a SurfaceView, with a Thread locking the Canvas and calling the onDraw(Canvas) method. When the thing I have drawn hasn't changed, I don't need to call the onDraw(Canvas) method, so I keep a boolean somethingChanged.
Also, when I touch the screen, I draw let's say a circle at the point of touch, so when I'm touching the screen, somethingChanged is true.
You can also use a wait() and make the other threads notify() this one when something has changed (if the somethingChanged is changed by other threads).
You probably doing a game, I recommend that article: http://dewitters.koonsolo.com/gameloop.html There are very good possible solutions for your request.
Android has a better mechanism regarding idle loops than the std java approach.
It consists of a Looper and a Handler which do the work for you:
Handler myHandler;
...
public void run() {
Looper.prepare(); //this tells Android that your thread will contain a loop
myHandler = new Handler() {
public void handleMessage(Message msg) {
draw();
}
};
Looper.loop; //starts the loop
}
All you have to do to call the draw method is to send a message to that handler instead of setting the boolean var.
Message mess;
myHandler.sendMessage(mess)
That way you can also send any object in that message to the loop, too and android does the thread synchro and message queue stuff for you. And - most importantly - it is efficient, too.
If nothing changed, this is an endless loop that will very probably use 100% cpu, so I'd say that you should at least add some Thread.sleep() calls to give other threads a chance do to something (e.g. changing the value of somethingChanged)
Usually, in infinite loops, you should have some mechanism to avoid it to take over all time of the cpu. This is done, for example, with a sleep. Even a brief sleep will alleviate the use of the processor.
Assuming that this code is in an thread:
while(continue)
{
if(somethingChanged)
{
draw();
}
Thread.sleep( mySleepTime );
}
Related
I am making an android game which is made up of a game loop that is constantly running as well as use of the android UI stuff. So they need to be in separate threads to work concurrently.
I am planning to put the game loop inside an AsyncTask however it says in the developer.android documentation that
AsyncTasks should ideally be used for short operations (a few seconds at the most.)
My game loop will in theory be operating indefinitely and almost always for more than a few seconds. Is the asynctask the right place to put this then or is there another preferred method to split up a game loop and the UI operations
AsyncTasks are for short operations only, as the documentation has stated. Also, they usually do some work that shouldn't interfere with the UI. Hence, "Async" and "Task".
What you should use instead is a new Thread. This is called Multi-Threading. There are a lot of Game Frameworks out there which will have problems with android's UI. Though you have not stated what UI Operations you are talking about, but if you plan to use the android's widgets(UI), you could call Activity.runOnUiThread() to run a code on the UI Thread, for example, changing a TextView's text.
Here is a snippet on how you would create a never ending loop in a new thread(or something like this, i dont remember if the function is private):
new Thread(new Runnable() {
#Override
private void run() {
while(true) {
//your code goes here
}
}
});
Although AsyncTask allows you to perform background operations and publish results on the UI thread without having to manipulate threads, it should ideally be used for short operations (a few seconds at the most).
To keep things simple, you could use a Handler, or even better, research about the various APIs provided by the java.util.concurrent package.
import android.os.Handler;
// Create the Handler
private Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnable = new Runnable() {
#Override
public void run() {
// Insert simulation processing code here
// Repeat 60 times per second
handler.postDelayed(this, 1000 / 60);
}
};
// Start the Runnable immediately
handler.post(runnable);
Remember that multi-threading is the easy part. Correct synchronization is hard.
I'm implementing a rendering loop for my live wallpaper in Android. All of the examples I found on the Internet contain a rendering loop like this:
public void run() {
while (mRunning) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
doUpdate();
doDraw(c);
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
Do I really need to synchronize on mSurfaceHolder object in a Live Wallpaper?
The question like this has been discussed here earlier, but no exact answer has been given. Also the answer by Jason Nichols here states:
I don't understand why your synchronizing in your rendering loop. This is bad form as it may lock up your rendering thread, causing the app to appear to freeze if it can't acquire the lock immediately for any reason. It also takes time to get acquire the lock.
If you've got your data organized in such a way that you need to get a lock in your rendering thread, you need to refactor your design.
I am really frustrated!
Update
Do I generally need any synchronization in a rendering loop? How much will it affect the rendering loop performance?
You don't need to synchronize on mSurfaceHolder. This code was probably taken from Lunar Lander example from SDK and changed so many times over the web that it lost its context. SurfaceHolder had been chosen as the object that provides the intrinsic lock, but as well, any other object could be used.
Actually this is quite simple. In most of the examples where synchronize is used, it is because there is a chance that doUpdate() and doDraw() methods would be accessed from more than one thread(Main thread and some helper thread).
However, if you can ensure that those methods will only be accessed from same thread, than there is no need to use synchronize at all.
An easy implementation (and best for performance) would be using a Handler like this:
Handler handler = new Handler(Looper.getMainLooper());
This will bind the handler to the main thread, and all the actions will be only on the main thread.
So use synchronize when you truly want to synchronize something.
I'm looking for a design pattern or approach for the following scenario. I wish to kick off two separate background threads for data retrieval from different sources. I then want one method (on the UI thread) to be called once both background threads have completed their work. As the data from the two sources must be combined to be useful, I must wait until both have finished retrieving before manipulating the data. How can I achieve this on the Android platform?
Edit: My first version has been bothering me, and I didn't like the necessary added boolean with it, so here's another version. Call it with this from onPostExecute of each added task.
ArrayList<AsyncTask> tasks;
public void doStuffWhenDone(AsyncTask finishedTask)
{
tasks.remove(finishedTask);
if(tasks.size() > 0)
return;
... do stuff
}
I'll keep the older one up also, since they both work, but I think the above is much cleaner. Now to go tidy up one of my earlier projects.
ArrayList<AsyncTask> tasks;
boolean hasBeenDone = false;
public void doStuffWhenDone()
{
for(int i=0;i<tasks.size();i++)
if(hasBeenDone || (tasks.get(i).getStatus() != AsyncTask.Status.FINISHED))
return;
hasBeenDone = true;
... do stuff
}
It's easily extendable to however many tasks you have, and there's no need for a thread to handle the threads. Just call the method at the end of each task. If it's not the last one done, nothing happens.
Edit: Good point, but I don't think it needs to be atomic. Since both AsyncTasks' onPostExecute methods run on the UI thread, they'll be called one after the other.
Use a CountDownLatch, like this:
CountDownLatch barrier = new CountDownLatch(2); // init with count=2
startWorkerThread1(barrier);
startWorkerThread2(barrier);
barrier.await(); // it will wait here until the count is zero
doStuffWithTheResult();
when a worker thread finishes, call barrier.countDown() from it.
You can use AsyncTask and an int to know if both jobs are finished...
1.
I have main UI thread and it uses library functions.
MainUI {
library.funcA(1);
library.funcB(2,3);
}
I don't want Main-Thread to wait for the end of each call. Also creating new thread for each call is ineffective and not thread-safe so I want them to run on another same thread.
So I created another thread with a single message queue / handler.
MainUI {
handler.post(new Message(FUNC_A,[1]));
handler.post(new Message(FUNC_B,[2,3]));
}
but it seems having overhead that I need to create new Message object every time and decode it again in handleMessage(). Furthermore It looks ugly to handle the various number of arguments packing/unpacking. I thought making all functions as Runnable and post them to handler, but functions have different arguments and I need to make new classes extending Runnable class!
my current plan is to insert synchronized keywords into every function in library so threads run one by one,
but I dislike many threads creating/disappering so making system heavy (also not thread-safe). I want to hear opinions.
2.
if the library is called from many threads (not only Main-thread), what's the best way to convert calls to run on the library's own single thread?
In my opinion, your current approach is feasible option to make thread-safe. However, if you want to go for having Runnable passed to handler, you could consider overloading your Runnable class. Here is pseudo-code
private Class MyRunner extends Runnable{
public MyRunner(){
//This is without any argument
}
public MyRunner(arg1){
//This is with 1 argument
}
public MyRunner(arg1,arg2){
//This is with 2 arguments
}
}
Still, you will have many instances of MyRunner class created.
You can use a Runnable like this:
int x = 1;
int y = 2;
// "a" and "b" are here to show how variable values can be sent to funcB.
// You could skip this and just have "funcB( 1, 2 )", of course.
final int a = x;
final int b = y;
handler.post( new Runnable() {
public void run() { library.funcB( a, b ); }
} );
The handler bit is a bit trickier. It has to run a looping thread to run each Runnable from the queue. Then it has to have a post method to put things on the queue. Some form of blocking queue would be the simplest way to link the two, saving you from having to do your own Object.wait/Object.notify. Synchronizing the post method would be the easiest way to keep multiple threads from tripping over each other.
To update the GUI from other threads, there are basically two main approaches:
Use java.lang.Runnable with any of these methods:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
Handler.post(Runnable)
Use android.os.Message:
Handler.sendMessage(Message) / Handler.handleMessage(Message)
You can also use AsyncTask, but my question is more focused on the use case of updating a very simple component. Let's see how it would be done using both approaches:
Using Runnables:
TextViev tv = ...;
final String data = "hello";
Runnable r = new Runnable() {
#Override
public void run(){
tv.setText(data);
}
};
//Now call Activity.runOnUiThread(r) or handler.post(r), ...
Using messages:
Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello");
handler.sendMessage(m);
//Now on handler implementation:
#Override
public void handleMessage(Message msg) {
if(msg.what == UPDATE_TEXT_VIEW){
String s = (String) msg.obj;
tv.setText(data);
} ... //other IFs?
}
IMHO, Messages are not the way to go because:
Not easy to understand for new non-android programmers (handler hooks to its thread during construction).
Object payload should be Parcellable if the message crosses process boundaries.
Messages are reused (error prone if not properly cleaned up?)
The handler has a dual role (it sends messages, but also handles them)
Message attributes are public, but also offer getter/setter.
On the other hand, Runnables follow the well known command pattern, and are more programmer-friendly and readable.
So what are the advantages of using Messages over Runnables? Are Messages pushed into the background in modern day Android programming? Is there anything you can do with Messages that can't be done with Runnables?
Thanks in advance.
I would say there is little difference between using a Message vs a Runnable. It'll mostly boil down to personal preference. Why? Looking at the source code you'll find that posting a Runnable uses the same exact messaging mechanism. It simply attaches the Runnable to a Message and sends that.
4.4.2 Source Code
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
Ref: Grep Code - Handler
Messages can be reused, so it results in fewer objects created and less GC. You also end up with fewer classes and anonymous types.
One big advantage is that a class sending a Message to a Handler doesn't need to know anything about the implementation of that Message. That can aid in encapsulation depending on where it's used.
Lastly consider the difference in cleanliness between
mHandler.obtainMessage(DO_STUFF, foo).sendToTarget();
vs
final Foo tempFoo = foo;
mHandler.post(new Runnable(){
#Override
public void run(){
doStuff(tempFoo);
}
};
If you have several places where you would have to doStuff(), the former is MUCH more readable and you'll have less code duplication.
Handler interface provides much more functionality than runOnUiThread(), according to docs:
There are two main uses for a Handler:
(1) to schedule messages and runnables to be executed as some point in the future
(2) to enqueue an action to be performed on a different thread than your own.
runOnUiThread does only a subset of (2). ie "enqueue an action to be performed on UI thread"
So IMO unless you need those extra features runOnUiThread is sufficient and preferred way.
I prefer Runnable to Message. I think code using Runnable is much clearer than Message, because the event handling code is very close to the event. Also, You can avoid the overhead of defining constants and switch cases.
And I don't think using Runnable violates encapsulation. You can extract the code in Runnable.run() into another method in the outer class, for example on...Event(), or even wrap it into an EventHandler object. Both ways are much clearer than using Message, especially when you need store references in Message, because using Runnable avoids downcasting msg.obj. And the nameless field msg.obj is also error prone and sometimes inefficient to understand.
And Runnable can also be reused by storing it as a field.