Как да разграничим промяната на ориентацията и напускането на приложението android

Разбирам, че когато ориентацията на екрана се промени, текущите дейности onDestroy() се извикват, последвани от onCreate() за ефективно пресъздаване на дейността. Трябва да знам как програмно да разбера дали приложението се излиза или просто се променя ориентацията.

Един метод е предишната дейност да ме уведоми, когато се извиква нейният метод onResume(), това ще ме уведоми, че потребителят е натиснал бутона за връщане назад и ориентацията не е променена.

P.S. Търся по-елегантно решение от това да слушам за щракване на хардуерен бутон отзад.

Ето какво исках да направя:

Имам два раздела, когато дейността се въвежда за първи път или потребителят е напуснал дейността и сега я въвежда, определен раздел се показва въз основа на някакъв критерий.

Когато ориентацията се промени, трябва да остана на същия раздел.


person Dustfinger    schedule 08.03.2012    source източник
comment
Можете ли просто да посочите в манифеста, че искате сами да се справите с промените в ориентацията? Тогава onDestroy / onCreate няма да бъде извикан - и вместо това ще бъде извикан onConfigurationChange на вашата дейност. Можете да правите всичко необходимо там.   -  person Aleks G    schedule 08.03.2012
comment
Това, което Алекс предложи, е да добавите към вашия манифест android:configChanges за ориентация. След това можете да презапишете onConfigurationChange и да се справите с промяната на ориентацията   -  person jsimpson    schedule 08.03.2012
comment
@AleksG: Цитирайки документацията за android:configChanges, използването на този атрибут трябва да се избягва и да се използва само като последна мярка.   -  person CommonsWare    schedule 08.03.2012
comment
Трябва да знам как програмно да разбера дали приложението се излиза или просто се променя ориентацията. -- защо?   -  person CommonsWare    schedule 08.03.2012
comment
Отначало мислех сам да се справя с промяната на ориентацията, но изглеждаше като много работа, когато логиката диктува, че „напускане на приложението“ и „промяна на ориентация“ трябва да се различават от жизнения цикъл на дейността. Предполагам, че тогава ще трябва да го направя по този начин (в краен случай).   -  person Dustfinger    schedule 08.03.2012
comment
Когато ориентацията се промени, трябва да остана на същия раздел. -- поставете вашия ID на раздела в Bundle, предоставен на onSaveInstanceState(), и възстановете избрания раздел в onRestoreInstanceState().   -  person CommonsWare    schedule 08.03.2012


Отговори (4)


Използвайте метода isFinishing() на дейността.

@Override
  protected void onDestroy() {
    super.onDestroy();
    if (isFinishing()) {
      // do stuff
    } else { 
      //It's an orientation change.
    }
  }
person dmon    schedule 08.03.2012
comment
Благодаря, прочетох за isFinishing() и това, от което имах нужда. Вижте моята редакция - person Dustfinger; 08.03.2012
comment
За да запазите текущия раздел, можете да запишете неговия идентификатор в onSaveInstanceState(), след което да го прочетете обратно в onCreate(), като по този начин дори не е нужно да се занимавате с isFinishing(). Внимавайте обаче, пакетът ще бъде нулев при стартиране на приложението за първи път. - person dmon; 08.03.2012
comment
Един страничен ефект от този подход: Ако преминете към друго приложение, то няма да завърши вашето активно (така че това няма да бъде извикано). Ако след това приложението бъде затворено от Android OS за пестене на памет - този метод ЩЕ бъде извикан, isFinishing() ще бъде FALSE (вижте тук: developer.android.com/reference/android/app/), като по този начин неправилно изпълнява вашия код за промяна на ориентацията. - person seanhodges; 08.03.2012
comment
Вече се опитах да използвам onSaveInstanceState() и да го прочета обратно в onCreate(), както казахте, но проблемът все още беше, че не знаех дали onCreate() се извиква от промяна на ориентацията или от потребителя, навигиращ до дейността за първи път време. - person Dustfinger; 08.03.2012
comment
Ако е за първи път, пакетът трябва да е нулев. Дори и да не е нула (по някаква причина), стойността на вашия запазен раздел не трябва да е там, така че ще заредите раздела по подразбиране. - person dmon; 08.03.2012
comment
Имам същия въпрос, но за Fragments. - person jasxir; 23.07.2015

