Timer / threads / reliability

by Neilz » Fri, 05 Mar 2010 00:12:02 GMT


Sponsored Links
 Hi all. I have an activity that uses a Timer (java.util.Timer) to
control the display. I set it off to repeat its run() method every
second or so. When it runs, it updates some View elements.

As Timer runs in its own thread, I assumed this would be reliable. But
I notice that sometimes there is a stutter, or delay, in the views
updating. It's like they occasionally get stacked up, and all happen
together. Studying the output from logcat, I notice that this happens
when the device is doing something else - some system functions, or
sometimes a garbage collection.

How can I avoid this? I'm not aware I can run the main activity in a
thread of its own, can I? If the timer has its own thread, why is it
affected?

Any help appreciated!

--



Timer / threads / reliability

by Mark Murphy » Fri, 05 Mar 2010 00:20:49 GMT


 


You can't.


Because the UI is drawn on the main application thread.

Whenever you make a change to the UI -- such as calling setText() on a
TextView -- think of it as putting a message on a message queue that is
processed in a message loop by the main application thread.

All your Timer is doing is triggering some messages to go into that
queue on a periodic basis. How quickly those messages will be popped off
the queue and processed depends on what else is in the queue, how much
time those other things in the queue take (including time in your
activity and listener callback methods), what else is being done in
threads in your application, and what else is being done in other
processes on the device.

You can simplify your current implementation by dumping the Timer and
using postDelayed() to trigger your updates, for what that's worth.

-- 
Mark Murphy (a Commons Guy)
 http://commonsware.com  |  http://twitter.com/commonsguy 

Android App Developer Training:  http://commonsware.com/training 

--


Sponsored Links


Timer / threads / reliability

by Neilz » Fri, 05 Mar 2010 01:46:29 GMT


 Thanks Mark, that makes sense. So basically, I should be implementing
a View with its own draw() method, run in a thread, as in the various
game examples.

I presume from your comment below that using postDelayed() isn't
really going to solve my problem.




--



Timer / threads / reliability

by Mark Murphy » Fri, 05 Mar 2010 01:55:40 GMT


 


No, it'd just negate the need for a separate Timer.

-- 
Mark Murphy (a Commons Guy)
 http://commonsware.com  |  http://twitter.com/commonsguy 

Android App Developer Training:  http://commonsware.com/training 

--



Timer / threads / reliability

by Neilz » Sat, 27 Mar 2010 17:24:53 GMT


 Ok, reviving an older thread.

Is there a way, to have View elements (TextView, Button, whatever)
that are not run on the main UI thread?

What about if I set up a game thread, with its own View (like in the
LunarLander sample, for instance) and then create View elements on the
fly and attach them to the main View? Are these still going to be run
in the main UI thread, or in the game thread?

Thanks.






--



Timer / threads / reliability

by Mark Murphy » Sat, 27 Mar 2010 19:00:32 GMT


 


No.


Neither. Your application will crash.

You cannot modify the widget-based UI from a background thread.

Now, I cannot speak for 2D (Canvas) or 3D (OpenGL) apps and what their
limitations are vis a vis threads. I am only talking about using Views.

-- 
Mark Murphy (a Commons Guy)
 http://commonsware.com  |  http://twitter.com/commonsguy 

_Android Programming Tutorials_ Version 2.0 Available!

--



Timer / threads / reliability

by Kevin Duffey » Sun, 28 Mar 2010 02:55:36 GMT


 The stutter, from what I've picked up on other threads, is as Mark said, due
to various other tasks, apps, and more likely garbage collection kicking in
randomly. One thing that seems to be a common thread for most "real-time"
like UI updating games is to do some sort of time based setup. I forget the
details, but basically on each iteration, you figure out the current time,
subtract the last "time" that was stored, that tells you how much elapsed
time has passed. You use this value to adjust all your UI elements so that
rather than seeing a hiccup with the UI, they UI elements themselves "speed
up" at various times. Or..maybe speed up isn't the right word. But lets say
you have a UI element moving from left to right, 1 pixel per second. A GC
hits and causes a 3 second delay. Your UI element hasn't moved for 3
seconds. In the time based method, you would instead move the UI element 3
pixels so that it would be where it should be. The hiccup would still be
noticeable.. but at least your UI elements will be where they should be,
rather than lagging behind where they should be causing more problems.

There are some threads, and Robert Green and some others have info on here
on how to do it. I've yet to really figure out how to apply the difference
between two frames time stamps and apply it to the world-coordinate system
of a View, for example to make sure a UI element moves to the right
position.

If you are making a sort of game, one of the other important things to do is
do NO creation of objects in the loop. Do all pre-allocation of elements,
objects etc before your loop starts.. or between levels, etc. That makes
game levels generally small in size based on the very limited 16MB ram (or
is it 24MB) you can use for game + images + code... but at least if you can
avoid any sort of object allocation/deallocation during the loop, you can
put off the GC process longer. At least for your game. There was a thread
that was pretty deep on the issue of background services running that could
also trigger a GC and cause your game to hiccup.. and the general solution
to come of that was Google needs to make some sort of "real-time" game mode
so that games that we see on iPhone will be possible on Android. Right now
there seems to be no way to guarantee smooth real-time-ish games on Android.
Some do a very good job tho.







>



Timer / threads / reliability

by Dianne Hackborn » Sun, 28 Mar 2010 16:50:56 GMT


 





