Android: правильный способ обработки действий

#android

#Android

Вопрос:

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

В настоящее время у меня настроено 3 действия. Main.class , Login.class и Display.class . Основное действие вообще не имеет связанного с ним пользовательского интерфейса, оно запускает другие действия. Итак, первое действие, которое запускается get при запуске приложения, является основным действием, и оно отправляется и считывается из хранилища SharedPreferences независимо от того, вошел пользователь в систему или нет. Если они не вошли в систему, откроется Login.class если они вошли в систему, он откроется Display.class (с обоими из которых связан пользовательский интерфейс). Он использует startActivityForResult().

Из-за того, что я решил обойти работу с действиями, мне нужно было переопределить кнопку «Назад» на обоих Login.class и Display.class: в противном случае он вернется к Main.class и повторно запустите последовательность действий запуска, которая в свою очередь повторно запустит действие, которое только что было запущено (поэтому кнопка «Назад» бесполезна). Итак, я переопределил кнопку «Назад», чтобы отправить обратно целое число, равное -1, а затем завершить () текущее действие. Я переопределил onActivityResult (int, int, Intent) для Main.class и если он получит значение -1, он также завершит () вместо того, чтобы пытаться повторно запустить действие.

Теперь все получилось так, как я хотел, хотя у меня такое чувство, что это совершенно неправильный способ обработки действий, и это вызывает у меня проблемы позже на этом пути.

В моем приложении я решил, что хочу вставить виджет приложения и уведомление, оба из которых откроют приложение при нажатии (с помощью намерения, которое запускает Main.class ). Я заставил все это работать, чтобы это делалось, хотя кажется, что запуск нового действия вызывает проблемы.

В принципе, если приложение уже запущено, и кто-то открывает уведомление и нажимает на него, это откроет новое действие того же приложения. Это проблематично, особенно с тем, как я обрабатываю кнопки «Назад»: когда вы открываете новую и нажимаете кнопку «Назад», она закроет новую (как и ожидалось), но затем вернет вас к СТАРОЙ. Затем вы можете снова нажать кнопку «Назад» и выйти из нее, но, очевидно, я не хочу выпускать приложение, для которого требуется дважды нажать кнопку «Назад». Каков наилучший способ решить эту проблему? Я рад полностью изменить способ обработки действий, если это основная часть проблемы.

Спасибо, Джош.

Комментарии:

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

Ответ №1:

На самом деле, то, как вы устанавливаете значение -1 (что нормально), а затем вызываете finish (), вполне приемлемо. Я забыл значения свойств, но если вам нужен только один экземпляр действия, есть способ установить это в манифесте… Привязка к задаче или одно из этих значений — вам придется посмотреть это.

В качестве альтернативы вы можете переопределить класс приложения и использовать свой собственный для управления состоянием приложения. Думайте об этом как об одноэлементном трекере для основного действия.. что-то вроде «если он уже существует, используйте этот, в противном случае создайте новый экземпляр». При создании вашего основного действия установите ссылку в вашем новом расширенном классе приложения (убедитесь, что вы обнуляете ее при завершении работы main), затем проверьте, доступна ли ссылка при повторном запуске onCreate () … если там уже есть ссылка, используйте этот экземпляр Main .. если нет, действуйте как обычно и установите его.

Пища для размышлений…

Комментарии:

1. Спасибо за предложение по изменению манифеста. В итоге я поместил android:launchMode =»singleTop» в теги <activity> как для входа, так и для отображения (не main), и это сработало хорошо. Сначала я попробовал singleInstance, но по какой-то причине SetResult перестал работать, но все это было отдельно от одного и того же документа. Ссылка на документ для разработчиков Android: developer.android.com/guide/topics/manifest /…

2. Да .. Я не мог вспомнить название свойства, но я помню, что читал об этом. Раньше аналогичные isues использовались в приложениях Windows CE и Windows Mobile. Хорошая работа, чтобы найти это.

Ответ №2:

У меня такое чувство, что я не до конца понимаю глубину проблемы, поэтому, пожалуйста, простите меня, если я говорю то, что вы уже пробовали.

Но не могли бы вы удалить Main и запустить Login с экрана? Я имею в виду, имеет больше смысла. Это то, что я делаю здесь постоянно, когда мне нужны вспомогательные действия, которые должны заполнять данные для основного действия (которое, очевидно, отображается в вашем случае). И когда вы вернетесь после входа в систему, вы сможете выполнить все необходимые проверки. Вы могли бы разрешить, скажем, отображение «только для чтения», вы могли бы предоставить диалоговое предупреждение…

Вы бы действительно избавили от множества проблем и бесполезного кода (большая часть спагетти с результатом / намерением).

Комментарии:

1. Сначала я подумал, что это был бы хороший метод, и я думаю, что это все еще так. Я думал, что у меня мог бы быть основной класс, который обрабатывал бы запуск всего с помощью SetResult (), вместо того, чтобы строить поверх других. Конечно, в небольшом приложении ваш способ, вероятно, был бы лучше. Скорее всего, я сделаю это таким образом, если переделаю это приложение или создам другое подобное. Спасибо!

2. Всегда пожалуйста. Рад, что вы нашли способ заставить это работать. Я мало что знал о singleTop, singleTask, singleInstance, так что спасибо, что разместили это здесь.

Ответ №3:

Возможный подход заключается в том, чтобы иметь класс, расширяющий Application и пару Activity привязанных к нему. private boolean logged Значение может определить, нужно ли Display вызывать LogIn на передний план.

 public class MyApp extends Application {
    private static boolean logged = false;
    private Activity logInActivity;
    private Activity displayActivity;
    public void onCreate () {
        super.onCreate();
    }
    public void setDisplayActivity (Activity act) {
        displayActivity = act;
    }
    public void setLogInActivity (Activity act) {
        logInActivity = act;
    }
    public void finishActivities (Activity act) {
        activity.finish();
    }
    public void setLogged (boolean logged) {
        this.logged = logged;
    }
    public boolean isLogged () {
        return logged;
    }
    public Activity getLoginActivity() {
        return logInActivity;
    }
    public Activity getDisplayActivity() {
        return displayActivity;
    }
}

class Display extend Activity {
    private MyApp app;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        app = (MyApp) getApplicationContext();
        if (!app.isLogged()) {
            // start LogInActivity. After log in, it will call app.setLogged (true);
        }
        else {
            // continue with Display;
        }
    }
}
  

Комментарии:

1. Определенно не тот способ, который у меня был раньше. Спасибо за предложение, я довольно новичок в разработке Android, поэтому все еще многому учусь с тем, как действия, намерения, приложения и т.д. все работает. Я обязательно буду ссылаться на это в своем следующем приложении для Android.