在Android中重用HTTPS连接?

时间:2011-12-27 23:27:48

标签: android https android-asynctask

我有一个应用需要与后端服务器建立一系列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 个答案:

答案 0 :(得分:1)

事实证明http://loopj.com/android-async-http/提供了一个很好的解决方案,因为它使用了缓存的线程池。 AsyncTask可能会被修改/子类化以做类似的事情,但为什么要重新发明轮子?

由于必须在某些条件下取消连接,我发现我需要https://github.com/loopj/android-async-http/commit/c7745276853ecd2e3838655f3ef93e683e80723d

中提供的更新