アプリの設計に関して混乱しています。サーバーから新しいデータを取得するには、サーバーを継続的にポーリングする必要があります。Async Task を一定間隔で実行するか、Service をバックグラウンドで実行する方がよい選択肢であるか、私は混乱しています。スレッドは、アプリの実行中にのみ実行されます
5 に答える
あなたの質問にはすでにいくつかの回答がありますが、要約する価値があると思います...
何が必要
完了するまでに時間がかかるコードを実行する場合は、常に UI スレッドとは別のスレッドで実行する必要があります。
次の 2 つの方法でそれを実現できます。
使用Thread
:
これは、新しいスレッドから UI スレッドへの多くの通信が必要ない場合の最も単純な方法です。通信が必要な場合は、おそらく a を使用して通信する必要がありますHandler
。
使用AsyncTask
:
また、別のスレッドで実行され、UI スレッドでいくつかの通信チャネルを既に実装しています。したがって、この通信を UI に戻す必要がある場合は、これが適しています。
必要のないもの
Service
これは主に、メイン アプリケーションを終了した後でも一部のコードを実行し続けるのに役立ちます。上記のオプションを使用して新しいスレッドを生成しない限り、UI スレッドで実行されます。アプリケーションを終了するとスレッドが終了するはずだとおっしゃっていたので、これは必要ありません。
IntentService
BroadcastReceiver
これは、アプリケーションが実行されていない場合でも、定義したコードを開始できる外部イベント (つまり ) によってアクティブ化できます。繰り返しますが、要件に基づいて、これは探しているものではありません。
よろしく。
Android サービスはバックグラウンド スレッドではありません。
したがって、ポーリングするたびに ASyncTask を開始する Service を実行する必要があります。
サービスは、他のアプリケーション オブジェクトと同様に、ホスティング プロセスのメイン スレッドで実行されることに注意してください。これは、サービスが CPU 集中型 (MP3 再生など) またはブロック (ネットワークなど) 操作を行う場合、その作業を行う独自のスレッドを生成する必要があることを意味します。詳細については、プロセスとスレッドを参照してください。IntentService クラスは、実行する作業をスケジュールする独自のスレッドを持つ Service の標準実装として利用できます。
Service
と比較してはいけませんAsyncTask
。おそらくここを意味していると思いますが、一般的な名前にもかかわらず、IntentService
これは とは少し異なります。Service
定期的なフェッチについては、繰り返しアラーム ( を使用AlarmManager
) と (ほとんどの場合) を使用IntentService
してフェッチを行います。
ここでは、AsyncTask の基礎といくつかのチュートリアルを説明 します。ここでは、IntentService の基礎とチュートリアルを説明します。
IntentService
ジョブは設計上キューに入れられますが、AsyncTasks
完全に並列に実行できることに注意してください。ただし、新しい API での AsyncTask 処理に関連するリグレッションに注意してください。回避策はコード行を数行追加するだけなので大したことではありませんが、知っておく価値はあります。
編集
AsyncTask のライフサイクルがアクティビティのライフサイクルに結びついていることに関して、多くの人の間で誤解が生じています。これは間違っています。AsyncTask はアクティビティから独立しています。コードで onDestroy() からクリーンアップしない限り、Finishing Activity は AsyncTasks に対して何もしません。ただし、アクティビティのプロセスがバックグラウンドで強制終了されている場合は、プロセス全体の強制終了の一部として、AsyncTask も強制終了されます。
「継続的にポーリング」したい場合は、asyncTask では実行できません。アプリが Android によって停止されると、タスクは停止します。ブランデルがすでに指摘したように、サービス自体はどちらも行いません。Service はメイン スレッドで実行され、メイン スレッドでポーリングを実行したくない場合。それには 2 つの方法があります。独自のスレッドを生成して実行したいことを実行する Service を作成するか、AsyncTask または別のスレッドで実行されるポーリングをスケジュールするようにします。アプリでポーリングを行わないようにしていますが、必要な場合は、サービスでポーリングを行う特別なスレッドを作成するのが最善のようです。
アプリの機能とポーリングの目的に応じて、別のスレッドの優先度を下げて、他の処理の邪魔にならないようにすることができます。
スレッドは、アプリの実行中にのみ実行されます
次にAsyncTask
、最も簡単な解決策になります。publishProgress()
バックグラウンド スレッドからアプリ スレッドに定期的にデータを送信します。Thread.sleep()
を使用して目的の間隔を設定しdoInBackground()
ます。また、 Activity のメソッドで新しいタスクを開始しonResume()
、Activity のメソッドでこのタスクを終了してonPause()
ください。
例:
public class MyActivity extends Activity {
private AsyncTask<Void,String,Void> mAsyncTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
mAsyncTask = new MyTask();
mAsyncTask.execute();
}
@Override
protected void onPause() {
super.onPause();
if(mAsyncTask != null){
mAsyncTask.cancel(true);
}
}
private void onServerResponse(String response){
Toast.makeText(this, "Got response !", Toast.LENGTH_SHORT).show();
}
private final class MyTask extends AsyncTask<Void,String,Void>{
@Override
protected Void doInBackground(Void... voids) {
while (!isCancelled()){
String response = "";
//server query code here
publishProgress(response);
Log.i("TEST", "Response received");
//sleep for 5 sec, exit if interrupted ,likely due to cancel(true) called
try{
Thread.sleep(5000);
}catch (InterruptedException e){
return null;
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
if(values.length > 0){
onServerResponse(values[0]);
}
}
}
}