如何在 Mono for android 中使用 Runnable

Posted

技术标签:

【中文标题】如何在 Mono for android 中使用 Runnable【英文标题】:How-to use Runnable in Mono for android 【发布时间】:2013-02-05 23:55:12 【问题描述】:

我正在努力学习 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,如何在新线程中实现适配器和网格视图的更新? 如果我使用 C# 线程,像这样:

...
Thread th = new Thread(new ThreadStart(mUpdatGeneration));
th.Start();

public void mUpdateGeneration()

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

它会生成错误“System.NullReferenceException”

感谢大家的帮助! 附言对不起我的英语:)

【问题讨论】:

这是 C#,所以使用 C# 线程类。 @KirkWoll Handler 可能不是线程类。它似乎是您可以用来发布到主事件队列的类。 @millimoose,对,但是谁实现了Handler?如果这是一个单声道项目,则不应使用 Java 习惯用法。 @KirkWoll Xamarin did, 可能直接映射到相应的(基于 Java 的)android 类。这为抱怨缺少Handler.PostDelayed(Action) 的意义设定了一个上限。 @millimoose,啊,我明白了。好点。 【参考方案1】:

好像有an overload of PostDelayed() that takes an Action parameter,所以直接的方法是做这样的事情:

void UpdateGeneration()

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


// ...

mHandler.PostDelayed(UpdateGeneration, 1000);

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

【讨论】:

@Beyka 它是无效的,因为它没有完全编译,或者答案并没有真正帮助你前进? (如果只是一个小问题,我想在答案中解决它。) 这不是真的有几个原因:Handler.PostDelay 有 2 个参数(Action action,long delayMillis)。如果我将 mAdapter.next() 和 mLifeGrid.Adapter = mAdapter 放入某个 Action 委托 - 我有 System.NullReferenceException。如果你愿意 - 我可以将源代码上传到 github,然后你尝试解决问题。我认为 - 对于 monodroid 开发人员来说,这个问题确实存在。 @Beyka 嗯,这似乎是一个不同的问题。如果有 PostDelayed(Action),这就是你对使用什么而不是匿名内部类的答案。 据我了解 - Mono For Android 上没有 Runnable 的实现(很可能我错了!)。在 Xamarin 文档中使用 Task() 处理线程。就我而言,任务运行良好。 Xamarin multitasking【参考方案2】:

以下是在 c# 中翻译 Runnable 实现的方法

private Java.Lang.Runnable mUpdateGeneration = new Java.Lang.Runnable(() =>

     mAdapter.next();
     mLifeGrid.setAdapter(mAdapter);
     mHandler.postDelayed(mUpdateGeneration, 1000);
);

【讨论】:

【参考方案3】:

测试此代码。希望问题得到解决

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

        , TaskScheduler.FromCurrentSynchronizationContext());

【讨论】:

以上是关于如何在 Mono for android 中使用 Runnable的主要内容,如果未能解决你的问题,请参考以下文章

关于 mono for android的安装问题

MonoTouch、Mono for Android 和 WP7 的认证 WCF 服务

Mono For Android MapsAndLocationDemo

Xamarin mono for android 读取 xml 文件

unity代码加密for Android,mono编译

Mono for android:Base64 字符串到 gridview 中的图像