3

在我的 Android 应用程序中,我有一个Observable Data类,其中包含一个download()下载和解析一些数据的方法。完成后,它会通知其Observers。

此外,我有一个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的 s 时,该方法将在哪个线程中update()运行?这会在由AsyncTask创建的线程中Activity,这会阻止代码onPostExecute()在服务完成之前通过该方法吗?如果是这样,我最好每次都创建MyService一个Observer并创建一个新的?MyWorkerThread或者代码会在它自己的线程中运行MyWorkerThread吗?

我希望它是可以理解的,提前谢谢!

4

3 回答 3

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
        }
}
于 2012-09-26T13:29:01.707 回答
2

我想我最好在每次调用 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;
    }
}
于 2012-09-26T15:49:53.010 回答
0
    Executor executor = Executors.newCachedThreadPool();
    Observer<MyData> observer = data -> executor.execute(() -> onMyDataChanged(data));
    MyData.getInstance().observeForever(observer);
于 2019-08-26T19:40:18.880 回答