Android 线程块ContentObserver

Android 线程块ContentObserver,android,multithreading,contentobserver,Android,Multithreading,Contentobserver,我当前使用的应用程序必须对日历或事件数据库中的更改做出反应,因此下面的观察者将使用URI注册: content://com.android.calendar (对于较旧的设备:content://calendar) “问题”是,当相应的数据发生更改时,观察者(有时)会被调用多次。如果我注册两个独立的ContentResolver,一个用于…/日历,另一个用于…/事件,它们仍然经常被多次调用。我试图用下面的代码实现的是缓冲这些多个调用,因为ContentResolver本身调用一个服务,这将运行大

我当前使用的应用程序必须对日历或事件数据库中的更改做出反应,因此下面的观察者将使用URI注册:

content://com.android.calendar (对于较旧的设备:content://calendar)

“问题”是,当相应的数据发生更改时,观察者(有时)会被调用多次。如果我注册两个独立的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());
    }
}
我解决这个问题的想法是,如果保存的值(“来自SharedReferences的int first”)等于1,则生成一个线程。如果观察者在线程休眠时再次被调用,那么该值将被提升,线程将再次休眠

不幸的是,线程会阻止其他传入调用,因此其循环永远不会被扩展。我的原始代码中的日志向我显示,在线程完成后,SharedReferences会发生更改

  • 有人能帮我解决吗?(我是穿线新手…)
  • 我应该为这个缓冲工作实现另一个服务吗
  • 常规:可以将上下文转移到ContentObserver中吗

提前谢谢!;)

我发现了我犯的错误:

我没有调用buffer.run(),而是通过buffer.start()实际启动线程,因为调用.run()只是执行run方法的实现

换句话说,实例化线程的客户端代码不应该在新实例化的线程上调用run()方法方法违背了多线程编程的目的,多线程编程在并发运行线程的执行顺序方面本质上是不确定的


我发现了我犯的错误:

我没有调用buffer.run(),而是通过buffer.start()实际启动线程,因为调用.run()只是执行run方法的实现

换句话说,实例化线程的客户端代码不应该在新实例化的线程上调用run()方法方法违背了多线程编程的目的,多线程编程在并发运行线程的执行顺序方面本质上是不确定的