Как запустить этот класс в потоке пользовательского интерфейса?

У меня есть класс ScheduleTimer, который работает с массивом дат. Вот:

class ScheduleTimer { public TextView textView; private Timer dateTimer; private Timer remainderTimer; private Date formatDate = new Date(); private Date nextDate; private boolean remainderTimerStarted; private static final long REMINDER_UPDATE_INTERVAL = 1000; private static String[] DATES; private int currentIndex; public ScheduleTimer(final TextView t) { textView = t; dateTimer = new Timer(); } public void main(String[] dates) throws ParseException { checkDates(dates); run(); } private void checkDates(String[] dates) throws ParseException { List<String> list = new ArrayList<>(); DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.ENGLISH); for(String date : dates) { long current = System.currentTimeMillis() + 1000; if(format.parse(date).getTime() - current > 0) { list.add(date); } } DATES = new String[list.size()]; list.toArray(DATES); } private void run() { nextDate = parseDate(DATES[currentIndex]); schedule(); } public void schedule() { runSecondsCounter(); dateTimer.schedule(new TimerTask() { @Override public void run() { System.out.println("Current date is:" + new Date()); currentIndex++; if (currentIndex < DATES.length) { nextDate = parseDate(DATES[currentIndex]); System.out.println("Next date is:" + nextDate); schedule(); } else { remainderTimer.cancel(); } } }, nextDate); } private Date parseDate(String nextDate) { Date date = null; DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.ENGLISH); try { date = format.parse(nextDate); } catch (ParseException e) { e.printStackTrace(); } return date; } private void runSecondsCounter() { if (remainderTimerStarted) { remainderTimer.cancel(); } remainderTimer = new Timer(); remainderTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { remainderTimerStarted = true; long remains = nextDate.getTime() - new Date().getTime(); System.out.println("Remains: " + (remains / 1000) + " seconds"); formatDate.setTime(remains); textView.setText(formatDate.toString()); } }, REMINDER_UPDATE_INTERVAL, REMINDER_UPDATE_INTERVAL); } } 

Он отлично работает, если я запускаю его так же, как Java-приложение, а не Android, и он выводит каждую подсчитанную секунду в консоли. Но когда дело доходит до запуска в среде Android, оно либо говорит, что поток пользовательского интерфейса не может быть затронут ни с каким другим потоком, либо он дает мне NullPointerException в методе run() класса ScheduleTimer .

Я использую его так: new ScheduleTimer(textView).main(new String[] {"13.04.2015 13:59", "13.04.2015 14:14", "13.04.2015 14:15"});

Я пытался использовать AsyncTask или Handler , но, вероятно, я не делал этого правильно. Во всяком случае, мне нужно найти способ обновить мой TextView каким-то образом, используя этот класс.

Может ли кто-нибудь помочь мне в этом? Как я могу запустить его обычно в моем методе onCreateView и правильно передать необходимый TextView ?

Полный ответ: Ваш фрагмент:

 public class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); TextView textView = (TextView) rootView.findViewById(R.id.tv); try { new ScheduleTimer(textView, getActivity()) .main(new String[] {"13.04.2015 13:59", "13.04.2015 14:14", "13.04.2015 14:15"}); } catch (ParseException e) { e.printStackTrace(); } return rootView; } } 

