[Mono-bugs] [Bug 634711] Updating the UI from a thread not working

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Sat Aug 28 23:48:37 EDT 2010


https://bugzilla.novell.com/show_bug.cgi?id=634711

https://bugzilla.novell.com/show_bug.cgi?id=634711#c1


Neal Sanche <thorinside at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |thorinside at gmail.com

--- Comment #1 from Neal Sanche <thorinside at gmail.com> 2010-08-29 03:48:34 UTC ---
I have also been trying to do this, to no avail. My code is as follows:


using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Java.Lang;
using Thread = System.Threading.Thread;

namespace TesterApp3
{
    public class TesterApp3Activity : Activity
    {
        int count = 1;

        public TesterApp3Activity(IntPtr handle)
            : base(handle)
        {
        }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            var handler = new Handler();

            // Set our view from the "main" layout resource
            SetContentView(R.layout.main);

            // Get our button from the layout resource,
            // and attach an event to it
            var button = FindViewById<Button>(R.id.myButton);

            button.Click += delegate
                                {
                                    Thread t = new Thread(() =>
handler.Post(new TextUpdater(button, string.Format("{0} clicks!", count++))));
                                    t.Start();
                                };
        }
    }

    public class TextUpdater : IRunnable
    {
        private readonly TextView m_button;
        private readonly string m_text;

        public TextUpdater(TextView button, string text)
        {
            m_button = button;
            m_text = text;
        }

        public IntPtr Handle { get; set; }

        public void Run()
        {
            m_button.Text = m_text;
        }
    }
}

When run, the 'adb logcat' output is as follows:

W/KeyCharacterMap(   98): No keyboard for id 0
W/KeyCharacterMap(   98): Using default keymap:
/system/usr/keychars/qwerty.kcm.
bin
I/ActivityManager(   52): Starting activity: Intent {
act=android.intent.action.
MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000
cmp=TesterApp3.Tester
App3/testerApp3.TesterApp3Activity }
I/ActivityManager(   52): Start proc TesterApp3.TesterApp3 for activity
TesterAp
p3.TesterApp3/testerApp3.TesterApp3Activity: pid=328 uid=10029 gids={3003}
I/ARMAssembler(   52): generated scanline__00000077:03010104_00000004_00000000
[
 22 ipp] (41 ins) at [0x366d80:0x366e24] in 3678978 ns
I/ActivityManager(   52): Displayed activity
TesterApp3.TesterApp3/testerApp3.Te
sterApp3Activity: 906 ms (total 906 ms)
D/dalvikvm(  328): Trying to load lib
/data/data/TesterApp3.TesterApp3/lib/libmo
nodroid.so 0x43d03268
D/dalvikvm(  328): Added shared lib
/data/data/TesterApp3.TesterApp3/lib/libmono
droid.so 0x43d03268
D/dalvikvm(   98): GC freed 2036 objects / 116264 bytes in 1254ms
D/dalvikvm(  328): +++ not scanning '/system/lib/libwebcore.so' for 'init'
(wron
g CL)
D/dalvikvm(  328): +++ not scanning '/system/lib/libmedia_jni.so' for 'init'
(wr
ong CL)
D/dalvikvm(  328): +++ not scanning '/system/lib/libexif.so' for 'init' (wrong
C
L)
D/dalvikvm(  328): +++ not scanning '/system/lib/libwebcore.so' for 'register'
(
wrong CL)
D/dalvikvm(  328): +++ not scanning '/system/lib/libmedia_jni.so' for
'register'
 (wrong CL)
D/dalvikvm(  328): +++ not scanning '/system/lib/libexif.so' for 'register'
(wro
ng CL)
E/mono    (  328):
E/mono    (  328): Unhandled Exception: System.TypeInitializationException: An
e
xception was thrown by the type initializer for Java.Lang.IRunnableAdapter --->
Java.Lang.NoClassDefFoundError: Exception of type
'Java.Lang.NoClassDefFoundErro
r' was thrown.
E/mono    (  328):   at Android.Runtime.JNIEnv.FindClass (System.String
classnam
e) [0x00000] in <filename unknown>:0
E/mono    (  328):   at Java.Lang.IRunnableAdapter..cctor () [0x00000] in
<filen
ame unknown>:0
E/mono    (  328):   --- End of inner exception stack trace ---
E/mono    (  328):   at Android.OS.Handler.Post (IRunnable r) [0x00000] in
<file
name unknown>:0
E/mono    (  328):   at
TesterApp3.TesterApp3Activity+<>c__DisplayClass2.<OnCrea
te>b__1 () [0x00000] in <filename unknown>:0
D/Zygote  (   30): Process 328 exited cleanly (1)
I/WindowManager(   52): WIN DEATH: Window{43d530f8
TesterApp3.TesterApp3/testerA
pp3.TesterApp3Activity paused=false}
I/ActivityManager(   52): Process TesterApp3.TesterApp3 (pid 328) has died.
I/UsageStats(   52): Unexpected resume of com.android.launcher while already
res
umed in TesterApp3.TesterApp3
W/InputManagerService(   52): Got RemoteException sending setActive(false)
notif
ication to pid 328 uid 10029
D/dalvikvm(  255): GC freed 2930 objects / 198624 bytes in 68ms

In my opinion, this pattern doesn't translate well from Java to C#. We should
be using delegates wherever possible here. I would love to be able to write
code like the following:

  handler.Post(() => { button.Text = "New Text"; });

IRunnable implementations all over the place are really clumsy, in my opinion.

Hope this helps.

-Neal

-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list