Зафиксируйте ориентацию до окончания работы Asynctask

Только хотите заблокировать ориентацию, пока все данные не будут загружены в моем представлении. Поэтому я подумал о следующем коде, но он не работает.

private class task extends AsyncTask<String, Void, String> {

   protected String doInBackground(String... params) {
      ...
   }

   protected void onPostExecute(String result) {
      ...
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
   }

   protected void onPreExecute() {
      ...
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
   }
}

Когда я запускаю эти две строки SENSOR и NOSENSOR, мой экран автоматически поворачивается горизонтально, не понимая почему. Это может произойти?

EDIT: Я установил следующие строки для проверки текущей ориентации со следующим результатом:

   protected void onPreExecute() {
        if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
            Log.e("TAG","LANDSCAPE");
        }else{
            Log.e("TAG","PORTRAIT");
        }
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
   }

Результат Logcat:

LANDSCAPE

Но если я удалю две строки (SetRequestedOrientation), я получу это в logcat:

PORTRAIT

Ответ 1

Просто замените setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); на setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

И дайте мне знать, что произойдет.

Для начального уровня

 protected void onPreExecute() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}

На уровне выхода

 protected void onPostExecute(String result) {
      ...
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
   }

Update:

Проводное поведение (в вашем случае), но каким-либо образом вы можете использовать текущую ориентацию,

int currentOrientation = getResources().getConfiguration().orientation; 

Теперь установите эту ориентацию в onPreExecute()..

Как

protected void onPreExecute() {
  ...
  int currentOrientation = getResources().getConfiguration().orientation; 
   if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
   }
   else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
   }
}

Простой..: -)

Ответ 2

Вероятно, ошибка, но, возможно, лучший способ - либо заблокировать вашу ориентацию, чтобы вам не нужно было беспокоиться о создаваемой деятельности... или еще лучше.

Используйте это в своем манифесте для активности:

android:configChanges="orientation|screenSize|screenLayout"

Затем ваша деятельность не воссоздается при вращении (также как и в HoneyComb/3.0. Действия не воссоздаются при вращении).

Просто переопределите:

onConfigurationChanged(Configuration newConfig){
  //Handle new orientation
}

Тогда вам не нужно путать пользователя, почему телефон остановился во время операции.


Также стоит посмотреть Robospice, если вы хотите выполнять задачи, связанные с lifecyled async.

Ответ 3

Вы делаете это, потому что обнаружили, что ваша асинхронная задача убита во время операции, уничтожая и воссоздавая. Я прав?

Правильный способ обработки: не, чтобы заблокировать ориентацию, пока ваша задача запущена. Я не согласен с тем, что подход setRequestedOrientation не работает, это ошибка; скорее идея блокировки ориентации деятельности, а затем разблокировка от асинхронной задачи не поддерживается.

Я подробно объяснил , как обеспечить, чтобы ваша задача async не была убита, отключив ее с помощью жизненного цикла вашей деятельности. Оглядываясь назад на решение, которое я предоставил, я с тех пор обнаружил лучшие способы проверки обслуживания (Inter Process Control и связанные сервисы), но применяется общий принцип. Задайте задачу async в ориентации, не осознающей android.app.Service, и разрешите асинхронной задаче связываться только со службой и службой только для связи с теми действиями, которые связаны с ней.

Я думаю, что это более стандартный подход.