DefaultHttpClient для AndroidHttpClient
У меня проблема с моим кодом, и я надеялся на какую-то помощь.
Сначала я использовал этот код:
new DefaultHttpClient().execute(new HttpGet(linkk)).getEntity().writeTo(
new FileOutputStream(f));
И он отлично работает на Android 2.3, но на 4.0 он этого не делает. После некоторых исследований я слышал, что лучше использовать AndroidHttpClient, и таким образом он будет работать с 4.0 и 3.1. Проблема в том, что я не знаю, правильно ли я изменил свой код и не так много примеров, касающихся AndroidhttpClient в Интернете.
Вот мой код, который был скорректирован:
AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
HttpGet request = new HttpGet(linkk);
HttpResponse response = client.execute(request); //here is where the exception is thrown
response.getEntity().writeTo(new FileOutputStream(f));
Это показывает логарифм:
01-03 01:32:11.950: W/dalvikvm(17991): threadid=1: thread exiting with uncaught exception (group=0x40a2e1f8)
01-03 01:32:11.986: E/AndroidRuntime(17991): FATAL EXCEPTION: main
01-03 01:32:11.986: E/AndroidRuntime(17991): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: android.os.NetworkOnMainThreadException
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.access$600(ActivityThread.java:123)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.Handler.dispatchMessage(Handler.java:99)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.Looper.loop(Looper.java:137)
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-03 01:32:11.986: E/AndroidRuntime(17991): at java.lang.reflect.Method.invokeNative(Native Method)
01-03 01:32:11.986: E/AndroidRuntime(17991): at java.lang.reflect.Method.invoke(Method.java:511)
01-03 01:32:11.986: E/AndroidRuntime(17991): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-03 01:32:11.986: E/AndroidRuntime(17991): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-03 01:32:11.986: E/AndroidRuntime(17991): at dalvik.system.NativeStart.main(Native Method)
01-03 01:32:11.986: E/AndroidRuntime(17991): Caused by: android.os.NetworkOnMainThreadException
01-03 01:32:11.986: E/AndroidRuntime(17991): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
01-03 01:32:11.986: E/AndroidRuntime(17991): at java.net.InetAddress.getAllByName(InetAddress.java:220)
01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-03 01:32:11.986: E/AndroidRuntime(17991): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
Ответы
Ответ 1
StrictMode.ThreadPolicy был введен с уровня API 9, а политика потоков по умолчанию была изменена с уровня API 11, что, вкратце, не разрешить работу сети (включая HttpClient и HttpUrlConnection), выполняться в потоке пользовательского интерфейса. если вы это сделаете, вы получите NetworkOnMainThreadException.
Это ограничение можно изменить, используя:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Добавьте вышеуказанный код в свой основной метод onCreate().
Кроме того, всегда рекомендуется переносить сетевую операцию с потока пользовательского интерфейса, например, используя AsyncTask.
надеюсь, что эта помощь.
Ответ 2
Используйте AsyncTask, чтобы сетевой запрос не блокировал поток пользовательского интерфейса. NetworkOnMainThreadException был представлен с версии API версии 11, поэтому он показывает только 3.0 и выше.
private class NetworkTask extends AsyncTask<String, Void, HttpResponse> {
@Override
protected HttpResponse doInBackground(String... params) {
String link = params[0];
HttpGet request = new HttpGet(link);
AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
try {
return client.execute(request);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
client.close();
}
}
@Override
protected void onPostExecute(HttpResponse result) {
//Do something with result
if (result != null)
result.getEntity().writeTo(new FileOutputStream(f));
}
}
Чтобы вызвать этот поток, просто сделайте это.
new NetworkTask().execute(linkk);
Взгляните на эту статью, написанную на сайте разработчика Android. В нем более подробно объясняется, как написать приложение для обработки потоков.