首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么onSuceeded(.)方法在JavaFX中不是第一次调用吗?

为什么onSuceeded(.)方法在JavaFX中不是第一次调用吗?
EN

Stack Overflow用户
提问于 2018-11-10 09:11:07
回答 1查看 205关注 0票数 0

我正在尝试从服务器加载数据。然后通过JavaFX视图显示加载的数据。我使用一个服务来执行网络操作,为此我使用Apache HttpClients。最初,我认为这个bug与网络有关。我做了一些穴居风格的调试,并意识到这个bug与服务相关。奇怪的是,当第二个方法运行时,服务调用onSucceeded()方法(不同的实例,我没有重新启动服务)。我无法理解为什么服务第二次调用onSucceeded()方法。

下面是我为执行网络操作而实现的服务类。

代码语言:javascript
复制
public class HttpClientService extends Service<String> {

    private static final String TAG = HttpClientService.class.getName();
    private static final Logger logger = Logger.getLogger(TAG);

    private ObjectProperty<URL> url = new SimpleObjectProperty<>();
    private ObservableList<NameValuePair> parameters = FXCollections.observableArrayList();

    public HttpClientService(String url, Map<String, String> map) throws MalformedURLException {
        setUrl(new URL(url));
        for (String name : map.keySet()) {
            String value = map.get(name);
            parameters.add(new BasicNameValuePair(name, value));
        }
    }

    public HttpClientService(String url, NameValuePair ... parameters) throws MalformedURLException {
        setUrl(new URL(url));
        getParameters().addAll(parameters);
    }

    public HttpClientService(URL url, NameValuePair ... parameters) {
        setUrl(url);
        getParameters().addAll(parameters);
    }

    protected Task<String> createTask() {
        return new HttpClientTask(getUrl(), getParameters());
    }

    public URL getUrl() {
        return url.get();
    }

    public ObjectProperty<URL> urlProperty() {
        return url;
    }

    public void setUrl(URL url) {
        this.url.set(url);
    }

    public ObservableList<NameValuePair> getParameters() {
        return parameters;
    }

    public void setParameters(ObservableList<NameValuePair> parameters) {
        this.parameters = parameters;
    }

    @Override
    protected void succeeded() {
        System.out.println("## Successful...");
    }

    @Override
    protected void failed() {
        Throwable exception = getException();

        System.out.println("Error: Failed to download guest profiles.");
        exception.printStackTrace();
    }

    @Override
    protected void cancelled() {
        System.out.println("HttpClientService was stopped.");
    }

    @Override
    protected void running() {
        logger.log(Level.INFO, "Running service...");
    }
}

下面是调用服务并将数据注入视图的方法。

代码语言:javascript
复制
private void loadBlocks() {
    try {
        // TODO: Get the property identifier and set!
        Integer propertyIdentifier = 1;

        Map<String, String> parameters = new HashMap<>();
        parameters.put("property", propertyIdentifier.toString());

        HttpClientService service = new HttpClientService(UrlPath.ADMINISTRATION_PROPERTY_BLOCK_LIST_ALL, parameters);
        service.setOnSucceeded(workerStateEvent -> {
            logger.log(Level.INFO, "Successfully loaded blocks");

            try {
                String result = (String)workerStateEvent.getSource().getValue();
                logger.log(Level.INFO, result);

                List<Block> blocks = mapper.readValue(result, new TypeReference<ArrayList<Block>>(){});

                ObservableList<Block> items = blocksTableView.getItems();
                items.clear();
                items.addAll(blocks);

                NotificationHelper.postNotification(eventBus, "Successfully loaded blocks", 500);
            }
            catch (IOException exception) {
                exception.printStackTrace();
            }
        });
        service.stateProperty().addListener((observableValue, state, t1) -> System.out.println(t1));
        service.start();
    }
    catch (MalformedURLException exception) {
        exception.printStackTrace();
    }
}

这是应用程序的日志。

