Недавно я пытался изменить http на https, но результат не был столь радостным из-за частых тайм-аутов запросов после перехода на https, что вызвало у меня очень плохой пользовательский опыт; Мое текущее решение - использовать пул потоков для выполнения запросов синхронизации okhttp, что является нормальным для запросов http. Я хочу решение, спасибо!
первый шаг: init 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%; этот результат делает мое приложение очень недружелюбным, но я не уверен, почему это так, я надеюсь получить решение, спасибо