使用 Android HttpURLConnection 获取 Http

Posted

技术标签:

【中文标题】使用 Android HttpURLConnection 获取 Http【英文标题】:Http Get using Android HttpURLConnection 【发布时间】:2012-01-29 02:31:15 【问题描述】:

我是 Java 和 android 开发的新手,我尝试创建一个简单的应用程序,该应用程序应该联系 Web 服务器并使用 http get 将一些数据添加到数据库中。

当我使用计算机中的网络浏览器拨打电话时,它工作得很好。但是,当我在 Android 模拟器中运行应用程序时,不会添加任何数据。

我已将 Internet 权限添加到应用的清单中。 Logcat 没有报告任何问题。

谁能帮我找出问题所在?

这里是源代码:

package com.example.httptest;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class HttpTestActivity extends Activity 
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        TextView tv = new TextView(this);
        setContentView(tv);

        try 
            URL url = new URL("http://www.mysite.se/index.asp?data=99");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.disconnect();
            tv.setText("Hello!");
        
        catch (MalformedURLException ex) 
            Log.e("httptest",Log.getStackTraceString(ex)); 
        
        catch (IOException ex) 
            Log.e("httptest",Log.getStackTraceString(ex));
           
            

【问题讨论】:

【参考方案1】:

使用 Tasks 和 Kotlin 在单独的线程上执行此操作的更现代方式

private val mExecutor: Executor = Executors.newSingleThreadExecutor()

private fun createHttpTask(u:String): Task<String> 
    return Tasks.call(mExecutor, Callable<String>
        val url = URL(u)
        val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
        conn.requestMethod = "GET"
        conn.connectTimeout = 3000
        conn.readTimeout = 3000
        val rc = conn.responseCode
        if ( rc != HttpURLConnection.HTTP_OK) 
            throw java.lang.Exception("Error: $rc")
        
        val inp: InputStream = BufferedInputStream(conn.inputStream)
        val resp: String = inp.bufferedReader(UTF_8).use it.readText() 
        return@Callable resp
    )

现在你可以在很多地方像下面这样使用它:

            createHttpTask("https://google.com")
                    .addOnSuccessListener 
                        Log.d("HTTP", "Response: $it") // 'it' is a response string here
                    
                    .addOnFailureListener 
                        Log.d("HTTP", "Error: $it.message") // 'it' is an Exception object here
                    

【讨论】:

【参考方案2】:

简单高效的解决方案:使用Volley

 StringRequest stringRequest = new StringRequest(Request.Method.GET, finalUrl ,
           new Response.Listener<String>() 
                    @Override
                    public void onResponse(String)
                        try 
                            JSONObject jsonObject = new JSONObject(response);
                            HashMap<String, Object> responseHashMap = new HashMap<>(Utility.toMap(jsonObject)) ;
                         catch (JSONException e) 
                            e.printStackTrace();
                        
                    
                , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 
                Log.d("api", error.getMessage().toString());
            
        );

        RequestQueue queue = Volley.newRequestQueue(context) ;
        queue.add(stringRequest) ;

【讨论】:

【参考方案3】:

网址 url = 新网址("https://www.google.com");

//如果你正在使用

URLConnection conn =url.openConnection();

//改成

HttpURLConnection conn =(HttpURLConnection )url.openConnection();

【讨论】:

他正在使用HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();【参考方案4】:

我已经创建了对 Activity 类的 callBack(delegate) 响应。

public class WebService extends AsyncTask<String, Void, String> 

    private Context mContext;
    private OnTaskDoneListener onTaskDoneListener;
    private String urlStr = "";

    public WebService(Context context, String url, OnTaskDoneListener onTaskDoneListener) 
        this.mContext = context;
        this.urlStr = url;
        this.onTaskDoneListener = onTaskDoneListener;
    

    @Override
    protected String doInBackground(String... params) 
        try 

            URL mUrl = new URL(urlStr);
            HttpURLConnection httpConnection = (HttpURLConnection) mUrl.openConnection();
            httpConnection.setRequestMethod("GET");
            httpConnection.setRequestProperty("Content-length", "0");
            httpConnection.setUseCaches(false);
            httpConnection.setAllowUserInteraction(false);
            httpConnection.setConnectTimeout(100000);
            httpConnection.setReadTimeout(100000);

            httpConnection.connect();

            int responseCode = httpConnection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) 
                BufferedReader br = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) 
                    sb.append(line + "\n");
                
                br.close();
                return sb.toString();
            
         catch (IOException e) 
            e.printStackTrace();
         catch (Exception ex) 
            ex.printStackTrace();
        
        return null;
    

    @Override
    protected void onPostExecute(String s) 
        super.onPostExecute(s);

        if (onTaskDoneListener != null && s != null) 
            onTaskDoneListener.onTaskDone(s);
         else
            onTaskDoneListener.onError();
    

