在Mono for Android中如何使用Runnable

17

我正在尝试学习Monodroid! 我试图将Java代码重写为C#,但遇到了一些问题:我不明白如何使用Runnable。 以下是Java的代码片段,我无法将其翻译成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);
       }
   }; 
   ...

您能向我解释一下如何编写这段代码并使用Runnable吗? 使用这个Runnable来更新gridview适配器并在后台从适配器加载数据到gridview中。如果我尝试在主线程中更新适配器呢?像这样(C#代码):

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

活动卡住了。 如果我不能使用Runnable,我该如何在新线程中实现适配器和GridView的更新? 如果我使用C#线程,像这样:

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

它生成了一个错误 "System.NullReferenceException"。

感谢所有人的帮助! 附言:对于我的英语我很抱歉 :)


1
这是C#,所以请使用C#线程类。 - Kirk Woll
@KirkWoll Handler 可能不是一个线程类。它似乎是一个可以用来向主事件队列发送消息的类。 - millimoose
@millimoose,没错,但是谁实现了Handler?如果这是一个单一项目,就不应该使用Java的习惯用法。 - Kirk Woll
1
@KirkWoll,Xamarin做到了这一点,可能是直接映射到相应的(基于Java的)Android类。这就对抱怨缺少Handler.PostDelayed(Action)的意义有了一定的上限。 - millimoose
@KirkWoll(显然,这很没有意义,因为该方法实际上是可用的,即使我在文档中也错过了它。) - millimoose
3个回答

7

似乎有一个接受Action参数的PostDelayed()函数过载, 所以直接的方法是像这样做:

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

// ...

mHandler.PostDelayed(UpdateGeneration, 1000);

(免责声明:我从未使用过MonoDroid,但它应该是有效的。)

@Beyka 这个问题不是因为代码无法编译,还是因为答案没有真正帮助到你?(如果只是小问题,我想在答案中修复它。) - millimoose
它并不是真的因为有几个原因:Handler.PostDelay有2个参数(Action action,long delayMillis)。如果我将mAdapter.next()和mLifeGrid.Adapter = mAdapter放到某个Action委托中 - 我会遇到System.NullReferenceException。如果您愿意 - 我可以上传源代码到github并尝试解决问题。我认为 - 这个问题对于monodroid开发人员来说是实际存在的。 - Beyka
@Beyka 嗯,那似乎是一个不同的问题。如果有 PostDelayed(Action),那么这就是你需要使用而不是匿名内部类的答案。 - millimoose
据我所知 - 在Mono For Android上没有Runnable的实现(很可能我是错的!)。在Xamarin文档中,使用Task()来处理线程。在我的情况下,Task运行良好。Xamarin多任务 - Beyka

5
这是如何在c#中翻译Runnable实现的方法:

以下是示例代码:

private Java.Lang.Runnable mUpdateGeneration = new Java.Lang.Runnable(() =>
{
     mAdapter.next();
     mLifeGrid.setAdapter(mAdapter);
     mHandler.postDelayed(mUpdateGeneration, 1000);
});

0

测试这段代码。我希望问题得到解决。

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

        }, TaskScheduler.FromCurrentSynchronizationContext());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接