android - httpurlConnection.getInputStream() 给出致命错误
问题描述
我正在开发一个用于预订的 Android 应用程序。这是我关于stackoverflow的第一个问题。如果我不完全遵守规则,请原谅我。我被这个致命错误困住了:
FATAL EXCEPTION: main
Process: com.connectandroiddb.myapplication, PID: 26440
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.HostResolver$1.getAllByName(HostResolver.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
at com.example.myapplication.JSONParser.makeHttpRequest(JSONParser.java:65)
at com.example.myapplication.MainActivity$GetProductDetails$1.run(MainActivity.java:144)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
我从以下位置借用了代码: https ://androidhive.info/2012/05/how-to-connect-android-with-php-mysql/ 下面的相关代码:我正在调用 GetProductDetails(),如下所示
public void sendMessage(View view) {
.....
new GetProductDetails().execute();
......
}
这是在 MainActivity.java
/**
* Background Async Task to Get complete product details
* */
class GetProductDetails extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
JSONObject json = jsonParser.makeHttpRequest(
url_get_product_details, "GET");// Line 144
}
});
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
}
}
这些是来自 JSONParser 的相关部分:
private String readStream(InputStream is) {
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = is.read();
while(i != -1) {
bo.write(i);
i = is.read();
}
return bo.toString();
} catch (IOException e) {
return "";
}
}
public JSONObject makeHttpRequest(String url, String method)
{
HttpURLConnection urlConnection = null;
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST CHECK
}else if(method == "GET"){
// request method is GET
URL u = new URL("http://example.com/");
urlConnection = (HttpURLConnection) u.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream()); //JSONParser.java:65
json=readStream(in);
}
}
catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
finally {
if (urlConnection != null) {
try {
urlConnection.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
}
我在 AndroidManifest.xml 中添加了 Internet 权限。请帮忙!!!。提前致谢,
解决方案
您的问题出在这部分代码中:
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
JSONObject json = jsonParser.makeHttpRequest(url_get_product_details, "GET");
}
});
return null;
}
如您所见,在该方法中,doInBackground
您正在 UI 线程上执行某些操作。Android 在同一个 UI 线程中运行所有 UI,并且您不能在该线程上执行任何长时间运行的任务(如网络请求),因为 UI 将保持冻结状态。
这就是人们使用异步任务或简单线程的原因。如果在doInBackground
您执行的方法runOnUiThread
中违反了该规则,则会NetworkOnMainThreadException
引发异常。
阅读此处的教程,了解如何使用AsyncTask
. 一个提示,你需要使用onPostExecute