在我的Android应用程序中,我有一个Observable
Data
类,其中包含一个方法download()
来下载和解析一些数据。完成后,它会通知其Observer
。
此外,我有Activity
和Service
。 Activity
使用download()
异步调用AsyncTask
方法。
Service
经常需要监听更新以进一步处理数据。这不应该发生在UI线程中。我创建了这个小Service
类:
public class MyService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
new MyWorkerThread().start();
}
private class MyWorkerThread extends Thread implements Observer{
@Override
public void run() {
observeData();
}
private void observeData(){
Data.getInstance().addObserver(this);
}
@Override
public void update(Observable observable, Object data) {
// In what thread does the code placed here run?
}
}
}
现在,我的问题是:当download()
类的Data
方法通知其Observer
时,update()
方法将在哪个线程运行?这是否在AsyncTask
创建的Activity
的主题中,这会阻止代码在服务完成之前通过onPostExecute()
方法?如果是这样,我最好还是MyService
Observer
并且每次都创建一个新的MyWorkerThread
吗?
或者代码是否会由MyWorkerThread
?
我希望这是可以理解的,提前谢谢!
答案 0 :(得分:2)
答案就在这里
当Data类的download()方法通知其Observers
时
在与update
方法相同的线程中将被调用(它将与download
方法运行在同一个线程中 - 据我所知,它会通知其观察者。
正如zapl发布的那样,MyWorkerThread
在观察数据(observeData();
)后完成。
为了在不同的线程中运行,你应该写一些类似的东西:
private class MyWorkerThread extends Thread implements Observer{
@Override
public void run() {
observeData();
}
private void observeData(){
Data.getInstance().addObserver(this);
}
@Override
public void update(Observable observable, Object data) {
this.start(); //will execute observeData(); in a new thread
}
}
答案 1 :(得分:1)
我想每次调用notifyObservers方法时,我最好创建一个新的线程
你可以这样做,但你不必这样做。例如,使用单个HandlerThread
可以实现相同的目标。此外,您不必处理并行运行的多个线程。
public class ObserverService extends Service {
private Looper mLooper;
private void onDataChanged() {
// do whatever you need.
// This is executed in a background thread.
}
@Override
public void onCreate() {
HandlerThread ht = new HandlerThread("ObserverService");
ht.start();
mLooper = ht.getLooper();
final Handler handler = new Handler(mLooper) {
@Override
public void handleMessage(Message msg) {
// executed in background HandlerThread
onDataChanged();
}
};
Observer observer = new Observer() {
@Override
public void update(Observable observable, Object data) {
// this is executed in whatever thread notifies
// enqueue max 1 messages.
handler.removeMessages(1234);
handler.sendEmptyMessage(1234);
}
};
// register observer that send message to background thread.
Data.getInstance().addObserver(observer);
}
@Override
public void onDestroy() {
mLooper.quit();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
答案 2 :(得分:0)
Executor executor = Executors.newCachedThreadPool();
Observer<MyData> observer = data -> executor.execute(() -> onMyDataChanged(data));
MyData.getInstance().observeForever(observer);