MonoDroid - 在StartService中的线程异常

时间:2012-07-12 19:04:49

标签: android .net multithreading mono xamarin.android

我要求此人更深入地了解Android的Mono碗,并在支持我的移动应用程序时做好更充分的准备......

我注意到,当从"主启动器"中启动的工作线程调用StartService时服务的OnStartCommand中的线程id与活动线程id(1)相同的活动,而不是启动它的worker-thread的id(3)。

这是一个更抽象的表示:

myActivity : Activity
{
  OnCreate
  {
    print_thread_id()  // 1

    start(thread_func) 
  }

  thread_func() 
  {
    print_thread_id()  // 3 (not 2!, but anyway ...)

    StartService(myService)
  }
}

myService : Service
{
  OnStartCommand
  {
    print_thread_id()   // 1 also!!!
  }
}

我还注意到,在我的工作线程thread_func中,即使服务继续运行,StartService也会返回。我想,在myService退出之前,对StartService的调用将会阻塞。

为什么myService.OnStartCommand中的线程id与thread_func不一样,是不是thread_func它的父节点是调用StartService的地方?

感谢。

2 个答案:

答案 0 :(得分:1)

我没有看到你描述的行为。新线程中的方法准确地报告其自己的id。这是一个非常简单的类,可以帮助您解决环境中的差异:

namespace ThreadTest
{
    [Activity (Label = "ThreadTest", MainLauncher = true)]
    public class Activity1 : Activity
    {
        int count = 1;

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

            SetContentView (Resource.Layout.Main);

            MyService service = new MyService();
            Console.WriteLine("First Thread id: " + Thread.CurrentThread.ManagedThreadId);
            Thread oThread = new Thread(new ThreadStart(service.StartCommand));
            oThread.Start();
        }
    }

    public class MyService : Android.App.Service
    {
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
        public void StartCommand()
        {
            Console.WriteLine("New Thread id: " + Thread.CurrentThread.ManagedThreadId);
        }
    }
}

输出是:

第一个帖子ID:1

新主题ID:4

答案 1 :(得分:0)

谢谢joates ...我可能对正确的服务使用有误解。这就是我在做的事情:

namespace ThreadTest  
{  
  [Activity (Label = "ThreadTest", MainLauncher = true)]  
  public class myActivity : Activity  
  {
    protected override void OnCreate(Bundle savedInstanceState)
    {
      base.OnCreate(savedInstanceState);
      SetContentView(Resource.Layout.Main);

      Console.WriteLine("Main Thread id: " + Thread.CurrentThread.ManagedThreadId); 

      Thread serviceWorker = new Thread(new ThreadStart(serviceThread));
      serviceWorker.Start();
    }

    private void serviceThread()
    {
      Console.WriteLine("Child Thread id: " + Thread.CurrentThread.ManagedThreadId); 

      StartService(new Intent(this, typeof(myService)));
    }
  }

  public class myService : Service
  {
    public override IBinder OnBind(Intent intent)
    {
      throw new NotImplementedException();
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
      Console.WriteLine("Service Thread id: " + Thread.CurrentThread.ManagedThreadId); 
    }
  }
}

这是错误的,还是只是一种不同的方法?如果使用StartService方法来启动服务,而不是如何在上面启动它,这是正确的方法吗?

按照您的建议方式,将Service对象的方法分配给主活动中的工作线程,然后通过ThreadStart()启动它。我的方法实际上是通过StartService启动服务本身(我在子线程中调用的唯一原因是UI不会被阻塞,而不是b / c)。

我提出的方式似乎是正确的,因为我让adroid / mono管理加载和调用服务(StartService最终将导致覆盖OnStartCommand被调用)。我不确定你的方式是否真的会导致明确地创建一个服务(虽然我会测试这个),我知道我的方法有。

您认为哪种方式更“合适”?