12

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)

onResume 中にコンテンツを要求するFragments内で2 つの を使用しています。ViewPagerリクエストの 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;
    }
}
4

3 に答える 3

2

次のインポート ステートメントを追加します。

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);
于 2016-01-25T11:33:46.073 に答える