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));
这是logcat显示的内容:
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)
StrictMode.ThreadPolicy是自API Level 9开始引入的,自API Level 11以来,默认线程策略已经被更改,简而言之,不允许在UI线程上执行networking操作(包括HttpClient和HttpUrlConnection)。 如果你这样做,你会得到NetworkOnMainThreadException。
这个限制可以改变,使用:
if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); }
将上面的代码添加到您的主要活动的onCreate()方法中。
此外, 总是build议将networking操作从UI线程移出 ,例如,使用AsyncTask。
希望这个帮助。
使用AsyncTask,以便networking请求不会阻止UI线程。 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开发人员网站上撰写的这篇文章 。 它更详细地解释了如何编写应用程序来处理线程。