Come posso eseguire il codice in un thread in background su Android?

Voglio un po ‘ di codice per eseguire continuamente in background. Non voglio farlo in un servizio. Non c’è altro modo possibile?

Ho provato a chiamare il Thread classe nel mio Activity ma il mio Activity rimane in background per un po di tempo e poi si ferma. Il Thread classe smette di funzionare.

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

    }
  • Ciao. Potete per favore postare un po ‘ di codice come esempio di che cosa avete provato? Ci sono diversi modi per eseguire il codice in un thread in background, ma si deve ricordare, se si accede a qualsiasi dei componenti dell’interfaccia utente, è necessario accedere sul thread dell’interfaccia utente utilizzando il runOnUiThread() metodo.
  • C’è qualche motivo particolare per non usare il Servizio
  • questo non è così raccomandato. l’esecuzione continua di drain della batteria del dispositivo.
  • Ho inviato il codice.
  • Ho provato ad utilizzare nel servizio, ma il suo invio lo stesso record più volte.
  • Sono d’accordo che drena la batteria, ma hanno bisogno di farlo. come voglio inviare i dati in modo continuo.

 

7 Replies
  1. 340

    SE avete bisogno di:

    1. esecuzione di codice in un Thread in background

    2. eseguire il codice che NON tocca/aggiornare l’interfaccia utente

    3. execute (breve) del codice, che avrà al massimo un paio di secondi per completare

    QUINDI utilizzare la seguente pulita ed efficiente modello che utilizza AsyncTask:

    AsyncTask.execute(new Runnable() {
       @Override
       public void run() {
          //TODO your background code
       }
    });
    • Nota: Richiede l’API di livello 11
    • Ho usato il codice di cui sopra si è detto che per inviare e-mail che non hanno collegamento con UI. Per la prima volta, ha funzionato bene, ma se provo ad eseguire lo stesso codice di nuovo, la mia app è rimasto bloccato. Devo uccidere AsyncTask dopo l’esecuzione di codice ?
    • Perché non si utilizza il seguente, che è più leggero: new Thread(new Runnable() { @Override public void run() { // sfondo di codice } }).start();
    • Anche se si desidera aggiornare l’interfaccia utente è possibile utilizzare il seguente frammento di codice all’interno di run: attività.runOnUiThread(new Runnable() { @Override public void run() { //Aggiorna UI } });
    • C’è la possibilità di incorrere in perdita di memoria?
    • Una cosa da notare è che AsyncTasks sono qeued. Se si utilizza questo per una serie di server di chiamate api, non verrà eseguito in parallelo.

  2. 40

    Ricordare in Esecuzione in Background, continuamente in Esecuzione di due diversi compiti.

    A lungo termine i processi in background, i Thread non sono ottimali con Android. Tuttavia, ecco il codice e lo farà a proprio rischio e pericolo…

    Ricordare Servizio o il Thread verrà eseguito in background, ma il nostro compito deve fare trigger (chiamare di nuovo e di nuovo) per ottenere gli aggiornamenti, cioè una volta che il compito è completato, abbiamo bisogno di richiamare la funzione per il prossimo aggiornamento.

    Timer (periodico trigger), Allarme (base dei tempi di trigger), Trasmissione di un Evento in base Trigger), la ricorsione si svegli nostre funzioni.

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

    L’Utilizzo Del Servizio:
    Se si avvia un Servizio avrà inizio, Si eseguirà il compito, e viene arrestato. dopo l’esecuzione di un task. terminato potrebbe anche essere causato da un’eccezione o un utente ucciso manualmente da impostazioni.
    START_STICKY (Sticky Servizio) è l’opzione data da android, il servizio verrà riavviato da solo, se terminato il servizio.

    Ricordare la questione differenza tra il multiprocessing e multithreading?
    Il servizio è un processo in background (come per le attività senza UI),
    Il modo stesso in cui si avvia il thread in attività per evitare che il carico sul thread principale (Attività thread), allo stesso modo è necessario per avviare il thread(o async attività) in servizio per evitare di caricare sul servizio.

    In un unico prospetto, se si desidera una corsa in background continua attività, è necessario avviare un StickyService ed eseguire il filo nel servizio sull’evento di base

    • Vorresti raccomandare questo metodo per l’esecuzione di un custom SignalStrengthListener in background per una media di 20 minuti, durante la cattura di valori da parte dell’ascoltatore, una volta al secondo per aggiornare il thread dell’interfaccia utente? Qui è ancora di più il contesto: stackoverflow.com/questions/36167719/…
    • Come funziona il processo viene eseguito di nuovo se si imposta “isRecursionEnable=true’? Quindi chiamare all’interno della ‘run’ per ‘runInBackground()’ , come non si entra se la dichiarazione all’inizio della funzione?
  3. 22

    Voglio un po ‘ di codice per eseguire continuamente in background. Non voglio
    per farlo in un servizio. Non c’è altro modo possibile?

    Più probabile meccanismo che si sta cercando è AsyncTask. Direttamente designati per l’esecuzione di un processo in background sul Thread in background. Il suo principale vantaggio è che offre alcuni metodi che funzionano su Main(UI) Filetto e rendere possibile per aggiornare l’interfaccia utente se si desidera annunciare utente su alcuni progressi in attività o aggiornamento della UI con i dati recuperati dal processo in background.

    Se non sai come iniziare qui è il bel tutorial:

    Nota: c’è Anche la possibilità di utilizzare IntentService con ResultReceiver che lavora bene.

    • non provare?
    • questi parametri di asyncTask sono confuso
    • AsyncTask è solo un wrapper per il Thread comunque, in modo da non risolve il problema di Android uccidendo l’applicazione mentre è in background
    • Ciao @LassiKinnunen ho scritto quella risposta 5 anni fa. Ora tutto è cambiato e non sono attualmente in uso AsyncTask, perché la sua perdita di memoria non-cassetta di sicurezza.
    • Sì mi rendo conto che anche se le persone ancora trovato questo con google e ho visto tanti commenti di persone che raccomandava di utilizzare google wrapper anche quando serve a poco o nessun scopo, mi dispiace. Come per la domanda originale, se qualcuno è alla ricerca di alcune risposte nel 2018, la creazione di un servizio e lo lancio e il marchio in primo piano con una notifica, se si vuole massimizzare le probabilità di non ottenere ucciso. L’attuale lungo processo in esecuzione può essere gestito con i gestori o un thread separato. Non si è accorto che sono riusciti a fare effettivamente non perdita di memoria comunque sicuro?
  4. 3

    Semplice 3-Liner

    Un modo semplice di fare questo che ho trovato un commento di @awardak in Brandon Rude risposta:

    new Thread( new Runnable() { @Override public void run() { 
      //Run whatever background code you want here.
    } } ).start();

    Io non sono sicuro di se, o come , questo è meglio che usare AsyncTask.execute ma sembra funzionare per noi. Commenti per la differenza sarebbe apprezzato.

    Grazie, @awardak!

  5. 2

    Un’Alternativa a AsyncTask è robospice. https://github.com/octo-online/robospice.

    Alcune delle caratteristiche di robospice.

    1.viene eseguita in modo asincrono (in un contesto AndroidService) le richieste di rete (es: il RESTO le richieste di utilizzo di Spring Android).la notifica app, sul thread dell’interfaccia utente, quando il risultato è pronto.

    2.è fortemente tipizzato ! Potete fare le vostre richieste utilizzando Pojo e si ottiene Pojo come richiesta risultati.

    3.applicare senza vincoli né su Pojo utilizzato per le richieste, né su classi di Attività all’interno dei progetti.

    4.memorizza nella cache i risultati (in Json sia con Jackson e Ediletto, o Xml o file di testo, file binari, anche utilizzando ORM Lite).

    5.segnala le tue attività (o in qualunque altro contesto) l’esito della richiesta di rete se e solo se sono ancora in vita

    6.nessuna perdita di memoria a tutti, come Android Caricatori, a differenza di Android AsyncTasks segnala le tue attività sul loro Thread UI.

    7.utilizza un semplice ma robusto eccezione modello di gestione.

    Campioni per iniziare con. https://github.com/octo-online/RoboSpice-samples.

    Un campione di robospice a https://play.google.com/store/apps/details?id=com.octo.android.robospice.motivations&feature=search_result.

    • Come memorizzare una matrice ottenuta dalla rete di SQLite? Fondamentalmente vorrei: ottenere i dati dalla rete E salvarli sul mio SQLite, sia nel thread in background, quindi ottenere la mia UI notifica per aggiornare ListView. Io di solito lo fanno con IntentService, ma RoboSpice è meno di battitura.
    • è possibile utilizzare un intento servizio se la sua un lungo funzionamento. Inoltre è possibile utilizzare asynctask, ma solo se per una breve durata. È possibile creare un thread e fare tutte le cose. Non ho usato robospice per lungo tempo ormai. Ci sono altre reti di biblioteche come il volley…
    • OK grazie. Ho pensato di usare Robospice, ma sembra che non è troppo buono (flessibile) per le mie esigenze. Io uso IntentService per un lungo periodo di tempo con successo.
  6. 2
    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;
        }
    }
    • Benvenuti a StackOverflow. Risposte con solo il codice in essi tendono ad essere contrassegnati per l’eliminazione come sono “bassa qualità”. Si prega di leggere la sezione di aiuto sulle domande quindi prendere in considerazione l’aggiunta di qualche commento alla tua Risposta.
  7. 0

    Se avete bisogno di eseguire thread predioticly con diversi codici qui è un esempio:

    Ascoltatore:

    public interface ESLThreadListener {
    
        public List onBackground();
    
        public void onPostExecute(List list);
    
    }

    Classe Thread

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

    Eseguire codici diversi:

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

Lascia un commento