Класс ScheduleTimer:

 class ScheduleTimer { public TextView textView; private Timer dateTimer; private Timer remainderTimer; private Date formatDate = new Date(); private Date nextDate; private boolean remainderTimerStarted; private static final long REMINDER_UPDATE_INTERVAL = 1000; private static String[] DATES; private int currentIndex; private Activity activity; public ScheduleTimer(final TextView t, Activity a) { textView = t; activity = a; dateTimer = new Timer(); } public void main(String[] dates) throws ParseException { checkDates(dates); run(); } private void checkDates(String[] dates) throws ParseException { List<String> list = new ArrayList<>(); DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.ENGLISH); for(String date : dates) { long current = System.currentTimeMillis() + 1000; if(format.parse(date).getTime() - current > 0) { list.add(date); } } DATES = new String[list.size()]; list.toArray(DATES); } private void run() { nextDate = parseDate(DATES[currentIndex]); schedule(); } public void schedule() { runSecondsCounter(); dateTimer.schedule(new TimerTask() { @Override public void run() { System.out.println("Current date is:" + new Date()); currentIndex++; if (currentIndex < DATES.length) { nextDate = parseDate(DATES[currentIndex]); System.out.println("Next date is:" + nextDate); schedule(); } else { remainderTimer.cancel(); } } }, nextDate); } private Date parseDate(String nextDate) { Date date = null; DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.ENGLISH); try { date = format.parse(nextDate); } catch (ParseException e) { e.printStackTrace(); } return date; } private void runSecondsCounter() { if (remainderTimerStarted) { remainderTimer.cancel(); } remainderTimer = new Timer(); remainderTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { remainderTimerStarted = true; long remains = nextDate.getTime() - new Date().getTime(); System.out.println("Remains: " + (remains / 1000) + " seconds"); formatDate.setTime(remains); activity.runOnUiThread(new Runnable() { @Override public void run() { textView.setText(formatDate.toString()); } }); } }, REMINDER_UPDATE_INTERVAL, REMINDER_UPDATE_INTERVAL); } } 

runOnUiThread() отправит ваш Runnable для выполнения в основной поток. В run() вы можете управлять элементами пользовательского интерфейса:

 @Override public void run() { remainderTimerStarted = true; long remains = nextDate.getTime() - new Date().getTime(); formatDate.setTime(remains); runOnUiThread(new Runnable() { // <= here! @Override public void run() { textView.setText(formatDate.toString()); } }); } 

Проверьте это для более подробного объяснения.

Скелет вашего AsyncTask будет выглядеть следующим образом:

 public class ListLoader extends AsyncTask<Void, Void, String> { ProgressDialog Asycdialog = new ProgressDialog(CreateGroup.this); @Override protected void onPreExecute() { // TODO Auto-generated method stub System.out.println("Pre Execute"); Asycdialog.setMessage("Working"); Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL); Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL); Asycdialog.setCancelable(false); Asycdialog.show(); super.onPreExecute(); } protected void onPostExecute(String result) { Asycdialog.cancel(); //Play with result here - Update UI } @Override protected String doInBackground(Context... params) { //Memory intense or long running operation here publishProgress(progress); //Publish your progress - update a textView return "result will be sent to onPostExecute()"; } protected void onProgressUpdate(String... values) { super.onProgressUpdate(values); Asycdialog.setMessage("" + values[0]); } } 
Intereting Posts
Передача id смежного вида в xml в пользовательское представление и извлечение его в конструкторе пользовательского представления Android Cursor.registerContentObserver () Бесплатная библиотека диаграмм для создания линий, бара (сложена и сгруппирована) и объединена в Android Activity.startLockTask () иногда вызывает исключение IllegalArgumentException Возможно ли в android определить константы в XML, которые различаются в зависимости от конфигурации Невозможно установить .apk после декодирования и восстановления (Apktool, Apkstudio) Java.lang.IllegalStateException: Рекурсивная запись в executePendingTransactions с быстрым переключением Как использовать setImageTintList () в Android API <21 Уменьшение размера приложения для Android (apk) Как вы можете справиться с увольнением DialogFragment (совместимость lib) после завершения AsyncTask Как установить onContextItemClickListener для контекстного меню ListView? Проблема с бесконечным бесконечным прокруткой RecyclerView WifiDirectActivity Изменение образца: Перенесите ArrayList <String> p2p Ошибка преобразования URI в Bitmap (2014): ANR сбой через несколько секунд при остановке в точке останова в основной нити (поле AOSP – RK3288)