В качестве альтернативы runOnUiThread
вы можете использовать AsyncTask
и использовать механизм publishProgress/onProgressUpdate
для касания видов.У Google есть довольно хороший пост об использовании AsyncTask
, включая сведения о том, какие методы запускаются в задаче, а какие - в потоке пользовательского интерфейса.Выполните вычисления в doInBackground
и вызывайте publishProgress
всякий раз, когда есть какие-то кванты данных, которые нужно передать в пользовательский интерфейс для рендеринга.Затем визуализируйте эти данные в функции onProgressUpdate
.Обратите внимание, что параметры для обеих функций совершенно произвольны, и вы можете определить их по своему усмотрению.
edit: Перечитав ваш вопрос, я задаюсь вопросом, стоит ли использовать отдельный поток, так как выпринимаем данные от пользователя во время ваших вычислений.Вполне возможно, что между движением ползунка и рендерингом может быть значительная задержка, особенно если вычислительный поток истощается.Если вычисления достаточно интенсивные, чтобы оправдать отдельный поток, вы можете подумать о том, чтобы подбрасывать индикатор выполнения во время вычислений, а не вводить пользователя в заблуждение из-за слишком большой задержки рендеринга за его движением ползунка.Либо так, либо вам придется добавить некоторую логику в cancel
поток вычислений, если изменение обнаружено и текущий рендер не завершен, а затем снова запустите его с новыми параметрами.Для получения дополнительной информации об отмене AsyncTasks
прочитайте раздел (ы) введения в документации для AsyncTask
.
edit2: когда я реализовал свой AsycTask, я определил объект, который содержалвсе элементы, которые мне нужны: представления, курсоры, исключения и т. д., и использовали его в качестве параметра для передачи туда и обратно.Я имею в виду ту же концепцию с TouchViewData, так как поток не может касаться представления.Просто соберите все данные, которые вам нужны, и пусть поток сходит с ума.
public class MyAsyncTask extends AsyncTask<TouchViewData, Object, void> {
/*
* These run on the UI thread, and can access the Views
*/
protected void onProgressUpdate(Object... values) {
// Here's where the magic happens!
// Update your views, open dialogs, Toast the user, whatever!
}
protected void onPreExecute() {
// Prep anything you need for the thread
}
protected void onPostExecute() {
// Finalize any rendering or cleanup
}
protected void onCancelled() {
// Got cancelled! Time to clean up
}
/*
* This runs in a separate thread, and can not change the View at all
*/
public void doInBackground(TouchViewData... params) {
while(stillCalculating && ! isCancelled()) {
// Do your calculations, then...
publishProgress(...); // pass some data to the UI thread to render
}
return;
}
}
В вашей деятельности:
MyAppTask calculator = new MyAppTask();
calculator.execute(touchViewInstanceData, someObject);
...
// if you need to:
calculator.cancel();