3

私の Android アプリケーションには、データをダウンロードして解析するObservable Dataメソッドを含むクラスがあります。download()これが完了すると、s に通知し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その s を通知するとき、メソッドはObserverどのスレッドでupdate()実行されますか? AsyncTaskこれはによって作成されたのスレッドにあり、サービスが完了するまでActivityコードがメソッドを通過するのを防ぎますか? onPostExecute()もしそうなら、私は自分MyServiceのを作成し、毎回Observer新しいものを作成したほうがよいでしょうか? MyWorkerThreadまたは、コードは独自のスレッドで実行されMyWorkerThreadますか?

理解できるといいのですが、よろしくお願いします!

4

3 に答える 3

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 に答える
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 に答える
0
    Executor executor = Executors.newCachedThreadPool();
    Observer<MyData> observer = data -> executor.execute(() -> onMyDataChanged(data));
    MyData.getInstance().observeForever(observer);
于 2019-08-26T19:40:18.880 に答える