2012-01-02 32 views
26

我的代碼有問題,希望得到一些幫助。 我首先使用此代碼: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) 
+0

使用android推薦的解決方案:http://tinyurl.com/88mctoh – wurde 2012-01-03 00:28:58

回答

72

StrictMode.ThreadPolicy自API Level 9開始引入,並且默認線程策略自API Level 11以來一直在更改,這簡直不允許在UI線程上執行網絡操作(包括HttpClient和HttpUrlConnection)。如果你這樣做,你會得到NetworkOnMainThreadException。

這種限制是可以改變的,使用:

if (android.os.Build.VERSION.SDK_INT > 9) { 
     StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
     StrictMode.setThreadPolicy(policy); 
    } 

添加上面的代碼到您的主要活動的onCreate()方法。

此外,它總是建議移動網絡操作關閉UI線程,例如,使用的AsyncTask。

希望得到這個幫助。

+9

這些政策的重點是強制良好的做法,並確保您的應用程序運行良好。關閉這些政策是一個壞主意。看到Sbossb的答案是正確的。 – rgardler 2012-05-05 08:30:29

+4

@rgardler,仔細閱讀答案:**總是建議將網絡操作從UI線程移出,例如使用AsyncTask。**線程策略在沒有突出顯示的情況下發生了變化,許多消費開發人員都沒有意識到,值得指出爲什麼代碼在GingerBread但HoneyComb中工作的確切原因,同時請注意AsyncTask是推薦的,但絕對不是唯一正確的方法。 – yorkw 2012-05-05 08:50:50

+2

@yorkw呃......你爲什麼要把這個作爲答案?!?尋求快速修復的初學者不會在意......他們只是將您的代碼複製並粘貼到他們的項目中,而當另一個蹩腳的應用程序在Android Market上發佈時,這將是您的錯。 – 2012-08-01 05:23:13

32

使用​​使網絡請求不阻塞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); 

看看this article寫在Android開發者網站上。它更詳細地解釋瞭如何編寫應用程序來處理線程。

+0

我試過這個,它給了我一個我無法解決的錯誤。以下是logcat顯示的內容:01-03 15:01:46.508:E/AndroidRuntime(23161):java.lang.RuntimeException:無法啓動活動ComponentInfo {com.lacra.fbirthdays/com.lacra.fbirthdays.ListV}: java.lang.IndexOutOfBoundsException:無效索引0,大小爲0 01-03 15:36:44.121:E/AndroidRuntime(24957):\t at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) – Lara 2012-01-03 13:41:50

+0

我已評論String link = params [0];我也包圍了client.execute(request);與try/catch – Lara 2012-01-03 13:44:43