web-dev-qa-db-fra.com

Démarrage d'un exécutable dans le thread d'arrière-plan

À ma connaissance, j'ai implémenté un exécutable qui est créé sur un nouveau thread. Cependant, le thread ne semble pas s'exécuter en arrière-plan et les actions prises à l'intérieur du runnable bloquent l'interface utilisateur avec des actions lourdes.

Voir ci-dessous:

custListLoadThread = new Thread(loadRunnable);
custListLoadThread.run();

private Runnable loadRunnable = new Runnable()
{
    @Override
    public void run()
    {
        Android.os.Process.setThreadPriority(Android.os.Process.THREAD_PRIORITY_BACKGROUND);

        Gen.popup("TEST"); // Creates a toast pop-up.
        // This is to know if this runnable is running on UI thread or not!

        try
        {               
            customers = Db.BasicArrays.getCustomers(CustomApp.Session.businessCode, empId);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    populate();
                    setCustListVisible(true);
                    loading = false;
                }
            });
        }
        catch (final Exception ex)
        {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Gen.popup(ex.getMessage());
                }
            });
        }
    }
};

Cependant, ce code ne s'exécute pas en arrière-plan, il semble toujours s'exécuter sur le thread d'interface utilisateur. J'ai placé la ligne Gen.popup("TEST"); pour m'en assurer (l'appel d'une fenêtre pop-up toast dans un thread non-UI devrait provoquer une erreur).

Des idées sur la raison pour laquelle cette exécutable ne fonctionne pas en arrière-plan?

15
Mike Baxter
custListLoadThread = new Thread(loadRunnable);
custListLoadThread.start();

Vous devez démarrer le thread, pas appeler la méthode run () dans le thread actuel.

24
Steve M

Si vous souhaitez exécuter du code sur un thread d'arrière-plan qui ne fait rien avec l'interface utilisateur:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //your action
        }
    };
    AsyncTask.execute(runnable);

Bien sûr, comme écrit précédemment, vous pouvez également créer un nouveau thread (qui est indépendant du thread d'interface utilisateur):

    new Thread(runnable).start();

Dans votre exemple, vous souhaitez mettre à jour des éléments d'interface utilisateur, il vaut donc mieux utiliser un AsyncTask (doit être appelé à partir du thread d'interface utilisateur!):

    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            // your async action
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            // update the UI (this is executed on UI thread)
            super.onPostExecute(aVoid);
        }
    }.execute();
12
Timo Bähr