2010-07-30 104 views
0

我剛剛這段代碼很簡單。我有一個列表,並且在onCreate方法中,我添加了一些對象到這個列表中以在屏幕上顯示它們。我有一個廣播接收器,當沒有互聯網連接時,它必須啓用/禁用列表中的某些元素。在Android中的廣播接收機的奇怪問題

當應用程序已經在此活動的屏幕中時,如果連接丟失,則廣播接收器工作良好。問題是在進入此活動之前沒有連接。在這種情況下,在onresume()方法中調用oncreate()方法後,接收方會被註冊,但是當我在接收方中調用getListView()時,它沒有任何孩子(儘管我在oncreate方法中添加了適配器,我沒有加載然後使用任何線程)。

有誰能告訴我爲什麼會發生這種情況?

public class MyActivity extends ListActivity { 
    private List<MyClass> myObjects; 

    private final BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 

      //check if internet connection is available 
      boolean networkAvailable = ... ; 
      if (!networkAvailable) { 
       //No Internet connection: disabled non-cached objects 
       List<MyClass> cachedObjects = getCachedObjects(); 
       for(int i = 0; i<myObjects.size(); i++){ 
        MyClass myObject = myObjects.get(i); 
        if (!cachedSurveys.contains(myObject)) { 
         ListView listView = getListView(); 
         //The problem is here: listView is empty when there was no connection 
         //before creating the activity so the broadcast receiver was called in a sticky way      
         View child = listView.getChildAt(i); 
         child.setEnabled(false); 

        } 
       } 
      } else { 
       // Internet connection: enable all myObjects 
       int size = getListView().getChildCount(); 
       for (int i = 0; i < size; i++) { 
        View child = getListView().getChildAt(i); 
        child.setEnabled(true); 
       } 
      } 
     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     myObjects = getMyObjects(); 

     setListAdapter(new ArrayAdapter<MyClass>(this, android.R.layout.simple_list_item_1, myObjects)); 
     getListView().setTextFilterEnabled(true); 
} 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"); 
     registerReceiver(receiver, intentFilter); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     unregisterReceiver(receiver); 
    } 
} 

感謝

回答

4

首先,我認爲我們應該通過一些事實:

  • 活動將啓動的onResume()方法後,繪製其內容的調用,但不是「右後」
    • 調用ListView.setListAdapter(...)後,ListView僅存儲適配器對象,此時沒有子視圖。
    • ListView在屏幕上繪製子對象後(在調用Adapter.getView()之後),子視圖將可用,並且每次ListView添加多個子視圖時,子視圖列表將逐個增加,直到ListView繪製它們全部在屏幕上。

    而對於您的代碼,您在第一次活動開始時無法獲取子視圖列表的原因是「ListView沒有在屏幕上繪製任何東西」。因爲接收器的onReceive()方法在ListView繪製之前觸發。

    您可以通過覆蓋適配器並顯示日誌來查看這些方法被調用的順序。 這裏是我的結果:

    07-30 23:06:03.231: DEBUG/MyActivity(386): onResume 1280505963237 
    07-30 23:06:03.281: DEBUG/MyActivity(386): onReceive 1280505963281 
    07-30 23:06:03.361: DEBUG/MyActivity(386): getView 0 1280505963371 
    07-30 23:06:03.381: DEBUG/MyActivity(386): getView 1 1280505963386 
    

    希望我的回答能幫助你!

  • +0

    非常感謝。 – Javi 2010-07-31 14:24:51