2014-01-13 27 views
1

在主線程上沒有網絡調用,但仍然收到相同的錯誤:NetworkOnMainThreadException「NetworkOnMainThreadException」,但在主線程上沒有網絡調用

MainActivity.class:

public class MainActivity extends Activity 
{ 
    private TextView tv1, 
         tv2, 
         tv3; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     tv1 = (TextView) findViewById(R.id.tv1); 
     tv2 = (TextView) findViewById(R.id.tv2); 
     tv3 = (TextView) findViewById(R.id.tv3); 

     String xmlUrl = "https://dl.dropboxusercontent.com/s/wbuxa7cutb6/update.xml"; 

     new DownloadData().execute(xmlUrl); 
    } 

    public class DownloadData extends AsyncTask<String, Void, InputStream> 
    { 
     @Override 
     protected InputStream doInBackground(String... urls) { 
      try { 
       URL url = new URL(urls[0]); 

       HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
       connection.setReadTimeout(10000); 
       connection.setConnectTimeout(15000); 
       connection.setRequestMethod("GET"); 
       connection.setDoInput(true); 

       connection.connect(); 
       int response = connection.getResponseCode(); 
       Log.d("", "The response is: " + response); 

       return connection.getInputStream(); 
       //return new Scanner(connection.getInputStream(),"UTF-8").useDelimiter("\\A").next(); 
      } 
      catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return null;  
     } 

     @Override 
     protected void onPostExecute(InputStream is) 
     { 
      List<List<String>> lists = new XmlParser().parse(is); 

      tv1.setText(lists.get(0).get(0)); 
      tv2.setText(lists.get(0).get(1)); 
      tv3.setText(lists.get(0).get(2)); 
     } 
    } 
} 

你怎麼能看到,需要互聯網只是doInBackground(),但錯誤依然存在。

登錄:

01-13 03:18:37.668: E/AndroidRuntime(5679): FATAL EXCEPTION: main 
01-13 03:18:37.668: E/AndroidRuntime(5679): android.os.NetworkOnMainThreadException 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:657) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at libcore.io.Streams.readSingleByte(Streams.java:41) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at libcore.net.http.AbstractHttpInputStream.read(AbstractHttpInputStream.java:63) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1623) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:111) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:132) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at neviat.test.downloaddata.XmlParser.parse(XmlParser.java:39) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:70) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:1) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.AsyncTask.finish(AsyncTask.java:631) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.AsyncTask.access$600(AsyncTask.java:177) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.os.Looper.loop(Looper.java:137) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at android.app.ActivityThread.main(ActivityThread.java:5041) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at java.lang.reflect.Method.invoke(Method.java:511) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
01-13 03:18:37.668: E/AndroidRuntime(5679):  at dalvik.system.NativeStart.main(Native Method) 

XmlParser的:

public class XmlParser 
{ 
    private DocumentBuilderFactory factory; 
    private DocumentBuilder builder; 

    private String getNodeValue(NamedNodeMap map, String key) { 
     String nodeValue = null; 
     Node node = map.getNamedItem(key); 
     if (node != null) 
      nodeValue = node.getNodeValue(); 
     return nodeValue; 
    } 

    public List<List<String>> parse(InputStream inStream) 
    { 
     List<List<String>> lists = new ArrayList<List<String>>(); 

     try { 
      factory = DocumentBuilderFactory.newInstance(); 
      builder = factory.newDocumentBuilder(); 
      builder.isValidating(); 
      Document doc = builder.parse(inStream, null); 

      doc.getDocumentElement().normalize(); 

      NodeList itemList = doc.getElementsByTagName("item"); 
      final int length = itemList.getLength(); 

      for (int i = 0; i < length; i++) { 
       final NamedNodeMap attr = itemList.item(i).getAttributes(); 
       final String dataId   = getNodeValue(attr, "id"); 
       final String dataName  = getNodeValue(attr, "name"); 
       final String dataUrl  = getNodeValue(attr, "url"); 

       List<String> list = new ArrayList<String>(); 

       list.add(dataId); 
       list.add(dataName); 
       list.add(dataUrl); 

       lists.add(list); 
      } 
     } catch (SAXException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ParserConfigurationException e) { 
      e.printStackTrace(); 
     } 

     return lists; 
    } 
} 
+0

這是顯示在你的logcat? 'Log.d(「」,「答案是:」+ response);' – Coderji

+1

'XmlParser'的第39行是什麼? – codeMagic

+0

解析來自'InputStream'的XML是一種網絡操作。這應該移到'doInBackground()'方法。 – corsair992

回答

1

您InputStream中返回到主線程,這意味着你會做的onPostExecute方法網絡操作(其在主線程上運行)。您必須在後臺線程中獲得全部數據。只有當數據不是來自網絡時,才能從InputStream解析UI線程上的數據,但這不是您的情況。

簡而言之,將您的List<List<String>> lists = new XmlParser().parse(is);代碼放入doInBackground方法中,然後返回您的列表。

澄清:您錯過的是Streamings的用途。它們意味着被使用,所以你不需要一次加載所有的數據(使資源使用,特別是內存消耗低)。當你將InputStream傳遞給UI線程時,你不知道已經下載了多少數據(如果有的話)。假設你正在下載一個巨大的XML文件(30MB),你需要解析它。使用InputStream避免了下載整個內容的需要,將其放入內存(這會使應用程序崩潰)然後解析它。通過Streams,該方法將下載一點數據,解析並釋放已用內存,因此內存消耗量始終保持較低水平。

+0

太棒了!非常感謝你! –

2

引用項目的第一行告訴你錯誤在哪裏。

at neviat.test.downloaddata.XmlParser.parse(XmlParser.java:39) 

所以錯誤實際上XmlParser.java是在第39行,而不是在MainActivity。然而,堆棧跟蹤我們展示了它是從哪裏通過查看它引用您的項目

at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:70) 

,所以我們可以看到這就是所謂的onPostExecute()MainActivity運行於UI Thread下一行調用。所以解決方法是在doInBackground()中運行該行。

List<List<String>> lists = new XmlParser().parse(is); 

但是,根據什麼地方,你會使用lists,您需要將其作爲申報或Activity(你需要它的任何範圍)的任一AsyncTask的成員變量。然後你可以在doInBackground()中初始化它。

+0

謝謝!但爲什麼解析** InputStream是**(從互聯網)做互聯網工作?我在另一個項目中使用過解析,並且我不需要在後臺執行它。 =/ –

+1

@Neviat向我們展示您的解析代碼。懷疑有網絡運營 – Raghunandan

+0

@Raghunandan,沒有。 –

相關問題