2014-06-28 18 views
0

我正在尋找一種同時完成多個HTTP連接的最佳方法。我的應用程序從25個不同的來源提取RSS提要,目前我只有一個HTTP連接,這顯然需要一點時間才能通過所有的URL。我使用ASyncTask工作,每次下載和解析RSS文檔時,我都會更新我的SQLite數據庫,並向它添加提要。在Android上使用HTTPClient完成多個HTTP連接的最佳方法

private class FeedFetcherTask extends AsyncTask<String, Void, Integer> { 

    private Context context; 
    private String[] pcFeedUrls; 
    private String[] xboxFeedUrls; 
    private String[] playstationFeedUrls; 
    private String[] nintendoFeedUrls; 
    private String[] mobileFeedUrls; 

    private ArrayList<NewsFeed> newFeeds; 

    public FeedFetcherTask(Context c) { 

     context = c; 
     pcFeedUrls = c.getResources().getStringArray(R.array.pc_feeds); 
     xboxFeedUrls = c.getResources().getStringArray(R.array.xbox_feeds); 
     playstationFeedUrls = c.getResources().getStringArray(R.array.playstation_feeds); 
     nintendoFeedUrls = c.getResources().getStringArray(R.array.nintendo_feeds); 
     mobileFeedUrls = c.getResources().getStringArray(R.array.mobile_feeds); 

     newFeeds = new ArrayList<NewsFeed>(); 
    } 

    @Override 
    protected Integer doInBackground(String... params) { 

     long time = System.currentTimeMillis(); 

     //getActivity().setProgressBarIndeterminateVisibility(true); 

     getNewsForPc(); 
     getNewsForXbox(); 
     getNewsForPlaystation(); 
     getNewsForNintendo(); 
     getNewsForMobile(); 

     newRowsInserted = storeNewsInDatabase(); 

     long finish = System.currentTimeMillis() - time; 
     Log.i("time elapsed", finish/1000.0 + ""); 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Integer count) { 
     super.onPostExecute(count); 

     if (getActivity() != null) { 
      getActivity().setProgressBarIndeterminateVisibility(false); 

      if (newRowsInserted == 0) { 
       Toast.makeText(getActivity().getApplicationContext(), getResources().getString(R.string.no_new_tweets), Toast.LENGTH_SHORT).show(); 
      } else { 
       newFeedsButton.setVisibility(Button.VISIBLE); 
       buttonVisible = Button.VISIBLE; 
       newFeedsButton.setText(getResources().getQuantityString(R.plurals.new_feeds_plurals, newRowsInserted, newRowsInserted)); 

       //TODO Create animation 
      } 
     } 

     else{ 
      buttonVisible = Button.VISIBLE; 
     } 

    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
    } 

    private void retainListViewPosition() { 

     int index = listView.getFirstVisiblePosition() + newFeeds.size(); 
     View v = listView.getChildAt(0); 
     int top = (v == null) ? 0 : v.getTop(); 
     listView.setSelectionFromTop(index, top); 
    } 

    private void getNewsForPc() { 

     int platform = NewsFeed.PLATFORM_PC; 

     for (String url : pcFeedUrls) { 
      parseRssFeed(url, platform); 
     } 
    } 

    private void getNewsForXbox() { 

     int platform = NewsFeed.PLATFORM_XBOX; 

     for (String url : xboxFeedUrls) { 
      parseRssFeed(url, platform); 
     } 
    } 

    private void getNewsForPlaystation() { 

     int platform = NewsFeed.PLATFORM_PLAYSTATION; 

     for (String url : playstationFeedUrls) { 

      parseRssFeed(url, platform); 
     } 
    } 

    private void getNewsForNintendo() { 

     int platform = NewsFeed.PLATFORM_NINTENDO; 

     for (String url : nintendoFeedUrls) { 
      parseRssFeed(url, platform); 
     } 
    } 

    private void getNewsForMobile() { 

     int platform = NewsFeed.PLATFORM_MOBILE; 

     for (String url : mobileFeedUrls) { 
      parseRssFeed(url, platform); 
     } 
    } 

    private void parseRssFeed(String urlIn, int platformIn) { 

     //TODO Too many GC, also need to close streams 

     try { 
      HttpClient apacheClient = new DefaultHttpClient(); 
      HttpResponse response = apacheClient.execute(new HttpGet(urlIn)); 

      BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
      InputSource is = new InputSource(br); 

      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder builder = factory.newDocumentBuilder(); 
      Document document = builder.parse(is); 

      NodeList nodeList = document.getElementsByTagName("item"); 

      String provider = document.getElementsByTagName("title").item(0).getTextContent(); 
      int platform = platformIn; 

      Node node; 
      NewsFeed feed = null; 
      String title; 
      String link; 
      String description; 
      NodeList guidNodeList; 
      String guid; 
      String pubDate; 
      NodeList creatorNodeList; 
      String creator; 

      Element element; 

      for (int i = 0; i < nodeList.getLength(); i++) { 

       node = nodeList.item(i); 

       if (node.getNodeType() == Node.ELEMENT_NODE) { 

        element = (Element) node; 
        feed = new NewsFeed(); 

        title = element.getElementsByTagName("title").item(0).getTextContent(); 
        feed.setTitle(title); 

        link = element.getElementsByTagName("link").item(0).getTextContent(); 
        feed.setLink(link); 

        description = element.getElementsByTagName("description").item(0).getTextContent(); 
        feed.setDescription(description); 

        guidNodeList = element.getElementsByTagName("guid"); 

        if (guidNodeList == null | guidNodeList.getLength() < 1) { 
         feed.setGuid(link); 
        } else { 
         guid = guidNodeList.item(0).getTextContent(); 
         feed.setGuid(guid); 
        } 

        pubDate = element.getElementsByTagName("pubDate").item(0).getTextContent(); 
        feed.setDate(pubDate); 

        creatorNodeList = element.getElementsByTagName("dc:creator"); 

        if (creatorNodeList == null | creatorNodeList.getLength() < 1) { 
         feed.setCreator(provider); 
        } else { 
         creator = creatorNodeList.item(0).getTextContent(); 
         feed.setCreator(creator); 
        } 

        feed.setProvider(provider); 
        feed.setPlatform(platform); 

        newFeeds.add(feed); 
       } 
      } 
     } catch (ConnectException ce) { 
      Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.connection_exception_error), Toast.LENGTH_SHORT).show(); 
     } catch (UnknownHostException uhe) { 
      uhe.printStackTrace(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private int storeNewsInDatabase() { 

     return dao.insertAllFeeds(newFeeds); 
    } 
} 

我相信這可能是最低效率的方法。我將不勝感激任何有關如何處理此任務的建議。我已經看過ExecutorService,但不知道這是否是正確的方式。

回答

1

我建議使用loopj,異步HTTP客戶端庫。您需要重構代碼以使其成爲事件驅動的,但它應該值得付出努力。

相關問題