17

I'm try to lern Monodroid! I try to re-write java code to C# and have some problem: I don't understand how-to use Runnable. That's snipet of code in Java, that I coudn't translate to C#:

public class RunActivity extends Activity implements OnClickListener
{
   ...

   private Handler mHandler;

   @Override
   public void onCreate(Bundle savedInstanceState)
   {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.run);
       ... 
       mHandler = new Handler();
       mHandler.postDelayed(mUpdateGeneration, 1000);
   }

   private Runnable mUpdateGeneration = new Runnable()
   {
       public void run()
       {
          mAdapter.next();
          mLifeGrid.setAdapter(mAdapter);

          mHandler.postDelayed(mUpdateGeneration, 1000);
       }
   }; 
   ...

Can you explain me how I must write this code and use Runnable? This Runnable use for update gridview adapter and load data from adapter to gridview in background. If I tried update adapter in main thread? like this(C# code):

mAdapter.next()
mLifeGrid.Adapter = mAdapter;
Thread.Sleep(1000);

Activity is stuck. If I can't use Runnable, how can I implement updating of adapter and gridview in new thread? If I use C# threading, like this:

...
Thread th = new Thread(new ThreadStart(mUpdatGeneration));
th.Start();
}
public void mUpdateGeneration()
{
    mAdapter.next()
    mLifeGrid.Adapter = mAdapter;
    Thread.Sleep(1000);
}

it generates an error "System.NullReferenceException"

Thanks to all for any help! P.S. Sorry for my English :)

Beyka
  • 1,372
  • 1
  • 10
  • 15
  • 1
    This is C#, so use C# threading classes. – Kirk Woll Feb 20 '13 at 20:15
  • @KirkWoll `Handler` might not be a threading class. It seems to be the class that you can use to post to the main event queue. – millimoose Feb 20 '13 at 20:19
  • @millimoose, right, but who implemented `Handler`? If this is a mono project, one should not be using Java idioms. – Kirk Woll Feb 20 '13 at 20:24
  • 1
    @KirkWoll [Xamarin did,](http://androidapi.xamarin.com/?link=T:Android.OS.Handler) presumably directly mapping to a corresponding (Java-based) Android class. This puts a certain upper bound on how much sense complaining about the lack of a `Handler.PostDelayed(Action)` makes. – millimoose Feb 20 '13 at 20:30
  • @KirkWoll (Apparently, very little sense, since the method is, in fact, available, and even I missed it in the docs.) – millimoose Feb 21 '13 at 21:24

3 Answers3

7

It seems like there's an overload of PostDelayed() that takes an Action parameter, so the straightforward way would be to do something like this:

void UpdateGeneration()
{
    mAdapter.next();
    mLifeGrid.setAdapter(mAdapter);
    mHandler.PostDelayed(UpdateGeneration, 1000);
}

// ...

mHandler.PostDelayed(UpdateGeneration, 1000);

(Disclaimer: I've never actually used MonoDroid, but it should be valid.)

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • @Beyka It's not valid as in it didn't exactly compile, or in that the answer hasn't really helped you forward? (If there's just a minor issue I'd like to fix it in the answer.) – millimoose Feb 20 '13 at 21:37
  • it's not really for a few reasons: Handler.PostDelay has 2 parameters (Action action, long delayMillis). If I put mAdapter.next() and mLifeGrid.Adapter = mAdapter to some Action delegate - I had System.NullReferenceException. If you want - I can upload source code to github and you try to solve the problem. I think - this trouble actual for monodroid developers. – Beyka Feb 21 '13 at 20:07
  • @Beyka Hm, that seems like a different problem though. If there's a `PostDelayed(Action)`, that's your answer to what to use instead of an anonymous inner class. – millimoose Feb 21 '13 at 21:25
  • As I understand - there is no implementation of Runnable on Mono For Android(strong possibility that I wrong!). In Xamarin docs for working with threads using Task(). In my case the Task working well. [Xamarin multitasking](https://github.com/xamarin/mobile-samples/blob/master/MultiThreading/AndroidMultiThreading/Screens/MainScreen.cs) – Beyka Feb 26 '13 at 21:25
5

Here's how you translate the Runnable implementation in c#

private Java.Lang.Runnable mUpdateGeneration = new Java.Lang.Runnable(() =>
{
     mAdapter.next();
     mLifeGrid.setAdapter(mAdapter);
     mHandler.postDelayed(mUpdateGeneration, 1000);
});
Radu Simionescu
  • 4,518
  • 1
  • 35
  • 34
0

Test this code. I hope the matter is resolved

      Task.Delay(10).ContinueWith(t =>
        {
            this.RunOnUiThread(() => adepter.NotifyDataSetChanged());

        }, TaskScheduler.FromCurrentSynchronizationContext());
tirozh
  • 1
  • 1