2012-01-18 7 views
9

私は別のスレッドで音楽をストリーミングしています。私がアプリを残すと(onPause()onStop()など)、音楽は引き続き再生されますが、最終的には他のアプリを開いてそれらを切り替えてホーム画面に戻った後、私のアプリは殺されます。クラッシュはありません。logcatのWIN DEATHprocess com.myapp.android has diedです。明らかに、リソースを回収するために、システムによってアプリケーションが破壊されることは正当です。別のスレッドのMediaPlayerとstartForeground()経由のサービスで実行中

私の質問は:メイン(UI)スレッドからのスレッドで実行中のものは、システムに関する限り優先度が低くなっているということですか?メディアプレーヤーをServiceで実行しても、startForeground()を使用してフォアグラウンドでサービスを実行する場合よりも、それはより多く殺される可能性がありますか?

ご意見やご要望をいただければ幸いです。

EDIT

はまた、サービス上のドキュメントの一部は、私を混乱させる。適切な部分では、それは述べて:

注意:サービスは独自のスレッドを作成しません。そのホストプロセス- サービスのメインスレッドで実行され、特に指定しない限り( 別のプロセスで実行されません。 )。これは、 サービスがCPU集約的な作業を行うか、または 操作(MP3再生やネットワーキングなど)をブロックする場合、その作業のためにサービス内に 新しいスレッドを作成する必要があることを意味します。

私は常にメインスレッドのサービスでMP3再生を実行しましたが、UIは応答したままでした。私が上の引用で推奨されているように別のスレッドに入れなければならないのであれば、私が始めた場所、つまりメディアの再生がメインスレッドから出て、再生の可能性が増す他のアプリが開かれたときなどに殺されますか?

答えて

2

ご質問のほとんどはAndroid documentation on Servicesで回答されていると思います。

リンクから:

フォアグラウンドサービスは、ユーザーがメモリ上の低殺傷するシステム のための候補者の積極的な意識であり、したがってない 何かであると考えられていたサービスです。フォアグラウンドサービスは、進行中の という見出しの下に表示されるステータスバーの通知を で提供する必要があります。つまり、 サービスが停止またはフォアグラウンドから削除されない限り、通知を破棄できません。

あなたの質問に答えるためにThreadを始めActivityが一時停止/停止されている場合は、はい、Activityの分離除去Threadを実行すると、フォアグラウンドで実行されているServiceよりも低い優先順位を持っているとしています。

私はServiceでこれを行うことを個人的にお勧めします。これはまさにServiceクラスのために作成されたものです。

編集:

興味深いが、あなたが提案私が読んだものに反しているようだ(Serviceにスレッドを使用しない場合、すべてが応答性です)。それにかかわらず、おそらくバックグラウンドスレッドで開始する必要があります。

スレッド(あなたが作成するスレッド)は、プロセスが終了しない限り死ぬことはなく、実行時にリソースが必要と判断されたときに発生します。 Activityはフォアグラウンドにいないときに殺すことができるので、Threadも破壊することができます。フォアグラウンドとしてServiceがマークされている場合は、破壊される可能性は低いため、同じ問題は発生しません。

+0

ありがとうございます!私の編集に対処できますか? – LuxuryMode

+1

私は自分のメディアプレイヤーをサービス内とそれ以外の場所の両方に配置しています。 Androidは、より多くのリソースが必要な場合、どこに位置していてもメディアプレイヤーを殺すだろう。また、フォアグラウンド優先度を持つサービスでは別のスレッドよりも殺される可能性は低くなりません。それが殺されることのない唯一の場所は、現在、前景にある活動にあります。 – AndroidDev

-1

スレッドからMediaPlayerを実行する必要はありません。 MediaPlayer.prepareではなくMediaPlayer.prepareAsyncを使用している限り、MediaPlayerには問題を引き起こすほど長くブロックされるメソッドはありません。サービスのフォアグラウンドスレッドで実行します。

プロセスが強制終了された場合、スレッドはプロセスを終了します。サービスをホストするプロセスは、Service.startForegroundメソッドを呼び出すと(ステータスバーにstartForegroundによって要求される必須の通知を表示する)、アクティビティよりも寿命が長くなります。アクティビティが一時停止すると、プロセス全体がリサイクルの主要候補になります(このプロセスにはフォアグラウンドサービスもありません)。

+4

残念ながら、ドキュメントにprepareAsync()が十分であると表示されているようですが、それだけでは不十分です。 prepare()以外の呼び出しはアプリケーションをハングする可能性があるので、MediaPlayerインスタンスが独自のスレッドにある方がよいでしょう。 – ajacian81

7

私は、この回答の一部を他の場所に掲載しましたが、まだ関連性があります。

残念なことに、prepareAsync()を呼び出すだけでは、特にネットワークからファイルを再生しているときに、ANRプロンプトとアプリケーションが数秒間停止するのを防ぐのに不十分です。あなたの最善の策はMediaPlayerインスタンスを独自のスレッドに置くことです。または、少なくともMediaPlayer.start()のようなハンドラで集中的に実行することができます。私はMediaPlayerを1年以上使用していましたが、状況によっては、さまざまな呼び出しの後に確実にハングアップすることがわかります。

理想的には、サービスからMediaPlayerを制御するスレッドを生成する必要があります。こうすることで、アプリがバックグラウンドにある間にメディアの再生が継続され、(prepare()/ prepareAsync()以外の)ブロッキングコールがアプリをハングアップしないようにすることができます。

+1

私は同意します。しかし、メディアプレイヤーがサービスから生成されたスレッドであっても終了したと私は考えています。メディアプレイヤーには、フォアグラウンドサービスよりも優先順位が低く、Androidがサービスを終了する前にスポーンされたスレッドを殺す意思があるという独自の内部スレッドがあるようだ。 – AndroidDev

+0

だから、これは問題が受け入れられたものよりも優れていると思います。とにかく、私が知りたいことは、サービスであっても別のスレッドを実行する必要があるということです。現在、私はまったく異なるプロセスを使用していますが、メインプロセスに移行したいと考えています。 – frostymarvelous

+0

サービスは、デフォルトでメインのUIスレッドで実行されます。このサービスでは、スレッド/非同期タスクを作成できます。それは私がそれをやる方法とほとんど同じです。 – ajacian81

関連する問題