Как запустить ProgressBar, используя данные из стороннего пакета
Дано: Пакет, написанный на С# и прогнанный через генератор Java. Передан мне в виде папки с названием, которую я просто скопировал в проект. Там есть функция, которая вызывается например так:
AlgoResult res = processAlgorithm(portf, apars, _ProgressChangedEventHandler_ _progress);
Функция очень тяжелая, устройство виснет секунд на 30-40 (можно и сильно больше, если постараться ), она основная в Приложении, поэтому хочется приделать к ней хотя бы ProgressBar.
Последний аргумент - как раз для бегунка.
Инструкция от разработчика:
В класс нужно добавить следующее (прямо внутрь, где эта функция), только в строке
public static Program _globalInstance;
изменить Program на имя своего класса. Основная реализация - после строки: // здесь вывод бегунка
private static void _progress(Object sender, ProgressEventArgs arg) {
// здесь вывод бегунка
}
public static class ProgressChangedEventHandler_ _progress implements
ProgressEventHandler {
@Override
public void call(Object sender, ProgressEventArgs arg) {
_progress(sender, arg);
}
public ProgressChangedEventHandler_ _progress() {
}
}
private static ProgressChangedEventHandler_ _progress
_ProgressChangedEventHandler_ _progress;
public static Program _globalInstance;
static {
try { _globalInstance = new Program(); }
catch(Exception e) { }
_ProgressChangedEventHandler_ _progress = new
ProgressChangedEventHandler_ _progress();
}
Поскольку вызов функции у меня прямо из Main, то, как и написано, поменял Program на MainActivity и добавил "вывод бегунка" в логи:
public static MainActivity _globalInstance;
static {
try { _globalInstance = new MainActivity(); }
catch(Exception e) { }
_ProgressChangedEventHandler__progress = new ProgressChangedEventHandler__progress();
}
private static void _progress(Object sender, ProgressEventArgs arg) {
// здесь вывод бегунка
percentProgress = arg.getProgressPercentage();
Log.d(TAG, percentProgress + "% ");
}
Реально, в логи валятся цифры от 1 до 100.
И с этого момента случился затык. Перебрал кучу вариантов реализации прогресс бара, найденных в разных местах, но получил один из двух исходов:
- Всё умирает на 30 секунд, прогресс появляется сразу 100% одновременно с результатом;
- Прогресс бежит на фоне сообщения о неудачном исходе вычислений (UI отработал независимо на пустом результате) и если продолжать, то следующий прогресс бежит уже на фоне результата предыдущего вычисления и т.д.;
Коды выкладывать не буду, чтобы не позориться ). Да они и не сохранились. Разработчик предлагает найти в jave аналог сишного doEvents и не парить ему мозги со всякой ерундой (претензий нет, пакет написан в качестве шефской помощи и человек никогда не писал для мобильных устройств вообще и на jave, в частности).
Предложите, пожалуйста, вариант реализации. Спасибо.
PS:
Испробованные варианты:
Исход 1:
(Прямо по инструкции )
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
...
int percentProgress;
ProgressBar progressAlgorithm;
...
private static void _progress(Object sender, ProgressEventArgs arg) {
// здесь вывод бегунка
percentProgress = arg.getProgressPercentage();
progressAlgorithm.setProgress(percentProgress);
}
...
@Override
public void onClick(View v)
{
switch(v.getId())
{
...
case R.id.chCalculation:
algoResult = processAlgorithm(port, algoParams,_ProgressChangedEventHandler_ _progress);
break;
...
}
}
...
}
Исход 2:
.....
@Override
public void onClick(View v)
{
switch(v.getId())
{
...
case R.id.chCalculation:
Thread threadGetResult = new Thread(new Runnable() {
@Override
public void run() {
try
{
algoResult = processAlgorithm(port,
algoParams,_ProgressChangedEventHandler_ _progress);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
threadGetResult.start();
break;
...
}
}
.....
Это то, что сразу сделал. Дальше были попытки
threadGetResult.join();
Получился Исход 1
Потом пробовал усыплять основной поток на полсекунды внутри onClick, когда функция в фоновом потоке. Получился Исход 1.
while (percentProgress < 99)`
{
progressAlgoruthm.setProgress(percentProgress);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Еще что-то делал, сейчас и не вспомню уже. И вроде как понятно, что происходит, но непонятно, как это обойти )
И да, private static void _progress работает, как автомат Калашникова - числа прогресса во всех вариантах валятся в логи со страшной силой )