AndroidでVolleyを使用してアプリリクエストを実行しています。残念ながら、次のエラーが発生します:
com.Android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x61e15f78: Failure in SSL library, usually a protocol error
error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5b647c58:0x00000000)
Fragments
内で2つのViewPager
を使用しており、onResume中にコンテンツをリクエストします。リクエストのURLは基本的に同じですが、クエリパラメータ(コンテンツのタイプを設定します(トレンドとホットなど))。
URLはhttps://Host/api/content?type={hot/trending}
の形式です。承認はリクエストヘッダーを介して行われます。
この例外の奇妙な部分は、2つの要求のうち1つだけが失敗し、どちらが時々変わるかということです。それらの間に遅延を追加した後、例外は発生しなくなりました(奇妙なことに何らかの競合状態を示していますか?)。しかし、これは悪い回避策のようであり、私はこれを正しい方法で解決したいと思います。
それの原因は何であるかについて何か考えはありますか?
編集:
リクエストは、次のように、キューを提供するシングルトンを使用して、標準的な方法で作成されます。
final RequestQueue requestQueue = RequestQueueSingleton.getInstance(getActivity()).getRequestQueue();
final GsonRequestGet<SearchApiWrapper> gsonRequest = new GsonRequestGet<>(clazz, url,successListener, errorListener);
gsonRequest.setRetryPolicy(new DefaultRetryPolicy(3000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
gsonRequest.setTag(mTag);
requestQueue.add(gsonRequest);
そして、これがシングルトンクラスです。
public class RequestQueueSingleton {
private static RequestQueueSingleton mInstance;
private RequestQueue mRequestQueue;
private Context mContext;
public RequestQueueSingleton(Context context) {
mContext = context;
mRequestQueue = getRequestQueue();
}
/**
* Returns a instance of this singleton
*/
public static synchronized RequestQueueSingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new RequestQueueSingleton(context);
}
return mInstance;
}
/**
* Returns instance of the request queue
*/
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
return mRequestQueue;
}
}
私たちのコメントの後、多分これはあなたを助けることができます:
あなたのrequestQueue
:
static {
requestQueue = Volley.newRequestQueue(Application.getContext(), new HurlStack(null, ClientSSLSocketFactory.getSocketFactory()));
}
ClientSSLSocketFactory
:
public class ClientSSLSocketFactory extends SSLCertificateSocketFactory {
private SSLContext sslContext;
public static SSLSocketFactory getSocketFactory(){
try
{
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;
}
};
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = ClientSSLSocketFactory.getDefault(10000, new SSLSessionCache(Application.getInstance()));
return ssf;
} catch (Exception ex) {
return null;
}
}
@Override
public Socket createSocket(Socket socket, String Host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, Host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
次のインポートステートメントを追加します。
import javax.net.ssl.TrustManager;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import Java.security.cert.X509Certificate;
import Java.util.ResourceBundle;
そしてネットワーク呼び出しを行う前に次のコードを追加します。
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sc.init(null, trustAllCerts, new Java.security.SecureRandom());
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting Host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting Host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);