Запуск runnable в фоновом потоке

Я, насколько мне известно, реализовал runnable, который создается в новом потоке. Тем не менее, поток, похоже, не работает в фоновом режиме, а действия, выполняемые внутри runnable, останавливают пользовательский интерфейс с тяжелыми действиями.

См. ниже:

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

Однако этот код не работает в фоновом режиме, он все еще работает в потоке пользовательского интерфейса. Я поместил строку Gen.popup("TEST");, чтобы убедиться в этом (вызов toast всплывает в потоке, отличном от UI, должен вызывать ошибку).

Любые идеи относительно того, почему этот runnable не работает в фоновом режиме?

Ответ 1

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

Вам нужно запустить поток, а не вызывать метод run() в текущем потоке.

Ответ 2

Если вы хотите выполнить код в фоновом потоке, который ничего не делает с пользовательским интерфейсом:

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

Конечно, как написано ранее, вы также можете создать новый поток (который не зависит от потока пользовательского интерфейса):

    new Thread(runnable).start();

В вашем примере вы хотите обновить элементы пользовательского интерфейса, поэтому лучше использовать AsyncTask (должен вызываться из потока пользовательского интерфейса!):

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