2013-05-12 2 views
1

приложение я в настоящее время работаю над должен реагировать на изменения в календаре или событий базы данных, поэтому наблюдатель ниже регистрируется с URI:блоки темы ContentObserver

содержание: //com.android. календарь (для более старых устройств: контент: // календарь)

«Проблема» в том, что Observer получает (иногда) несколько раз, когда соответствующие данные изменяются. Если я зарегистрирую два отдельных ContentResolver, один для .../календарей и один для .../событий, они все равно часто вызываются несколько раз. То, что я пытаюсь достичь с помощью следующего кода, - это буферизация этих нескольких вызовов, поскольку сам ContentResolver вызывает службу, которая будет запускать много кода. Таким образом, услугу следует вызывать только один раз для многих вызовов ContentObserver за короткий промежуток времени.

public class Observer extends ContentObserver{ 

private Context con; 

public Observer(Handler handler, Context con) { 
    super(handler); 
    this.con = con; 
} 

@Override 
public void onChange(boolean selfChange) { 
    Log.i("TS", "Änderung an den Kalendern"); 

    //Gets released after the first Change, waits and checks SharedPrefs in order to buffer multiple Calls in a short period of time! 
    //Changes get handled in the Service 
    Thread buffer = new Thread(){ 

     @Override 
     public void run() { 
      int check = 1, last = 0; 

      do{ 
       try { 
        sleep(5000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       last = check; 
       check = getCurrent(); 
      } while(last != check); 

      releaseIntent(); 
     } 

    }; 

    SharedPreferences prefs = con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE); 
    Editor edit = prefs.edit(); 

    int first = prefs.getInt(Constants.FIRST_ON_CHANGE, 1); 

    if(first == 1) 
     buffer.run(); 

    first++; 

    edit.putInt(Constants.FIRST_ON_CHANGE, first); 
    edit.commit(); 

} 

//returns the current control-integer from SharedPrefs (for Thread) 
private int getCurrent(){ 
    SharedPreferences prefs = con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE); 
    return prefs.getInt(Constants.FIRST_ON_CHANGE, 1);  
} 

//releases ContentChanged-Intent for Service, resets SharedPrefs 
private void releaseIntent(){ 
    con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE).edit().putInt(Constants.FIRST_ON_CHANGE, 1).commit(); 


    AlarmManager alm = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE); 
    alm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), new PendingIntentCreator(con).createContentChangedIntent()); 
    } 
} 

Моя идея, чтобы решить эту проблему, было создание нити, если сохраненное значение («Int первого» от SharedPreferences) равен 1. Если наблюдатель будет вызываться еще раз в то время как поток спит, значение будет подняться и нить снова будет спать ...

К сожалению, нить блокирует другие входящие вызовы, так что ее цикл никогда не расширяется. Журналы в моем исходном коде показали мне, что SharedPreferences изменяются после завершения Thread!

  • У кого-нибудь есть решение для меня? (Я новичок в потоковом ...)
  • Должен ли я реализовать другую службу для этой буферизации?
  • Общее: Можно ли передать контекст в ContentObserver?

Заранее благодарен! ;)

ответ

1

Я нашел ошибку я сделал:

Вместо вызова buffer.run(), я должен был на самом деле начать нить на buffer.start(), так как вызов .run() просто выполняет реализацию метода run ...

Другими словами, клиентский код, создающий экземпляр потока, не должен размещать вызов метода run() для вновь созданного потока. Поскольку очень факт, что вызов метода run() для объекта потока немедленно выполнил шаги в методе run() defeats сама цель многопоточного программирования, которая по существу не является детерминированным характером в терминах порядка выполнения одновременно работающих потоков.

http://www.coderanch.com/t/234040/threads/java/Difference-run-start-method-Thread

Смежные вопросы