Android HttpUrlConnection w持久连接

时间:2016-02-02 03:11:14

标签: android httpurlconnection persistent-connection

方案

用户必须使用此应用登录服务器。稍后在应用程序中,我们需要检查他们对服务器的登录状态。我们过去通过跟踪上次使用的HttpClient来做到这一点。最近我们切换到HttpUrlConnection,但所谓的持久连接无效。

问题

我写了这个测试应用程序,看看连接是否持久。我从这两个URL中获取了xml,但连接的行为并不像它一致。我怎样才能让它发挥作用?

注意:如果您在浏览器中转到登录网址,然后在同一浏览器中转到GetUserInfo网址,则一切正常。

MainActivity.java

package com.mediajackagency.test;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    public Button signInBtn = null;
    public Button getUserInfoBtn = null;
    public TextView xmlTextView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        this.xmlTextView = (TextView)findViewById(R.id.xmlTxtView);

        this.signInBtn = (Button)findViewById(R.id.signInBtn);
        this.signInBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTask task = new AsyncTask() {
                    @Override
                    protected Object doInBackground(Object[] params) {
                        String xml = loadUrl("https://www.fake.site/Login?userName=test&password=pass123");

                        return xml;
                    }

                    @Override
                    protected void onPostExecute(Object o) {
                        super.onPostExecute(o);
                        xmlTextView.setText(o.toString());
                    }
                };
                task.execute();
            }
        });

        this.getUserInfoBtn = (Button)findViewById(R.id.getUserInfoBtn);
        this.getUserInfoBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTask task = new AsyncTask() {
                    @Override
                    protected Object doInBackground(Object[] params) {
                        String xml = loadUrl("https://www.fake.site/GetCurrentUser");

                        return xml;
                    }

                    @Override
                    protected void onPostExecute(Object o) {
                        super.onPostExecute(o);
                        xmlTextView.setText(o.toString());
                    }
                };
                task.execute();
            }
        });
    }

    public String loadUrl(String url) {
        URI uri = MainActivity.encodeUrl(url);
        Log.i("XMLParser", "Get URL: " + url);

        String xml = null;
        URL link;
        BufferedReader reader = null;
        StringBuilder stringBuilder = null;
        InputStream is = null;
        HttpURLConnection connection = null;

        try {
            link = new URL(url);
            connection = (HttpURLConnection) link.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is));
            stringBuilder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null)
            {
                stringBuilder.append(line + "\r");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    if(reader != null) reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                try {
                    if(is != null) is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                try {
                    if(connection != null) connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            xml = stringBuilder.toString();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return xml;
    }

    public static URI encodeUrl(String url) {
        URL urlObject;
        URI uri = null;
        try {
            urlObject = new URL(url);
            uri = new URI(urlObject.getProtocol(), urlObject.getUserInfo(), urlObject.getHost(),
                    urlObject.getPort(), urlObject.getPath(), urlObject.getQuery(), urlObject.getRef());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return uri;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

1 个答案:

答案 0 :(得分:2)

使用Cookie解决

经过几天/几小时的工作后,我发现与http.keepalive的持久关联(HttpUrlConnection)并非全部被破解为:

1)您需要确保InputStreamHttpUrlConnection已关闭,然后才能重复使用连接,而即使也可能无法始终重复使用。

2)开放TCP连接可能是资源占用。

找到&测试using cookies with HttpUrlConnection的想法我决定走这条路,因为它的声音从根本上说比我原来的想法更好。