我正在处理的应用程序必须对日历或事件数据库中的更改做出反应,因此下面的Observer将使用URI进行注册:
content://com.android.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());
}
}
我解决这个问题的想法是,如果保存的值(来自SharedPreferences的“int first”)等于1,则生成一个线程。如果观察者在该线程休眠时被另一次调用,则该值将被提升并且线程会再次入睡......
不幸的是,线程会阻止其他传入的调用,因此它的循环永远不会被扩展。我的原始代码中的Logs告诉我,在完成Thread之后,SharedPreferences会被更改!
提前致谢! ;)
答案 0 :(得分:1)
我发现了我犯的错误:
而不是调用 buffer.run(),我不得不通过 buffer.start()实际启动线程,因为调用.run()只执行实现运行方法......
换句话说,实例化线程的客户端代码不应该在新实例化的线程上调用run()方法。因为在线程对象上调用run()方法会立即执行run()方法中的步骤违背了多线程编程的目的,就同时运行的线程的执行顺序而言,这基本上是一种非确定性的。
http://www.coderanch.com/t/234040/threads/java/Difference-run-start-method-Thread