Как правильно использовать Workerthread?

Я пишу приложения для Android уже несколько месяцев, и я нахожусь в точке, где я создаю действительно необходимое приложение.

Поскольку я хочу, чтобы это работало хорошо и быстро, я создал Workerthread для выполнения всех видов задач в фоновом режиме, в то время как пользовательский интерфейс может... создавать, работать и все такое.

Он основан на проекте приложения Android Studio Drawer.

В Main.onCreate я получил свой operator=new Operator(), который расширяет Thread,

Теперь при загрузке нового фрагмента он иногда вызывает MainActivity.operator.someMethod() (Я сделал оператор статическим, чтобы я мог использовать его из любого места), и через некоторое время я понял, что единственные задачи, выполняющиеся в фоновом режиме, - это операторы run() метод и Asynctask Фрагмент моего логина запускается. Все остальное пользовательский интерфейс ожидает завершения и, следовательно, выполняется потоком пользовательского интерфейса.

Вот я и подумал: нет проблем! мой operator получает handler который встроен в run()и я меняю эти задачи:

public void run() {
    Looper.prepare();   //Android crashed and said I had to call this
    OpHandler = new Handler();
    LoadLoginData();
    [...Load up some Arrays with hardcoded stuff and compute for later use...]
}

public void LoadLoginData() {
    OpHandler.post(LoadLoginDataRunnable);
}
private Runnable LoadLoginDataRunnable = new Runnable() {
    @Override
    public void run() {
        if(sharedPreferences==null)
            sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
        sessionID=sharedPreferences.getString("sessionID", null);
        if(sessionID!=null) {
            postenID = sharedPreferences.getString("postenID", PID_STANDARD);
            postenName = sharedPreferences.getString("postenName", PID_STANDARD);
            context.QuickToast(sessionID, postenName, postenID);
        }
    }
};

контекст - моя MainActivity, я дал оператору ссылку, чтобы я мог отправить тосты для отладки.

Но теперь, кажется, что Runnables не запускаются или не завершаются, любой материал Log.e или Log.d не появляется в консоли.

После некоторого гуглинга и переполнения стека все просто объясняют, в чем разница между обработчиками, Asynctask и потоками. И примеры многозадачности всегда показывают только что-то вроде new Thread(new Runnable{run(task1)}).start раза 3 с разными задачами.

И так стал мой большой вопрос:

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

Изменить: чтобы уточнить, я также хотел бы прямого решения моей специальной проблемы.

Изменить 2: после прочтения комментария никис (спасибо), простой ответ, кажется, "использовать HandlerThread вместо потока". Постараюсь, как только я вернусь домой.

Попробуем HandlerThread сейчас. Похоже, мой OpHandler, инициализированный в run(), разрушается или что-то после run() закончил, не уверен, что здесь (это, кстати, еще одна загадка, на которую я надеялся получить ответ здесь). Я получаю NullpointerException, как только я пытаюсь использовать его после run() закончил

1 ответ

Сделайте ваш рабочий поток владельцем очереди задач. в run() метод, просто вытолкнуть задачу из очереди и выполнить ее. Если очередь пуста, дождитесь ее заполнения.

class Operator extends Thread
{
     private Deque<Runnable> tasks;
     private boolean hasToStop=false;

     void run()
     {
          boolean stop=false;
          while(!stop)
          {
               sychronized(this)
               {
                    stop=hasToStop;
               }
               Runnable task=null;
               synchronized(tasks)
               {
                    if(!tasks.isEmpty())
                         task=tasks.poll();
               }
               if(task!=null)
                   task.run();
          }
     }

     void addTask(Runnable task)
     {
          synchronized(tasks)
          {
               tasks.add(task);
          }
     }

     public synchronized void stop()
     {
          hasToStop=true;
     }
}
Другие вопросы по тегам