【发布时间】:2018-12-04 21:01:04
【问题描述】:
我最近在尝试将http改成https,但是由于改成https后频繁的请求超时,结果并没有那么开心,这让我的用户体验非常糟糕;我目前的解决方案是使用线程池执行okhttp同步请求,这对于http请求来说是正常的。我想要一个解决方案,谢谢!
第一步:初始化okhttpclient
public static class MyHttpUtils{
private static MyHttpUtils myHttpUtils;
private OkHttpClient okHttpClient;
private MyHttpUtils(){
initClient();
}
private void initClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.writeTimeout(60_000, TimeUnit.MILLISECONDS);
builder.connectTimeout(60_000,TimeUnit.MILLISECONDS);
builder.readTimeout(60_000,TimeUnit.MILLISECONDS);
HttpsUtils httpsUtils = HttpsUtils.getInstance();
HttpsUtils.SSLParams sslParams = httpsUtils.getSslSocketFactory();
builder.sslSocketFactory(sslParams.sSLSocketFactory,sslParams.trustManager)
.hostnameVerifier(httpsUtils.hostnameVerifier());//check hostname
okHttpClient = builder.build();
}
public static MyHttpUtils getInstance(){
if(myHttpUtils == null){
synchronized (MyHttpUtils.class){
if(myHttpUtils == null){
myHttpUtils = new MyHttpUtils();
}
}
}
return myHttpUtils;
}
public OkHttpClient getOkHttpClient() {
return okHttpClient;
}
}
第二步:创建线程池
public static class ThreadPool{
private static ThreadPool threadPool = new ThreadPool();
private ExecutorService service = new ThreadPoolExecutor(0 /* corePoolSize */,
Integer.MAX_VALUE /* maximumPoolSize */, 60L /* keepAliveTime */, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp ConnectionPool", true));
public static ThreadPool getInstance(){
return threadPool;
}
public void execute(Runnable runnable){
service.execute(runnable);
}
}
第三步:创建Runnable
private Runnable createRunnable(){
return new Runnable() {
@Override
public void run() {
try {
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
requestBuilder.url(url).tag(this).build();
okhttp3.Request request = requestBuilder.build();
okhttp3.Response response = client.newCall(request).execute();
if(response.code() == 200){
synchronized (this){
successSum++;
}
Log.e(MainActivity.class.getSimpleName(),"success="+successSum);
Log.e("myResult","result="+response.body().string());
}else{
synchronized (this){
failSum++;
}
Log.e(MainActivity.class.getSimpleName(),"failSum="+failSum+"==code="+response.code());
}
} catch (IOException e) {
client.connectionPool().evictAll();
synchronized (this){
exceptionSum++;
}
Log.e(MainActivity.class.getSimpleName(),"exceptionSum="+exceptionSum+"==msg="+ e.toString());
}
}
};
}
第四步:发送请求
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_request:
successSum = 0;
failSum = 0;
exceptionSum = 0;
int i = 10;
while (i>0){
requestSync();
i--;
}
break;
}
}
方法:requestSync()
private void requestSync(){
ThreadPool.getInstance().execute(createRunnable());
}
最终结果:发生SocketTimeoutException
我在测试的时候使用了样本数据,请求成功率在60%左右;这个结果让我的应用很不友好,但是不知道为什么会这样,希望能得到解决,谢谢
【问题讨论】:
标签: java https okhttp socket-timeout-exception