2010-07-30 9 views
0

У меня есть только этот фрагмент кода, который довольно прост. У меня есть список и в методе onCreate я добавил некоторые объекты в этот список, чтобы показать их на экране. У меня есть широковещательный приемник, который должен включать/отключать некоторые элементы списка, если нет подключения к Интернету.Странная проблема с широковещательным приемником в Android

Радиовещательный приемник работает хорошо, если соединение потеряно, когда приложение уже находится на экране этой операции. Проблема заключается в отсутствии связи перед входом в эту деятельность. В этом случае после вызова метода oncreate() в onresume() ресивер зарегистрирован, но когда я вызываю 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() получателя запускается до того, как DrawView рисует.

Вы можете проверить это самостоятельно, переопределив адаптер и показать журнал, чтобы увидеть порядок вызова этих методов. Вот мой результат:

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