首页 > 解决方案 > ScheduledExecutorService 无法正常工作

问题描述

我使用 ScheduledExecutorService 每 15 秒从网站获取数据:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(this::refresh, 0, 15, TimeUnit.SECONDS);

这是每 15 秒调用一次的方法:

public void refresh() {
        Site.refreshData();
        System.out.println("Refreshed Data");
        LinearLayout listView = findViewById(R.id.linearLayout);
        System.out.println("Size: " + List.getList().size());
        for (int i = 0; i < List.getList().size(); i++) {
            Entry entry = List.getList().get(i);

            CardView cardView = (CardView) LayoutInflater.from(
                    getApplicationContext()).inflate(R.layout.card, listView, false);

            ImageView checkedView = (ImageView) cardView.getChildAt(0);
            checkedView.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(),
                    entry.isChecked() ? R.drawable.check : R.drawable.cross));

            TextView name = (TextView) cardView.getChildAt(1);
            name.setText(entry.getName());

            TextView comment = (TextView) cardView.getChildAt(2);
            comment.setText(entry.getComment());

            listView.addView(cardView, i);
        }
        System.out.println("Added Cardviews");
        listView.invalidate();
        System.out.println("Refreshed LinearLayout");
    }

我添加了多个打印,作为一个穷人调试器,我只到达打印 ArrayList 大小的地步。从那里开始没有任何东西被打印出来,就像执行停止一样。我确定错误发生在 for 循环内。我已经通过添加打印进行了检查,它显示了当前的i并且它刚刚停止在 4,即使列表大小是 57。

有什么问题?

标签: javaandroidandroid-cardviewandroid-scrollviewscheduledexecutorservice

解决方案


在构建 GUI 之前,让您计划的页面检索在控制台上工作。

这是一个执行此操作的示例应用程序。每五秒半分钟,我们下载一个页面并将其各个部分转储到控制台。

此演示使用HttpClient根据 JEP 321 添加到 Java 11 的类:HTTP 客户端。此处显示的网页访问代码是从本文复制而来的。

提示:始终优雅地关闭您的执行器服务,因为它的线程池可能会在您的应用程序结束后继续无限期地运行。

package work.basil.example;

import java.io.IOException;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class PageFetch
{
    public static void main ( String[] args )
    {
        PageFetch app = new PageFetch();
        app.demo();
    }

    private void demo ( )
    {
        Runnable pageFetchRunnable = ( ) -> { this.fetchPage(); };

        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate( pageFetchRunnable , 1 , 5 , TimeUnit.SECONDS );  // Wait one second, then every five seconds.

        try
        {
            Thread.sleep( Duration.ofSeconds( 30 ).toMillis() );  // Let the executor service do its thing for a half-minute, then shut it down.
        }
        catch ( InterruptedException e )
        {
            e.printStackTrace();
        }
        finally
        {
            scheduledExecutorService.shutdown();
        }
    }

    private void fetchPage ( )
    {
        // Example code for using `HttpClient` framework of Java 11 taken from this article:
        // https://mkyong.com/java/java-11-httpclient-examples/

        HttpClient httpClient = HttpClient.newBuilder()
                .version( HttpClient.Version.HTTP_2 )
                .followRedirects( HttpClient.Redirect.NORMAL )
                .connectTimeout( Duration.ofSeconds( 20 ) )
//                .proxy( ProxySelector.of(new InetSocketAddress("proxy.yourcompany.com", 80)))
//                .authenticator( Authenticator.getDefault())
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .GET()
                .uri( URI.create( "https://httpbin.org/get" ) )
                .setHeader( "User-Agent" , "Java 11 HttpClient Bot" ) // add request header
                .build();

        HttpResponse < String > response = null;
        try
        {
            System.out.println( "\n-----|  Demo  |-------------------------------------------" );
            System.out.println( "INFO - Access attempt at " + Instant.now() );
            response = httpClient.send( request , HttpResponse.BodyHandlers.ofString() );
            // print response headers
            HttpHeaders headers = response.headers();
            headers.map().forEach( ( k , v ) -> System.out.println( k + ":" + v ) );

            // print status code
            System.out.println( response.statusCode() );

            // print response body
            System.out.println( response.body() );
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
        catch ( InterruptedException e )
        {
            e.printStackTrace();
        }
    }
}

运行时:

-----|  Demo  |-------------------------------------------
INFO - Access attempt at 2020-11-20T21:54:37.905896Z
:status:[200]
access-control-allow-credentials:[true]
access-control-allow-origin:[*]
content-length:[242]
content-type:[application/json]
date:[Fri, 20 Nov 2020 21:54:38 GMT]
server:[gunicorn/19.9.0]
200
{
  "args": {}, 
  "headers": {
    "Host": "httpbin.org", 
    "User-Agent": "Java 11 HttpClient Bot", 
    "X-Amzn-Trace-Id": "Root=1-5fb83b1e-7a6acb893aec6fb310984adb"
  }, 
  "origin": "76.22.40.96", 
  "url": "https://httpbin.org/get"
}



-----|  Demo  |-------------------------------------------
INFO - Access attempt at 2020-11-20T21:54:42.907678Z
:status:[200]
access-control-allow-credentials:[true]
access-control-allow-origin:[*]
content-length:[242]
content-type:[application/json]
date:[Fri, 20 Nov 2020 21:54:43 GMT]
server:[gunicorn/19.9.0]
200
{
  "args": {}, 
  "headers": {
    "Host": "httpbin.org", 
    "User-Agent": "Java 11 HttpClient Bot", 
    "X-Amzn-Trace-Id": "Root=1-5fb83b23-3dbb566f5d58a8a367e0e528"
  }, 
  "origin": "76.22.40.96", 
  "url": "https://httpbin.org/get"
}

… and so on for a half-minute.

推荐阅读