Windows can run in their own threads, all views inside of a particular
window must run in the same thread.  The window associated with an Activity
is created in the main thread of its process, so that is where its UI runs.
 You can run windows in other threads if you use Looper to prepare and run a
message loop in that thread, and then instantiate and display the window
there.

SurfaceView also is often used to do UI from a separate thread, by letting
the other thread have the Surface to draw into it (either via the Canvas or
OpenGL APIs).  This also allows you to draw without going through updates,
though doesn't allow you to use a regular view hierarchy in the surface.

-- 
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails.  All such
questions should be posted on public forums, where I and others can see and
answer them.

--



Other Threads

1. Service works on 1.1, not on 1.5

Our remote service is working great on 1.1. It is a pretty rich API too.

BUT, running the same code on cupcake, it hangs after the service 
returns the concrete interface stub it has new'd in onBind(). 
(onConnect() in the client's ServiceConnection is never executed.)

Any thoughts?

Thanks

-- Ward

--~--~---------~--~----~------------~-------~--~----~

2. JNI Running

Ok I have been trying and trying to get a simple JNI program running.

This is my source:
Run.java:

package corey.nativetest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class Run extends Activity {

    private native int print();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        ((TextView)findViewById(R.id.text)).setText(print());
    }
    static {
        try {
            Log.i("JNI", "Trying to load libRun.so");
            System.loadLibrary("/data/lib/libRun.so");
        }
        catch (UnsatisfiedLinkError ule) {
            Log.e("JNI", "WARNING: Could not load libRun.so");
        }
    }
}

Run.c:
#include <jni.h>
#include <stdio.h>
#include "Run.h"


JNIEXPORT jint JNICALL Java_Run_print(JNIEnv * x, jobject y)
{
    return (jint)42;
}

static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
    {"print", "()I", (void*)Java_Run_print}
};


jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    static const char* const kClassName = "corey/nativetest/Run";
    JNIEnv* env;
    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
        return -1;

    /* get class with (*env)->FindClass */
    /* register methods with (*env)->RegisterNatives */

    jclass clazz;

    /* look up the class */
    clazz = (*env)->FindClass(env, kClassName);
    if (clazz == NULL) {
        return -1;
    }

    (*env)->RegisterNatives(env, clazz, sMethods, 1);

    return JNI_VERSION_1_4;
}

int main(int argc, char **argv) {
    return 0;
}

and my .h is really just the "javah -jni" prebuilt one.

I compiled it using the instructions here:
 http://www.***.com/ 
 http://www.***.com/ 

adb push libRun.so /data/lib/


Nothing works, I get

I/jdwp    (  942): received file descriptor 20 from ADB
I/dalvikvm(  942): De{*filter*} thread not active, ignoring DDM send
(t=0x54455354 l
=8)
W/SurfaceFlinger(  582): executeScheduledBroadcasts() skipped, contention on
the
 client. We'll try again later...
D/dalvikvm(  553): GC freed 227 objects / 8600 bytes in 224ms
D/dalvikvm(  553): GC freed 7 objects / 272 bytes in 163ms
D/dalvikvm(  553): GC freed 2 objects / 56 bytes in 130ms
I/JNI     (  942): Trying to load libRun.so
E/JNI     (  942): WARNING: Could not load libRun.so
D/dalvikvm(  942): +++ not scanning '/system/lib/libwebcore.so' for 'print'
(wrong CL)
D/dalvikvm(  942): +++ not scanning '/system/lib/libmedia_jni.so' for
'print' (wrong CL)
W/dalvikvm(  942): No implementation found for native
Lcorey/nativetest/Run;.print ()I
D/AndroidRuntime(  942): Shutting down VM
W/dalvikvm(  942): threadid=3: thread exiting with uncaught exception
(group=0x4000fe70)
E/AndroidRuntime(  942): Uncaught handler: thread main exiting due to
uncaught exception
E/AndroidRuntime(  942): java.lang.UnsatisfiedLinkError: print
E/AndroidRuntime(  942):        at corey.nativetest.Run.print(Native Method)
E/AndroidRuntime(  942):        at corey.nativetest.Run.onStart(Run.java:23)
E/AndroidRuntime(  942):        at
android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1205)
E/AndroidRuntime(  942):        at
android.app.Activity.performStart(Activity.java:3490)
E/AndroidRuntime(  942):        at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2240)
E/AndroidRuntime(  942):        at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
E/AndroidRuntime(  942):        at
android.app.ActivityThread.access$1800(ActivityThread.java:112)
E/AndroidRuntime(  942):        at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
E/AndroidRuntime(  942):        at
android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  942):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  942):        at
android.app.ActivityThread.main(ActivityThread.java:3948)
E/AndroidRuntime(  942):        at
java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  942):        at
java.lang.reflect.Method.invoke(Method.java:521)


Obviously my lib isn't loading, but I don't know why. Any ideas?

Thanks
-Corey Ling

--~--~---------~--~----~------------~-------~--~----~
unsubscribe: android-porting+unsubscr...@googlegroups.com
website:  http://www.***.com/ 
-~----------~----~----~----~------~----~------~--~---

3. How to know it's week when input random date?

4. Buttons/ImageViews overlaid on a GLSurfaceView

5. Android Silicon Valley MeetUp June 16th 鈥?Hosted by Motodev

6. Android Silicon Valley MeetUp J une 16th 鈥?Hosted by Motodev

7. How selective are the Android Marketplace "police" in allowing our apps to be published?