簡體   English   中英

ScheduledExecutorService 無法正常工作

[英]ScheduledExecutorService not working correctly

我正在使用 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。

有什么問題?

在構建 GUI 之前,讓您在控制台上進行預定的頁面檢索。

這是一個示例應用程序。 在半分鍾內,我們每五秒下載一個頁面並將其各個部分轉儲到控制台。

該演示使用根據JEP 321: HTTP Client添加到 Java 11 的HttpClient類。 此處顯示的網頁訪問代碼是從本文中復制的。

提示:始終優雅地關閉您的 executor 服務,因為即使您的應用程序結束,其線程池也可能無限期地繼續運行。

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.

經過更多的搜索,我找到了一種完全符合我想要的方法:

runOnUiThread(可運行可運行)

//scheduler.scheduleAtFixedRate(this::refresh, 0, 15, TimeUnit.SECONDS); ->

public void refresh() {
        Site.refreshData();
        runOnUiThread(() -> {
            ((TextView) findViewById(R.id.queueView)).setText("Total Entries: " + List.getList().size());
            LinearLayout listView = findViewById(R.id.linearLayout);
            listView.removeAllViews();
            for (Entry entry : List.getList()) {

                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);
            }
            Toast.makeText(getApplicationContext(), "Refreshed data and UI.", Toast.LENGTH_SHORT).show();
        });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM