I try to write a little game using android and have some problems with threading.
The mainloop of the game runs in this own thread and basically just does something like this:
public void run() {
while (true) {
NativeGameLib.gameTick(t);
}
}
Now I want to pass touch inputs to my NativeGameLib. I thought I use the onTouchEvent() of the view in the UI-thread, create a runable inside and let it execute on the main-loop thread.
But I don't really get how to do it. I have seen that there is a Handler and a Looper class and that I can use the handler to post runables to the messageQueue and the Looper.loop() function to process the queue.
As far as I understand it, the loop() function endlessly checks for new messages and therefore blocks the thread.
So, how can I combine it with my thread. I want to do something like this in the thread:
public void run() {
while (true) {
processMessageQueue();
NativeGameLib.gameTick(t);
}
}
Any ideas?
Thanks.
Did you check View.Post API ?
http://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable)
Related
I know Android UI is not really meant for executing functions and waiting for them to finish, however, I think there are use cases were it is required, like networking.
My problem is, I want to run a series of network operations that rely on each other and take a bit more time than the split second it takes to the next execution, so some waiting is in order:
Start hotspot
Get network interfaces and IP
Start socket
Initially I tested that all is working using buttons, then it waited between my button presses. But now I'd like to automatize it. I googled but all I found are solutions with Async task, which is deprecated. I tried with threads and join, but that usually causes weird crashes in the runnable, and it is not very elegant. I wonder if there is another solution?
The best thing you can do with SDK it's use Executors to run your work in background sequentially
val newSingleThreadExecutor = Executors.newSingleThreadExecutor()
newSingleThreadExecutor.execute {
// 1...
}
newSingleThreadExecutor.execute {
// 2...
}
But if you want to touch the UI from background should create handler check if view's not null
val handler = Handler(Looper.myLooper()!!)
newSingleThreadExecutor.execute {
handler.post {
view?.visibility = View.GONE
}
}
How about something like this?
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startHotspot();
getNetworkInterfaceAndIP();
startSocket();
}
}, 300);
Is it fine to do following if we think about efficiency?
new Runnable() {
#Override
public void run() {
try {
final Runnable uitask = new Runnable() {
public void run() {
//sth that modifies UI
}
};
for (...) {
context.runOnUiThread(uitask);
Thread.sleep(...);
}
} catch (Throwable t) {
}
}
}
I'm most concerned about that runOnUi might create new thread each time, which would be very bad? Am I right or it smarter like ThreadPool?
Well, runOnUiThread doesn't create new threads, it is starting your runnable on the existing UI thread.
but instead of your code you could just do
void onCreate(..) {
...
mHandler = new Handler();
}
for (...) {
mHandler.postDelayed(uitask, DELAY * i++);
}
I'm most concerned about that runOnUi might create new thread each
time, which would be very bad?
Well. It depends what you want to achieve. In Android, native threads are not much efficient. There are more effective ways how to do background work (SDK provides them).
If you want to do some periodical work you can use Handler to achieve your goal. Just create only one Runnable and then you can send request for periodical callbacks. Another solution is to use Services which run in background. They're directly designated for long-running tasks and provide very handy way for background processing.
Sometimes you need to inform user with some information about current progress in your tasks so in this case you can simply use mentioned Handler or AsyncTask.
I think your solution is not clean and efficient. If you'll create for example 40 Threads, your work won't be faster or more efficient at all. Your GB will scream and application will take the greater part of CPU and high battery consumption is something you shouldn't allow.
After discovering that Google redesigned the threading model in AsyncTask which now comes with a major bug of blocking code, I've chosen to abandon using the AsyncTask and simply use Threads and Runnables, so please don't post any comments on AsyncTask as that is not my discussion. What I would like to know is whether the following is the correct way to implement a nested Runnable that runs stuff on the UI thread:
private class MyOuterRunnable implements Runnable
{
#Override
public void run()
{
int x = 1;
// Do something on the UI thread.
runOnUiThread(new Runnable()
{
public void run()
{
// Update a listview, etc.
}
});
}
}
For the most part, this seems to work, but I am experiencing crashes in certain modules where I do it this way. Is this the proper way to execute UI stuff from within a nested Runnable or should I be doing it differently? All LogCat tells me is that a fatal error occurred in the nested runnable but doesn't provide any detailed info.
Let's say in various points in my application, I create and fire off a new runnable like so:
new Thread(new Runnable() {
public void run() {
while(true) {
//do lots of stuff
//draw lots of stuff on screen, have a good ol time
//total loop processing time abt 1250-1500ms
//check for conditions to stop the loop, break;
} } }
Now, is there any way to terminate that thread midway through execution other than break; inside my while loop? I'd like to be able to kill it specifically and immediately from the parent thread, like, as in the event that the user just requested to load a different map. It feels clunky to insert an if (stopFlag) break; (set in parent thread) after every 5 or so lines of code.
I peeked at Runnable's and Thread's methods and I just can't see it. Someone know an awesome trick?
You may use AsyncTask and call cancel to cancel the thread.
Instead of while (true) you may check for a condition or a flag that would be changed properly when the Thread/Runnable should be stopped. This seems to be the suggested strategy since Thread.stop() has been deprecated.
You could use AsyncTask as suggested, which probably works best in this case. I believe you can also use the interrupt() method, which is preferred if good if you're not in Android, but still suffers from having to explicitly check if it is interrupted:
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
// do some stuff
if (isInterrupted()) {
break;
}
}
});
t.start();
// Whoa! Need to stop that work!
t.interrupt();
I need to write a helper method which I can use in various places in the app to essentially make it 'sleep' for N milliseconds.It looks like Handler.postAtTime may be one way to do it, but I'd like any code snippets if available.
You did not say why you need your app to "sleep".
Assuming you need to run a task after some time:
Handler h = new Handler();
h.postDelayed(new Runnable() {
public void run() {
// do something here
}
}, 1000); // 1000 ms delay
If you don't mind blocking the thread, an alternative to Thread.sleep() is SystemClock.sleep().
Benefit is that it's a one-liner, as it ignores the
InterruptedException so you don't need to handle it.
More info on http://developer.android.com/reference/android/os/SystemClock.html.
As already stated, you should avoid calling this on the main UI thread as it will cause your app to become unresponsive and potentially show the dreaded dialog we all hate to see (please wait or force close.)
Are you looking for something like this?
try {
//Put the thread to sleep for the desired amount of time (milliseconds)
Thread.currentThread().sleep(1000);
}
catch(InterruptedException ie){
}
This will put the thread you are calling it from to sleep for the amount of time you specify.