можете да използвате isChangingConfigurations() Прочетете от документация

Проверете дали тази дейност е в процес на унищожаване, за да бъде пресъздадена с нова конфигурация. Това често се използва в onStop(), за да се определи дали състоянието трябва да бъде изчистено или ще бъде предадено на следващия екземпляр на дейността чрез onRetainNonConfigurationInstance().

Връща Ако дейността се премахва, за да бъде пресъздадена с нова конфигурация, връща true; else връща false

Обяснете по прост начин с пример

isChangingConfigurations()

е метод, използван за проверка дали дейността ще бъде унищожена, за да бъде създадена отново (в резултат на промяна в ориентацията)

Как се използва ?

ако използвате api >= 11, тогава няма проблем, но ако използвате api ‹ 11, тогава трябва да обработим този метод ръчно, правя булева променлива, наречена IsconfigChange

private boolean IsconfigChange ;
...

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IsconfigChange = true ;

}


    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    @Override
    public boolean isChangingConfigurations() {
        if(android.os.Build.VERSION.SDK_INT >= 11){
            Log.i("DEBUG", "Orientation changed api >= 11 ");
            return super.isChangingConfigurations();    
        }else {
            Log.i("DEBUG", "Orientation changed api < 11 ");
            return IsconfigChange; 
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    @Override
    protected void onStop() {
        super.onStop();
        if(isChangingConfigurations()){
            Log.i("DEBUG", "isChangingConfirgurations OnStop Called");
        }  else{
            Log.i("DEBUG", "OnStop Called");
        }
    }

Лятно

можете да използвате isChangingConfigurations в onStop, за да проверите дали приложението спира да бъде унищожено или поради промяна в ориентацията.

или можете да използвате isFinishing проверете моя отговор тук

person Mina Fawzy    schedule 04.03.2015

за API lvl >= 11 Дейността има isChangingConfigurations() метод

person Maurycy    schedule 03.11.2014

Можете да вземете стойността на Activity.getChangingConfigurations() във вашето onDestroy обратно извикване. Това ще върне резултат като ORIENTATION_PORTRAIT, който вие може да провери спрямо вашата текуща ориентация.

Обърнете внимание, че затварянето на активността и промените в ориентацията не са единствените условия, които трябва да имате предвид тук: Какво ще кажете за връщането към началния екран, входящите телефонни обаждания и други приложения, които крадат фокуса, и всички други сценарии, когато вашият Дейността вече не е в началото на стека?

През повечето време няма да е необходимо да правите това. Ако се опитвате да коригирате някакъв проблем със състоянието на активност (често се проявява като NullPointerException, когато завъртите екрана), като заснемете събитието за ориентация; прегледайте жизнения цикъл на Android Activity и се уверете, че не се опитвате просто да хакнете корекция за дефект в дизайна. Публикувайте първоначалния си проблем на този сайт, ако не сте сигурни.

person seanhodges    schedule 08.03.2012
comment
Благодаря. Ако имате по-добър начин да реализирате това, което искам да направя, отколкото да използвате isFinishing(), уведомете ни. - person Dustfinger; 08.03.2012
comment
Мисля, че това е по-добрият начин isFinishing() поради причините, които обясних в отговора на dmon, но защо изобщо искате да го направите? Рядко се случва приложение за Android да знае кога променя ориентацията си, ако приемем, че се придържате към указанията за разработка... - person seanhodges; 08.03.2012
comment
вижте редактирания въпрос, опитах се да обясня какво трябва да направя. - person Dustfinger; 08.03.2012
comment
А, съжалявам, пропуснах редакцията. Ако бях на твое място, щях да последвам предложението на @CommonsWare в коментарите. Вижте това решение: stackoverflow.com/a/5676186/43662 - person seanhodges; 08.03.2012