在哪里

public interface OnTaskDoneListener 
    void onTaskDone(String responseData);

    void onError();

您可以根据自己的需要进行修改。是为了得到

【讨论】:

这很有帮助。不过,我确实有几个问题。变量 mContext 是由从未引用的。它需要在那里吗?另外,是否需要如上所述断开连接? 如果您不需要它,请删除它。但大多数时候我需要 AsyncTask 中的活动上下文。第二点是关于 setConnectTimeout 。如果响应延迟超过 10 秒。你面临一个 ANDrod 没有响应的消息。 我是这个环境的新手,所以试图了解最佳实践。 @Luigi 对 Davos555 发表评论:“你应该在 finally 块中关闭你的连接”。我看到你有一个 br.close() 来关闭阅读器,但是在某处也应该有一个 httpConnection.disconnect() ,还是有关系? 是的@John Ward,你是对的,连接也应该关闭。【参考方案5】:

这是一个完整的AsyncTask

public class GetMethodDemo extends AsyncTask<String , Void ,String> 
    String server_response;

    @Override
    protected String doInBackground(String... strings) 

        URL url;
        HttpURLConnection urlConnection = null;

        try 
            url = new URL(strings[0]);
            urlConnection = (HttpURLConnection) url.openConnection();

            int responseCode = urlConnection.getResponseCode();

            if(responseCode == HttpURLConnection.HTTP_OK)
                server_response = readStream(urlConnection.getInputStream());
                Log.v("CatalogClient", server_response);
            

         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        

        return null;
    

    @Override
    protected void onPostExecute(String s) 
        super.onPostExecute(s);

        Log.e("Response", "" + server_response);


    


// Converting InputStream to String

private String readStream(InputStream in) 
        BufferedReader reader = null;
        StringBuffer response = new StringBuffer();
        try 
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null) 
                response.append(line);
            
         catch (IOException e) 
            e.printStackTrace();
         finally 
            if (reader != null) 
                try 
                    reader.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
        return response.toString();
    

调用这个AsyncTask

new GetMethodDemo().execute("your web-service url");

【讨论】:

【参考方案6】:

尝试从这里获取输入流,然后可以这样获取文本数据:-

    URL url;
    HttpURLConnection urlConnection = null;
    try 
        url = new URL("http://www.mysite.se/index.asp?data=99");

        urlConnection = (HttpURLConnection) url
                .openConnection();

        InputStream in = urlConnection.getInputStream();

        InputStreamReader isw = new InputStreamReader(in);

        int data = isw.read();
        while (data != -1) 
            char current = (char) data;
            data = isw.read();
            System.out.print(current);
        
     catch (Exception e) 
        e.printStackTrace();
     finally 
        if (urlConnection != null) 
            urlConnection.disconnect();
            
    

您也可以使用其他输入流阅读器,例如缓冲阅读器。

问题是当您打开连接时 - 它不会“拉”任何数据。

【讨论】:

你应该在 finally 块中关闭你的连接 我故意使用广泛的例外来防止方法变得过于冗长。用户应尝试在适当的情况下使用更具体的。 我找不到断开连接抛出什么异常? 是的,disconnect() 不需要 try catch,已删除。【参考方案7】:

如果你只需要一个非常简单的调用,你可以直接使用URL:

import java.net.URL;

    new URL("http://wheredatapp.com").openStream();

【讨论】:

以上是关于使用 Android HttpURLConnection 获取 Http的主要内容,如果未能解决你的问题,请参考以下文章

android 连接网络的简单实例

如何使用 HttpUrlConnect 使用 java 查询 Github graphql API

HttpUrlConnect post提交

Android中的网络编程

android中的HttpUrlConnection的使用之一

Android探索之HttpURLConnection网络请求