2012-07-13 55 views
0

我有一個顯示項目的listview的活動。該活動有三個按鈕和一個包含多個其他按鈕的菜單。Android ListView和更新列表視圖的多個線程

當我按下一個按鈕,一個新的線程啓動,從Web服務獲取數據,填充列表視圖。然後顯示列表視圖。

唯一的問題是,每次我按下其中一個按鈕,我啓動一個線程。根據數據被檢索需要多長時間,有時會發生listview沒有填充好數據(用戶不會等待一個線程完成並推送另一個按鈕)

First我試圖取消線程,但它不工作(異步任務或與thread.interrupt)

我怎樣才能停止以前的線程,以便listview將充滿最後的數據?

感謝您的幫助:)

// Items to be displayed in the listview 
    private ArrayList<HashMap<String, Object>> oItems = new ArrayList<HashMap<String, Object>>(); 

    // Launch the thread when toggle is checked 
    button.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
      if (isChecked) { 
       LoadListView(); 
      } 

     } 
    }); 

oMenu.setOnChildClickListener(new OnChildClickListener() { 

      @Override 
      public boolean onChildClick(ExpandableListView parent, View v, 
        int groupPosition, int childPosition, long id) { 
       LoadListView(); 
       return true; 
      } 

     }); 

    private void LoadListView() { 
     new Thread(ListViewRunnable).start(); 
    } 

    private Runnable ListViewRunnable = new Runnable() { 
     public void run() { 
      while (GetItems() < 1) {  
      } 

      MainHandler.post(new Runnable() { 
       public void run() { 

       } 
      }); 
     } 

     private int GetItems() { 
      try { 
       HashMap<String, Object> oItem; 

       //Get items from web services 
       List<ItemFromService> oItemsFromService = GetItemsFromWebService(); 

       for (oItemFromService : oItemsFromService) { 
        oItem = new HashMap<String, Object>(); 
        oItem.put("ID", oItemFromService.get_iID()); 
        oItem.put("Label", oItemFromService.get_sLabel()); 

        oItems.add(oItem); 
       } 

       MainHandler.sendEmptyMessage(GOT_ITEMS); 

      } catch (Exception e) { 

      } 

      return 1; 
     } 
    } 

    private Handler MainHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 

      if (msg.what == GOT_ITEMS) { 

       adapter.notifyDataSetChanged(); 
      } 
     } 
    }; 
+0

你使用線程或AsyncTask或其他東西來產生你的線程?一些示例代碼可能會有所幫助。 – zostay 2012-07-13 12:33:29

+0

列出一些您正在使用的代碼,以便事情變得易於理解。 – 2012-07-13 12:36:07

+0

我正在使用可運行的線程。我的線程連接到Web服務,用對象填充數組,然後調用.notifyDataSetChanged()方法刷新列表視圖。 – user1523505 2012-07-13 12:39:53

回答

0

直到得到完整需要的數據,不使用adaptername.notifyDataSetChanged()方法,以便ListView的適配器將不會得到更新和舊的數據將得到保留。

+0

好的,但是當新線程啓動時,我如何對舊線程說他們不必執行notifyDataSetChanged()方法? :) – user1523505 2012-07-13 12:40:37

+0

布爾值通常用於線程以瞭解他們需要繼續運行..線程將多次使用(mRunning){..do work ..}。 – 2012-07-13 12:43:12

+0

您是否爲不同的按鈕單擊了不同的異步方法?在我們的例子中.3按鈕,所以3個異步方法? – 2012-07-13 12:44:13

0

您可以使用Thread類而不是AsyncTask。實例化線程並維護它的句柄。用途:

hThread.interrupt() 

發送線程中斷消息,以及線程內,測試:

if (isInterrupted()) 
return; 

離開線程。

+0

好吧,我會嘗試。我試圖把我的線程放在一個List中,在啓動一個新的線程之前,我試圖中斷線程,但沒有在線程中檢查「isInterrupted」方法。 當你的意思是「保持一個句柄」,它可以是一個陣列列表中的線程正確嗎? 謝謝 – user1523505 2012-07-13 14:37:11

+0

是的,hThread =新的線程(...),將它存儲在一個ArrayList或其他。你也可以使用線程。isAlive()來測試線程當前是否正在運行。線程完成後,您需要將其從列表中刪除。 – CSmith 2012-07-13 14:51:18

+0

好的,我會試試看,並讓你知道如果沒關係:) 謝謝 – user1523505 2012-07-13 14:52:51