4

我可以认为代码run将在新线程中执行还是我必须使用AsyncTask

Timer myTimer = new Timer(); // Создаем таймер
        final Handler uiHandler = new Handler();
        myTimer.schedule(new TimerTask() { // Определяем задачу
            @Override
            public void run() {
                uiHandler.post(new Runnable() {
                    @Override
                    public void run() {

                    }
                });
            }

            ;
        }, 0L, 10L * 1000); // интервал - 10000 миллисекунд, 0 миллисекунд до первого запуска.

更新

我在这段代码中有一个错误:

Timer myTimer = new Timer();
        final Handler uiHandler = new Handler();
        myTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                while (songRefreshing) {
                    uiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                HttpClient httpclient = new DefaultHttpClient();
                                HttpResponse response = null;
                                response = httpclient.execute(new HttpGet(Const.php_url));
                                StatusLine statusLine = response.getStatusLine();
                                if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                                    response.getEntity().writeTo(out);
                                    out.close();
                                    String responseString = out.toString();
                                    if (app.getCurSong() == null || app.getCurSong().intern() != responseString.intern()) {
                                        app.setCurSong(responseString);
                                        song_name.setText(app.getCurSong());
                                        Log.d(LOG_TAG, "refreshCurSung - " + responseString);
                                    }
                                } else {
                                    response.getEntity().getContent().close();
                                    throw new IOException(statusLine.getReasonPhrase());
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                                Log.d(LOG_TAG, e.toString());
                            }
                        }
                    });
                }
            }

            ;
        }, 0L, 10L * 1000); // 10s interval

错误:

android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1178)
    at java.net.InetAddress.lookupHostByName(InetAddress.java:394)
    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:245)
    at java.net.InetAddress.getAllByName(InetAddress.java:220)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:590)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:510)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:488)

这是否意味着 TimerTask 不在新线程中执行?

4

1 回答 1

5

要直接回答您的问题,请从此处引用:

类概述

计时器安排一次性或重复执行的任务。对于新代码,首选 ScheduledThreadPoolExecutor。

每个计时器都有一个线程,任务在其上按顺序执行。当该线程忙于运行任务时,可运行的任务可能会出现延迟。

One-shot 计划在绝对时间或相对延迟后运行。

定期任务以固定周期或固定速率安排:

使用默认的固定周期执行,任务的每次连续运行都是相对于前一次运行的开始时间安排的,因此两个运行永远不会在时间上比指定的周期更接近。使用固定速率执行,任务的每次连续运行的开始时间都会被安排,而不考虑上一次运行发生的时间。如果延迟阻止计时器按时启动任务,这可能会导致一系列聚集运行(一个接一个地立即启动)。当不再需要定时器时,用户应该调用 cancel(),它会释放定时器的线程和其他资源。未明确取消的计时器可能会无限期地持有资源。

此类不保证任务调度的实时性。多个线程可以共享一个定时器而不需要同步。

所以,是的,它是一个线程。

更新(在问题更新之后):

当前的实现可能包含很多缺陷,这就是为什么我建议您将代码Runnable放在一个中AsyncTask(并将整个一堆代码放在doInBackground方法中)。在那里您可以轻松控制它。

此外,我认为两次一个内另一个可能会导致您陷入僵局或其他什么@Overridingrun()由于TimerTask它实际上是一个线程,所以我认为你不需要一个单独Runnable的内部。

首先删除 的实现并尝试在其内部Runnable启动(不带)。如果您无法做到这一点,那么将代码(如建议的那样)放在一个(无论如何您都会有一个更漂亮的实现)。TimerTaskHttpClientRunnableAsyncTask

谢谢

于 2013-09-12T08:24:22.493 回答