IT박스

Android의 백그라운드 스레드에서 코드를 어떻게 실행할 수 있습니까?

itboxs 2020. 8. 14. 07:32
반응형

Android의 백그라운드 스레드에서 코드를 어떻게 실행할 수 있습니까?


일부 코드가 백그라운드에서 계속 실행되기를 원합니다. 나는 서비스에서 그것을하고 싶지 않습니다. 다른 방법이 있습니까?

나는 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

    }

필요한 경우 :

  1. 백그라운드 스레드에서 코드 실행

  2. UI를 터치 / 업데이트하지 않는 코드 실행

  3. 완료하는 데 최대 몇 초가 걸리는 (짧은) 코드 실행

그런 다음 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();
}

서비스 사용 : 서비스 를 시작하면 서비스가 시작되고 작업이 실행되고 자체적으로 종료됩니다. 작업 실행 후. 종료는 예외로 인해 발생하거나 사용자가 설정에서 수동으로 종료했을 수도 있습니다. START_STICKY (고정 서비스)는 서비스가 종료되면 서비스가 다시 시작되도록 Android에서 제공하는 옵션입니다.

Remember the question difference between multiprocessing and multithreading? Service is a background process (Just like activity without UI), The same way how you launch thread in the activity to avoid load on the main thread (Activity thread), the same way you need to launch threads(or async tasks) on service to avoid load on service.

In a single statement, if you want a run a background continues task, you need to launch a StickyService and run the thread in the service on event base


I want some code to run in the background continuously. I don't want to do it in a service. Is there any other way possible?

Most likely mechanizm that you are looking for is AsyncTask. It directly designated for performing background process on background Thread. Also its main benefit is that offers a few methods which run on Main(UI) Thread and make possible to update your UI if you want to annouce user about some progress in task or update UI with data retrieved from background process.

If you don't know how to start here is nice tutorial:

Note: Also there is possibility to use IntentService with ResultReceiver that works as well.


An Alternative to AsyncTask is robospice. https://github.com/octo-online/robospice.

Some of the features of robospice.

1.executes asynchronously (in a background AndroidService) network requests (ex: REST requests using Spring Android).notify you app, on the UI thread, when result is ready.

2.is strongly typed ! You make your requests using POJOs and you get POJOs as request results.

3.enforce no constraints neither on POJOs used for requests nor on Activity classes you use in your projects.

4.caches results (in Json with both Jackson and Gson, or Xml, or flat text files, or binary files, even using ORM Lite).

5.notifies your activities (or any other context) of the result of the network request if and only if they are still alive

6.no memory leak at all, like Android Loaders, unlike Android AsyncTasks notifies your activities on their UI Thread.

7.uses a simple but robust exception handling model.

Samples to start with. https://github.com/octo-online/RoboSpice-samples.

A sample of robospice at https://play.google.com/store/apps/details?id=com.octo.android.robospice.motivations&feature=search_result.


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;
    }
}

If you need run thread predioticly with different codes here is example:

Listener:

public interface ESLThreadListener {

    public List onBackground();

    public void onPostExecute(List list);

}

Thread Class

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;
    }
}

Run different codes:

  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();

참고URL : https://stackoverflow.com/questions/15472383/how-can-i-run-code-on-a-background-thread-on-android

반응형