【问题标题】:Http Get using Android HttpURLConnection使用 Android HttpURLConnection 获取 Http
【发布时间】: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));
        }   
    }        
}

【问题讨论】:

    标签: java android-emulator android-internet


    【解决方案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();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多