seh*_*ugg 12 android apache-httpclient-4.x
我正在使用HttpClient进行HTTPS请求,到目前为止一直运行良好.升级到ICS后,一些用户报告连接3G连接时出现问题.
编辑:他们中的大多数似乎使用代理,我可以使用他们的代理在本地使用T-Mobile SIM重现.
日志具有此堆栈跟踪:
java.lang.IllegalStateException: Scheme 'http' not registered.
org.apache.http.conn.scheme.SchemeRegistry.getScheme(SchemeRegistry.java:80)
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:126)
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
Run Code Online (Sandbox Code Playgroud)
我们的端点仅限HTTPS,因此我们不会故意在SchemeRegistry中注册HTTP端点.我们没有任何地方(AFAIK)重定向到HTTP.
以下是为HTTPS客户端设置HttpClient的代码:
DefaultHttpClient ret = null;
// sets up parameters
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "utf-8");
params.setBooleanParameter("http.protocol.expect-continue", false);
HttpConnectionParams.setConnectionTimeout(params, DEFAULT_CONN_TIMEOUT_MSEC);
HttpConnectionParams.setSoTimeout(params, timeoutMsec);
HttpConnectionParams.setStaleCheckingEnabled(params, true);
SchemeRegistry registry = new SchemeRegistry();
final SocketFactory sslSocketFactory = getPreferredSSLSocketFactory();
registry.register(new Scheme("https", sslSocketFactory, 443));
ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
ret = new DefaultHttpClient(manager, params);
// for preemptive authentication
// http://dlinsin.blogspot.com/2009/08/http-basic-authentication-with-android.html
ret.addRequestInterceptor(preemptiveAuth, 0);
ret.setCookieStore(communalCookieJar);
SimpleCredentialsProvider credProvider = new SimpleCredentialsProvider(getAccountPreferences());
ret.setCredentialsProvider(credProvider);
return ret;
Run Code Online (Sandbox Code Playgroud)
注意:我们在多个线程之间共享此HttpClient实例.
从您的堆栈跟踪,我建议您注册(http,https)并查看是否不起作用.
您应该能够通过包含apache源jar来调试它 - 向下钻取trace @ SchemeRegistry.getScheme().
这个帖子可能有帮助.
下面在ICS上测试OK ...在androidhttpclient libs 上示例SSL ConnectionMgr :
static X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
MyConnectionManager(SchemeRegistry scheme){
super(scheme);
}
public static MyConnectionManager getInstance() {
if (instance == null){
SSLContext ctx=null;
try {
ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{tm}, null);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register( new Scheme("http", 80,PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
instance = new MyConnectionManager(schemeRegistry);
// Increase max total connection to 200
instance.setMaxTotal(15);
// Increase default max connection per route to 20
instance.setDefaultMaxPerRoute(15);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("picasaweb.google.com", 443);
instance.setMaxForRoute(new HttpRoute(localhost), 10);
}
return instance;
}
Run Code Online (Sandbox Code Playgroud)
问题似乎是一些运营商在 4.0.4 更新中推送了无效的代理定义。这破坏了 HTTPS,但 HTTP 工作正常(例如,Google Play 无法工作)。
一种可能的修复(除了修复无效的代理条目之外)是在执行 HttpClient 请求时捕获 IllegalStateException 并设置一个标志。此代码将绕过任何代理:
hc = new DefaultHttpClient(manager, params);
if (BYPASS_PROXY)
hc.setRoutePlanner(new DefaultHttpRoutePlanner(registry));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14691 次 |
| 最近记录: |