2013-05-12 19 views
1

我目前正在对应用必须在日历或事件数据库的变化作出反应,因此观察下面获取与URI注册:线程块ContentObserver

内容://com.android。日历(对于较旧的设备:内容://日历)

“问题”是观察者在相应的数据发生变化时会(有时)调用几次。如果我注册了两个单独的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被更改!

  • 有没有人有我的解决方案? (我是线程新手......)
  • 我应该为此缓冲工作实施其他服务吗?
  • 一般:可以将上下文转移到ContentObserver中吗?

在此先感谢! ;)

回答

1

我发现我犯了这个错误:

而不是调用buffer.run()的,我不得不实际buffer.start()启动线程,因为调用.RUN ()只是执行run-method ...

换句话说,实例化线程的客户端代码不应该在新实例化的线程上调用run()方法。因为事实上,调用线程对象上的run()方法会立即执行run()方法中失败的步骤多线程编程的目的,就同时运行的线程的执行顺序而言,它本质上具有非确定性性质。

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