web-dev-qa-db-ja.com

Androidのバックグラウンドスレッドでコードを実行するにはどうすればよいですか?

いくつかのコードをバックグラウンドで継続的に実行したい。私はサービスでそれをしたくありません。他に可能な方法はありますか?

ThreadActivityクラスを呼び出してみましたが、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

    }
97
user2082987

もしあなたが必要ならば:

  1. バックグラウンドスレッドでコードを実行する

  2. uIに触れたり更新したりしないコードを実行する

  3. 完了するまでに数秒かかる(短い)コードを実行する

次に、AsyncTaskを使用する次のクリーンで効率的なパターンを使用します。

AsyncTask.execute(new Runnable() {
   @Override
   public void run() {
      //TODO your background code
   }
});
316
Brandon Rude

長期的なバックグラウンドプロセスの場合、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();
}
35
Sandeep P

いくつかのコードをバックグラウンドで継続的に実行したい。私はサービスでそれをしたくありません。他に可能な方法はありますか?

おそらくあなたが探しているメカニズムは AsyncTask です。バックグラウンドスレッドでバックグラウンドプロセスを実行するように直接指定されています。また、その主な利点は、Main(UI)スレッドで実行されるいくつかのメソッドを提供し、タスクの進行状況をユーザーに通知したり、バックグラウンドプロセスから取得したデータでUIを更新したりする場合にUIを更新できることです。

ここから始める方法がわからない場合は、ニースチュートリアルをご覧ください。

注:また、 IntentServiceResultReceiver とともに使用することもできます。

18
Simon Dorociak

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のサンプル。

2
Raghunandan
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;
    }
}
1
Geno Papashvili

異なるコードで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();
0
Beyaz