当前位置: 首页 > 知识库问答 >
问题:

如何在UI线程中运行此类?

唐麒
2023-03-14

我有一个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环境中运行它时,它要么说UI线程不能从任何其他线程接触,要么它在类ScheduleTimer的方法中给了我null点异常。

我这样使用它:newscheduletimer(textView)。main(新字符串[]{“13.04.2015 13:59”,“13.04.2015 14:14”,“13.04.2015 14:15”})

我尝试使用AsyncTask或处理程序,但可能没有正确执行。无论如何,我需要找到使用这个类更新我的文本视图的方法。

有人能帮我吗?如何在我的onCreateView方法中正常运行它,并正确传递所需的文本视图?


共有3个答案

微生昌勋
2023-03-14

Async任务的框架是:

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]);
        }


    }
宋腾
2023-03-14

完整的答案是:你的片段:

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);
    }
}
冯星阑
2023-03-14

runOnUiThread()方法将发送您的Runnable以在主线程上执行。在run()中,您可以操作UI控件:

@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());
          }
     });
 }

查看此项了解更多解释。

 类似资料:
  • 在Android上有没有办法知道,如果运行我的代码的线程,是UI线程还是不是?在swing中,有来告诉我是否在UI线程上。安卓SDK里有什么功能让我知道这一点吗?

  • 在UI线程中运行代码的观点中,以下两者之间有什么区别吗: 或 而且

  • 问题内容: 我有一个正在运行的线程,但是从外面我无法绕过一个值来停止该线程。如何在内部发送false / true值或调用运行线程的公共方法?当我按下按钮1?例如: 或 跟进(校对): 问题答案: 如果您通过类而不是通过a定义它,则可以调用实例方法。 还要注意,由于多个内核具有自己的关联内存,因此您需要警告处理器该状态可能在另一个处理器上更改,并且它需要监视该更改。听起来很复杂,但只需将’vola

  • 问题内容: 目的是能够从 主类中* 调用 单独线程的 执行。 * 一些上下文:我有一个必须运行 进程的程序 。仅当主程序执行完毕并从内存中卸载时,该进程 (一个cmd程序)才 应运行。 我应该在 主类中 包括哪些代码? 问题答案: 如果您的意思是: 如何启动一个Java线程,当我的JVM(Java程序)运行时,该线程不会结束? 。 因为在Java中,如果JVM退出,则所有线程均已完成。这是一个例子

  • 问题内容: 据我所知,在android中,当我们运行进程时,它们始于Main线程。当我们做一些繁重的工作时,我们使用了一个新线程。如果我们想修改UI外观,可以使用在UI上运行。 有人可以向我解释这些线程的作用以及如何使用它们吗? 问题答案: UI线程和主线程只是同一线程的不同名称。 应用程序的所有UI膨胀都在此主线程上完成。之所以将“较重”的工作委派给其他线程,是因为我们不希望这些操作减慢UI的响