0

私はこれを求めて、Android用のMonoのボウルについてより深い洞察を得て、モバイルアプリをサポートする際の準備を整えてください...

「メインランチャー」アクティビティで開始されたワーカースレッドからStartServiceを呼び出すと、サービスのOnStartCommandのスレッドIDがアクティビティスレッドID(1)と同じであり、それを開始したワーカースレッドの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が返されることに気付きました。StartServiceの呼び出しは、myServiceが終了するまでブロックされると思いました。

myService.OnStartCommandのスレッドIDがthread_funcのものと同じではないのはなぜですか?thread_funcは、StartServiceの呼び出しが行われる親であるのではありませんか?

ありがとう。

4

2 に答える 2

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

于 2012-07-12T20:34:23.673 に答える
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がブロックされないようにするためであり、必要な場合ではありません)。

私が提示した方法は、adroid / monoにサービスのロードと呼び出しを管理させるという意味で適切なようです(StartServiceにより、最終的にオーバーライドOnStartCommandが呼び出されます)。あなたのやり方で実際にサービスが明示的に作成されるかどうかはわかりませんが(これをテストしますが)、私のアプローチにはあることを知っています。

これを行うためのより「適切な」方法はどれだと思いますか?

于 2012-07-12T21:34:02.480 に答える