いくつかのコードをバックグラウンドで継続的に実行したい。私はサービスでそれをしたくありません。他に可能な方法はありますか?
Thread
でActivity
クラスを呼び出してみましたが、Activity
がしばらくバックグラウンドに残った後、停止します。 Thread
クラスも動作を停止します。
class testThread implements Runnable {
@Override
public void run() {
File file = new File( Environment.getExternalStorageDirectory(), "/BPCLTracker/gpsdata.txt" );
int i = 0;
RandomAccessFile in = null;
try {
in = new RandomAccessFile( file, "rw" );
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String line =null;
while ( true ) {
HttpEntity entity = null;
try {
if ( isInternetOn() ) {
while ( ( line = in.readLine() ) != null ) {
HttpClient client = new DefaultHttpClient();
String url = "some url";
HttpPost request = new HttpPost( url );
StringEntity se = new StringEntity( line );
se.setContentEncoding( "UTF-8" );
se.setContentEncoding( new BasicHeader( HTTP.CONTENT_TYPE, "application/json" ) );
entity = se;
request.setEntity( entity );
HttpResponse response = client.execute( request );
entity = response.getEntity();
i++;
}
if ( ( line = in.readLine() ) == null && entity != null ) {
file.delete();
testThread t = new testThread();
Thread t1 = new Thread( t );
t1.start();
}
} else {
Thread.sleep( 60000 );
} // end of else
} catch (NullPointerException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}// end of while
}// end of run
}
もしあなたが必要ならば:
バックグラウンドスレッドでコードを実行する
uIに触れたり更新したりしないコードを実行する
完了するまでに数秒かかる(短い)コードを実行する
次に、AsyncTaskを使用する次のクリーンで効率的なパターンを使用します。
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//TODO your background code
}
});
長期的なバックグラウンドプロセスの場合、Androidではスレッドは最適ではありません。しかし、ここにコードがあり、あなた自身の責任でそれを行います...
サービスまたはスレッドはバックグラウンドで実行されますが、タスクは更新を取得するためにトリガーを何度も呼び出す必要があります。つまり、タスクが完了したら、次の更新のために関数を呼び出す必要があります。
タイマー(定期的なトリガー)、アラーム(タイムベーストリガー)、ブロードキャスト(イベントベーストリガー)、再帰は関数を呼び起こします
public static boolean isRecursionEnable = true;
void runInBackground() {
if (!isRecursionEnable)
// Handle not to start multiple parallel threads
return;
// isRecursionEnable = false; when u want to stop
// on exception on thread make it true again
new Thread(new Runnable() {
@Override
public void run() {
// DO your work here
// get the data
if (activity_is_not_in_background) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI
runInBackground();
}
});
} else {
runInBackground();
}
}
}).start();
}
いくつかのコードをバックグラウンドで継続的に実行したい。私はサービスでそれをしたくありません。他に可能な方法はありますか?
おそらくあなたが探しているメカニズムは AsyncTask
です。バックグラウンドスレッドでバックグラウンドプロセスを実行するように直接指定されています。また、その主な利点は、Main(UI)スレッドで実行されるいくつかのメソッドを提供し、タスクの進行状況をユーザーに通知したり、バックグラウンドプロセスから取得したデータでUIを更新したりする場合にUIを更新できることです。
ここから始める方法がわからない場合は、ニースチュートリアルをご覧ください。
注:また、 IntentService
を ResultReceiver
とともに使用することもできます。
AsyncTaskの代替はrobospiceです。 https://github.com/octo-online/robospice 。
ロボスパイスの機能の一部。
1.(バックグラウンドAndroidServiceで)非同期的にネットワークリクエストを実行します(例:Spring Androidを使用したRESTリクエスト)。結果が準備できたらUIスレッドでアプリに通知します。
2.強く型付けされています! POJOを使用してリクエストを行い、リクエスト結果としてPOJOを取得します。
3.リクエストに使用されるPOJOにも、プロジェクトで使用するアクティビティクラスにも制約を適用しません。
4.結果をキャッシュする(JsonでJacksonとGsonの両方、またはXml、フラットテキストファイル、またはORM Liteを使用したバイナリファイルでも)。
5.ネットワークリクエストの結果をアクティビティ(またはその他のコンテキスト)に通知する
6. Androidローダーとは異なり、Android AsyncTasksとは異なり、UIスレッドでアクティビティを通知するメモリリークはありません。
7.シンプルだが堅牢な例外処理モデルを使用します。
開始するサンプル。 https://github.com/octo-online/RoboSpice-samples 。
https://play.google.com/store/apps/details?id=com.octo.Android.robospice.motivations&feature=search_result にあるrobospiceのサンプル。
class Background implements Runnable {
private CountDownLatch latch = new CountDownLatch(1);
private Handler handler;
Background() {
Thread thread = new Thread(this);
thread.start();
try {
latch.await();
} catch (InterruptedException e) {
/// e.printStackTrace();
}
}
@Override
public void run() {
Looper.prepare();
handler = new Handler();
latch.countDown();
Looper.loop();
}
public Handler getHandler() {
return handler;
}
}
異なるコードでpredioticlyにスレッドを実行する必要がある場合の例を次に示します。
リスナー:
public interface ESLThreadListener {
public List onBackground();
public void onPostExecute(List list);
}
スレッドクラス
public class ESLThread extends AsyncTask<Void, Void, List> {
private ESLThreadListener mListener;
public ESLThread() {
if(mListener != null){
mListener.onBackground();
}
}
@Override
protected List doInBackground(Void... params) {
if(mListener != null){
List list = mListener.onBackground();
return list;
}
return null;
}
@Override
protected void onPostExecute(List t) {
if(mListener != null){
if ( t != null) {
mListener.onPostExecute(t);
}
}
}
public void setListener(ESLThreadListener mListener){
this.mListener = mListener;
}
}
異なるコードを実行します:
ESLThread thread = new ESLThread();
thread.setListener(new ESLThreadListener() {
@Override
public List onBackground() {
List<EntityShoppingListItems> data = RoomDB.getDatabase(context).sliDAO().getSL(fId);
return data;
}
@Override
public void onPostExecute(List t) {
List<EntityShoppingListItems> data = (List<EntityShoppingListItems>)t;
adapter.setList(data);
}
});
thread.execute();