Ответ 1
custListLoadThread = new Thread(loadRunnable);
custListLoadThread.start();
Вам нужно запустить поток, а не вызывать метод run() в текущем потоке.
Я, насколько мне известно, реализовал 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 не работает в фоновом режиме?
custListLoadThread = new Thread(loadRunnable);
custListLoadThread.start();
Вам нужно запустить поток, а не вызывать метод run() в текущем потоке.
Если вы хотите выполнить код в фоновом потоке, который ничего не делает с пользовательским интерфейсом:
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();