代码语言:javascript
复制
SCHEDULED
RUNNING
Nov 10, 2018 2:28:26 PM com.onecube.pms.client.service.HttpClientService running
INFO: Running service...
Nov 10, 2018 2:28:26 PM com.onecube.pms.client.task.HttpClientTask call
INFO: [Content-Type: application/x-www-form-urlencoded,Content-Length: 10,Chunked: false]
14:28:26.778 [Thread-3] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default
14:28:26.794 [Thread-3] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
14:28:26.796 [Thread-3] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 100; total allocated: 0 of 200]
14:28:26.809 [Thread-3] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 100; total allocated: 1 of 200]
14:28:26.810 [Thread-3] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->http://localhost:8080
14:28:26.829 [Thread-3] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to localhost/127.0.0.1:8080
14:28:26.830 [Thread-3] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:63671<->127.0.0.1:8080
14:28:26.831 [Thread-3] DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /administration/property/block/listAll HTTP/1.1
14:28:26.831 [Thread-3] DEBUG org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
14:28:26.834 [Thread-3] DEBUG org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> POST /administration/property/block/listAll HTTP/1.1
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Length: 10
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> Content-Type: application/x-www-form-urlencoded
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> Host: localhost:8080
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> Connection: Keep-Alive
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.6 (Java/11.0.1)
14:28:26.836 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "POST /administration/property/block/listAll HTTP/1.1[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Length: 10[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "Content-Type: application/x-www-form-urlencoded[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "Host: localhost:8080[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.6 (Java/11.0.1)[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
14:28:26.837 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "[\r][\n]"
14:28:26.838 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 >> "property=1"
14:28:26.845 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "HTTP/1.1 200 [\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "Content-Type: application/json;charset=UTF-8[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "Transfer-Encoding: chunked[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "Date: Sat, 10 Nov 2018 08:58:26 GMT[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "2[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "[][\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "0[\r][\n]"
14:28:26.846 [Thread-3] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
14:28:26.850 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 200 
14:28:26.850 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 << Content-Type: application/json;charset=UTF-8
java.lang.Throwable
    at com.onecube.pms.client.task.HttpClientTask.call(HttpClientTask.java:81)
    at com.onecube.pms.client.task.HttpClientTask.call(HttpClientTask.java:32)
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1425)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at javafx.concurrent.Service.lambda$executeTask$6(Service.java:725)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.concurrent.Service.lambda$executeTask$7(Service.java:724)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
14:28:26.850 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 << Transfer-Encoding: chunked
14:28:26.850 [Thread-3] DEBUG org.apache.http.headers - http-outgoing-0 << Date: Sat, 10 Nov 2018 08:58:26 GMT
14:28:26.856 [Thread-3] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely
14:28:26.860 [Thread-3] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://localhost:8080] can be kept alive indefinitely
14:28:26.861 [Thread-3] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0
14:28:26.861 [Thread-3] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 100; total allocated: 1 of 200]
SCHEDULED
RUNNING
Nov 10, 2018 2:28:43 PM com.onecube.pms.client.service.HttpClientService running
INFO: Running service...
Nov 10, 2018 2:28:43 PM com.onecube.pms.client.task.HttpClientTask call
INFO: [Content-Type: application/x-www-form-urlencoded,Content-Length: 10,Chunked: false]
14:28:43.429 [Thread-4] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default
14:28:43.430 [Thread-4] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
14:28:43.431 [Thread-4] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 100; total allocated: 0 of 200]
14:28:43.431 [Thread-4] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 1][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 100; total allocated: 1 of 200]
14:28:43.431 [Thread-4] DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->http://localhost:8080
14:28:43.431 [Thread-4] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to localhost/127.0.0.1:8080
14:28:43.432 [Thread-4] DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:63675<->127.0.0.1:8080
14:28:43.432 [Thread-4] DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /administration/property/block/listAll HTTP/1.1
14:28:43.432 [Thread-4] DEBUG org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
14:28:43.433 [Thread-4] DEBUG org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
14:28:43.433 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> POST /administration/property/block/listAll HTTP/1.1
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> Content-Length: 10
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> Content-Type: application/x-www-form-urlencoded
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> Host: localhost:8080
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> Connection: Keep-Alive
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> User-Agent: Apache-HttpClient/4.5.6 (Java/11.0.1)
14:28:43.434 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 >> Accept-Encoding: gzip,deflate
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "POST /administration/property/block/listAll HTTP/1.1[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "Content-Length: 10[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "Content-Type: application/x-www-form-urlencoded[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "Host: localhost:8080[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "Connection: Keep-Alive[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "User-Agent: Apache-HttpClient/4.5.6 (Java/11.0.1)[\r][\n]"
14:28:43.434 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "Accept-Encoding: gzip,deflate[\r][\n]"
14:28:43.435 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "[\r][\n]"
14:28:43.435 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 >> "property=1"
java.lang.Throwable
    at com.onecube.pms.client.task.HttpClientTask.call(HttpClientTask.java:81)
    at com.onecube.pms.client.task.HttpClientTask.call(HttpClientTask.java:32)
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1425)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at javafx.concurrent.Service.lambda$executeTask$6(Service.java:725)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.concurrent.Service.lambda$executeTask$7(Service.java:724)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Nov 10, 2018 2:28:43 PM com.onecube.pms.client.controller.administration.room.ManageBlocksController lambda$loadBlocks$2
INFO: Successfully loaded blocks
Nov 10, 2018 2:28:43 PM com.onecube.pms.client.controller.administration.room.ManageBlocksController lambda$loadBlocks$2
INFO: []
14:28:43.444 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "HTTP/1.1 200 [\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "Content-Type: application/json;charset=UTF-8[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "Transfer-Encoding: chunked[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "Date: Sat, 10 Nov 2018 08:58:43 GMT[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "2[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "[][\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "0[\r][\n]"
14:28:43.449 [Thread-4] DEBUG org.apache.http.wire - http-outgoing-1 << "[\r][\n]"
14:28:43.450 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 << HTTP/1.1 200 
14:28:43.450 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 << Content-Type: application/json;charset=UTF-8
14:28:43.450 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 << Transfer-Encoding: chunked
14:28:43.451 [Thread-4] DEBUG org.apache.http.headers - http-outgoing-1 << Date: Sat, 10 Nov 2018 08:58:43 GMT
14:28:43.452 [Thread-4] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely
14:28:43.453 [Thread-4] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 1][route: {}->http://localhost:8080] can be kept alive indefinitely
14:28:43.453 [Thread-4] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-1: set socket timeout to 0
14:28:43.453 [Thread-4] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 1][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 100; total allocated: 1 of 200]
## Successful...
SUCCEEDED
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-11 04:18:57

从您向我们展示的内容来看,您的代码在任何地方都不包含对HttpClientService的强烈引用。这让我相信,在HttpClientService完成https://stackoverflow.com/questions/3798424/what-is-the-garbage-collector-in-java之前,它就是https://stackoverflow.com/questions/3798424/what-is-the-garbage-collector-in-java。一些快速测试证实这是可能的。事实上,文档对此特别提出了警告:

一旦服务启动,它将安排其任务并侦听对任务状态的更改。任务不包含对启动它的服务的引用,这意味着正在运行的任务不会阻止服务被垃圾收集。

要解决这个问题,您需要保持对HttpClientService实例的强大引用。这可以通过将其存储在loadBlocks()所属的类中(假设所述类的实例也被强烈引用)来实现。然后,当服务终止时,您可以删除该引用(因为您目前没有重用该服务)。另一种解决方案是直接使用HttpClientTask,并且只在准备就绪时使用HttpClientService实现。

注意,HttpClientTask不是垃圾收集的。这是因为它可以从执行它的Thread中获得。因此,您的后台任务正常完成,但不再有一个HttpClientService通知您。

此外,您第一次运行此代码时与以后的任何时间没有区别。它适用于第二次调用,这只是运气。每次调用此方法时,HttpClientService都要进行垃圾收集;但是,不能保证垃圾收集周期会运行,这意味着您会时不时地得到幸运。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53237510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档