Повторно использовать HTTPS-соединения в Android? - PullRequest
0 голосов
/ 28 декабря 2011

У меня есть приложение, которое должно выполнить серию HTTPS-подключений к внутреннему серверу. Эти соединения происходят в ответ на пользовательский ввод, поэтому возможно повторное использование сеанса HTTS. Эксперименты на других платформах (iOS) показали, что этот подход может сократить время загрузки на несколько секунд. Тем не менее, я не нашел хорошего подхода для Android. Идеи?

Вот текущий подход, упрощенный, но все еще длительный. (К сожалению!)

public class ExampleActivity extends Activity {
static final String preconnectEndpoint; // value redacted -- pick your favorite https url.
static final String TAG = "HttpsReuseExampleActivity";

private Button startButton;
private TextView resultText;

private HttpClient httpClient; 

private void setupHttpClient(Context androidContext) {
    if (httpClient == null) {
        httpClient = AndroidHttpClient.newInstance("reusableHttpsConnectionExampleClient (Android/0.1)", androidContext);
        Log.i(TAG,"created httpClient" + httpClient.toString());

        SSLSessionCache sslSession = new SSLSessionCache(androidContext);
        SSLSocketFactory sslSocketFactory = SSLCertificateSocketFactory.getHttpSocketFactory(10*60*1000, sslSession);

        ClientConnectionManager cm = httpClient.getConnectionManager();
        Log.d(TAG, "ClientConnectionManager is: " + cm.toString());
        cm.getSchemeRegistry().register(new Scheme("https", sslSocketFactory, 443));
    }
}

    private class ConnectTask extends AsyncTask<Void, Void, String>{
    private HttpClient client;
    private long connectionStartTime;

    ConnectTask(HttpClient client) {
        this.client = client;
    }

    @Override 
    protected void onPreExecute() {
        Log.d(TAG, "beginning connection...");
        connectionStartTime = System.currentTimeMillis();
    }

    @Override
    protected String doInBackground(Void... arg0) {
        Log.d(TAG, "connecting with client: " + client.toString());

        try {
            HttpGet getRequest = new HttpGet(preconnectEndpoint);
            HttpResponse resp = client.execute(getRequest);
        } catch (Exception e) {
            Log.e(TAG,"failed to connect", e);
            return "connection failed";
        } 

        return String.format("connected after %d ms", System.currentTimeMillis() - connectionStartTime);
    }

    @Override
    protected void onPostExecute(String r) {
        Log.i(TAG,r);
        resultText.setText(r);
    }

};



/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    startButton = (Button) findViewById(R.id.startButton);
    resultText = (TextView) findViewById(R.id.resultText);

    setupHttpClient(this.getApplicationContext());

    startButton.setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            assert(httpClient != null);
            ConnectTask t = new ConnectTask(httpClient);
            t.execute();
        }
    });
}

1 Ответ

1 голос
/ 30 декабря 2011

Оказывается, что http://loopj.com/android-async-http/ обеспечивает хорошее решение, поскольку использует пул кэшированных потоков. AsyncTask, вероятно, может быть изменен / разделен на подклассы, чтобы сделать аналогичную вещь, но зачем заново изобретать колесо?

Поскольку соединение должно быть отменено при определенных условиях, я обнаружил, что мне нужны обновления, представленные в https://github.com/loopj/android-async-http/commit/c7745276853ecd2e3838655f3ef93e683e80723d

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...