I have an application I've writ开发者_高级运维ten that works perfectly in the simulator. When I put it on a device however it does not.
It does one HttpRequest to get and parse all the xml containing all the urls of the thumbnails I want to download. Once all of that is done and the thread is closed, it will create a new thread which loops through all the url's and requests/downloads the thumbnails (7 at a time for each XML request). It works fine for the first 14-28 downloads, then one or two will fail. My question here is, how can I get the code:
_connFact.setAttemptsLimit(2);
_connFact.setRetryFactor(500);
_connFact.setTimeLimit(500);
_connFact.setConnectionTimeout(2000);
_connFact.setTimeoutSupported(true);
//Hangs on the line below for 2-5 minutes on the ones that it failed to download
//trans[i] is just a list of Transports that I've prechecked for coverage and availability
for (int i = 0; i < trans.length; i++){
_httpsConn = (HttpsConnection)_connFact.getConnection(URLFactory.EncodeUrl(trans[i], _url), trans[i], null).getConnection();
if (_httpsConn != null){
break;
}
}
to just die if it fails to connect. I'd rather have the app continue and display a broken thumbnail then hang for the 2+ minutes per failure it does now.
After a week of research:
An HttpConnection as most know is blocking. When doing many HttpRequests one after another the blackberry has trouble handling it. Eventually one will fail. This is a problem because ConnectionTimeout=Value flag is only supported with MDS / BES connections. Thus the connection does not time out and continues blocking. Unfortunatly this also blocks other applications (including browser etc) from working as well. The default timeout is 1 day, which means, the only way to fix this is to recycle the radio.
Thus the proper way to do many HttpRequests simultaneously is to use a NonBlockingSenderDestination with an application connection factory context like so and implement a separate MessageListener:
_factory = new ConnectionFactory();
_factory.setAttemptsLimit(3);
if (DeviceInfo.isSimulator()) {
_factory.setPreferredTransportTypes(new int[] { TransportInfo.TRANSPORT_TCP_WIFI,
TransportInfo.TRANSPORT_TCP_CELLULAR });
}
_context = new Context("yourappname", _factory);
NonBlockingSenderDestination destination = DestinationFactory.createNonBlockingSenderDestination(_context,
URI.create(url), this);
destination.send();
This is the proper way to do it because you cannot abandon a conventional HttpConnection unless it is an MDS connection. This then, allows the OS to handle it and the application listens for a response. If no response is forthcoming, then it was abandoned by the OS.
精彩评论