Как выполнить обработчик в другом потоке основного потока пользовательского интерфейса - PullRequest
0 голосов
/ 05 октября 2019

В моей деятельности обработчик, который делает две вещи, для сообщения GAME_ACTIVITY_UPDATE_UI, должен выполнить некоторые вычисления вне основного потока, а для GAME_ACTIVITY_REFRESH_UI должен выполнить себя в основном потоке. У меня есть отдельный поток вне моей деятельности, который должен вызывать этот обработчик для двух вещей, и в одном случае должен учитывать, что он находится вне основного потока, но для другого случая должен соблюдаться тот, который должен выполнять код в основном потоке.

Проблема в том, что когда мой внешний протектор вызывает обработчик действия, код handleMessage всегда выполняется в главном потоке. Как я могу поддерживать поток, который вызвал обработчик sendEmptyMessage для случая GAME_ACTIVITY_UPDATE_UI вместо выполнения кода в главном потоке пользовательского интерфейса?

Мой обработчик активности:

Handler gameHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){
            case GAME_ACTIVITY_UPDATE_UI:
                updateUI();
                break;
            case GAME_ACTIVITY_REFRESH_UI:
                refreshUI();
                break;
        }
    }
};

Мой внешнийПоток, вызывающий обработчиквыполнить в главном потоке (в данный момент работает)

Спасибо

1 Ответ

0 голосов
/ 05 октября 2019

Вы смотрели на AsyncTask ? Если ваша фоновая задача выполняется всего несколько секунд, вам следует использовать эту концепцию.

, но если вы не хотите менять свой код, я думаю, вы можете сделать это следующим образом

public class MainActivity extends AppCompatActivity implements CallBackListener {
View uiView;
private Handler gameHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 0:
                updateUiInBackground(MainActivity.this);
                break;
            case 1:
                refreshUiInUiThread();
                break;
        }
    }
};

private void updateUiInBackground(CallBackListener callBackListener) {
    //do some task in background
    //can not change uiView here
    callBackListener.backgroundWorkFinished();
}

private void refreshUiInUiThread() {
    //Do some task
    uiView.someMetheode();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    uiView = findViewById(R.id.ui);

    new Thread(new Runnable() {
        @Override
        public void run() {
            gameHandler.sendEmptyMessage(0);
        }
    }).start();

    this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            gameHandler.sendEmptyMessage(1);
        }
    });
}

@Override
public void backgroundWorkFinished() {
    MainActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            uiView.someMethod();
        }
    });
}
}

и это класс обратного вызова

 public interface CallBackListener {
      void backgroundWorkFinished();
 }
...