私は、ドライバ(Android HAL)とサービスをUNIXソケットを介して通信しています。どちらも、ハートビートを使用して接続を維持するスレッドを持っています。 HALはソケットデーモンであり、サービスはソケットクライアントです。Androidサービスのスレッドスケジューリングの問題
ブート時にHALがロードされます。アプリケーションがバインドされるとサービスが読み込まれます。このアプリは何もしません。
私は、Appが見える限り、クライアントとデーモンの両方のスレッドが正常であることを確認しました。しかし、アプリをバックグラウンドにプッシュすると(ホームボタンを押すなどして)、デーモンスレッドによって報告されたクライアントスレッドでタイムアウトが発生するのを観察します(ハートビートが十分速く送信されないため)。
私はいくつかのタイミング測定を行い、アプリケーションが表示されている限り、サービスは正しく動作しますが、アプリケーションが見えないときはサービススレッドが不規則に動作することがわかりました。スケジューラーが頻繁にサービスでスレッドを実行していないかのようです。
現在のところ、Androidシステムには他のアプリはありません。
この動作はネクサス7(2013)とネクサス5X Mを実行すると、Nexus Playerのアプリがサービスを開始した場合のAndroid N
を実行しているのではなく、それへの結合を確認した、悪いスレッドのスケジューリングが持続します。違いは、アプリケーション可視性状態はサービススレッドの実行に影響しません(常に遅いです)。
サービススレッドをより高速に実行する方法はありますか?
主に、スレッドは10msのselect()呼び出しを行い、ループの中でブックを保持します。擬似コードは次のよう:
while(running) {
if not_connected {
connect()
}
if send_heartbeat_timeout_elapsed
send_heartbeat()
}
if recv_heartbeat_timeout_elapsed {
close_connection()
}
if connected {
wait_for_daemon_msg(10 ms)
if msg_received {
process_msg()
}
}
}
編集1:多分言及するのに有用である 、最終的なシステムでは、私はブート時にサービスを「開始」できるようにする必要があり、そして何のアプリがあってはなりません。このシナリオでは、サービススレッドを正しく実行する必要があります。
編集2: サービスを「フォアグラウンドサービス」にすると、このスケジューリングの問題が解消されます。
私は、サービスプロセスの優先度がそれ以外のCPU負荷が低いときでさえ、十分に頻繁に実行できるようにするには不十分であるという事実に困惑しています。理想的には私はこれをする必要はありません。
便利な質問が表示された場合は、すぐに質問を残しておいてください。
ユーザが少なくとも1回起動したアプリケーションに属していない限り、起動時にサービスを開始することはできません。 [この回答](http://stackoverflow.com/a/30112243/1953590)を参照してください。 –
@ケビン:あなたがプレイストアや他の場所から "インストール"するものに当てはまります。これらはシステムサービス/アプリになります。ところで、これらをシステムサービスとしてインストールしても、この問題は解決しません。 – GPS