Базовый запрос о том, что происходит со стеком в приложении Java ME - PullRequest
1 голос
/ 31 января 2012

Я прихожу в Java ME с фоном Java SE (который по сути не имеет опыта работы с GUI / ActionListener) и все еще немного дезориентирован отсутствием метода main (). Возможно, я должен сказать, что я изучил Java SE должным образом, но пытаюсь научить себя Java ME, прибегая к поиску большого количества страниц «Java ME для чайников», что не идеально. Я предполагал, что мне это сойдет с рук, но теперь я гораздо менее уверен.

Чтобы запустить скрипт Java ME, я пишу код для базового класса, но у меня нет статического метода main (). Вместо этого я заставляю класс расширять MIDlet, а затем пишу методы startApp (), pauseApp () и destroyApp (). Эти методы не выглядят статичными (в том смысле, что приложение «Здравствуй, мир», которое я здесь рассматриваю, не создает их как статические методы).

Первый вопрос: когда я запускаю свой мидлет, скажем, на моем телефоне, создается ли экземпляр базового класса в стеке?

После этого я еще больше растерялся. Предположительно, ответ на мой первый вопрос - да, и я могу назвать этот случай «этим». Теперь в StartApp () я собираюсь создать форму и отобразить ее. Так что часть моего кода выглядит так:

public class TestMidlet extends MIDlet implements CommandListener {

    List mainForm;
    Command comSelect;

    protected void startApp() throws MIDletStateChangeException {

        mainForm = new List("Menu",List.IMPLICIT);

        mainForm.append("this one?",null);
        mainForm.append("or this one?",null);

        comSelect=new Command("Select",Command.ITEM,1);
        mainForm.setSelectCommand(comSelect);
        mainForm.setCommandListener(this);

        Display.getDisplay(this).setCurrent(mainForm);
    }

    public void commandAction(Command c,Displayable d) {
        // we will end up here when the user makes a selection in mainForm.
    }

Когда мидлет запускается, я подозреваю, что в стеке создается экземпляр TestMidlet. Затем запускается метод startApp (), который создает форму и отображает ее на экране. Теперь, на мой наивный взгляд, теперь произойдет следующее: в startApp () заканчиваются команды для выполнения, а затем он завершается.

Второй вопрос: прав ли я, предполагая, что (a) startApp () действительно завершается, но (b) экземпляр TestMidlet по какой-то причине не становится доступным для сборки мусора, потому что каким-то образом форма поддерживает его работу с помощью commandListener ? На данный момент мне неясно, есть ли в данный момент работающий стек. Предположительно, дело в том, что безымянный TestMidlet сам по себе является CommandListener и, следовательно, все еще занят, поэтому не хочет становиться доступным для сборки мусора, несмотря на то, что я не вижу ничего, ссылающегося на него.

Наконец, когда пользователь делает выбор в форме, этот безымянный экземпляр TestMidlet возвращается в действие в том смысле, что его метод commandAction () начинает работать? И, в частности, я все еще могу получить доступ к этому таинственному безымянному экземпляру TestMidlet в его методе commandAction, используя «this»?

Есть ли у меня все это прямо?

1 Ответ

2 голосов
/ 31 января 2012
  1. когда вы запускаете свой мидлет на своем телефоне, экземпляр TestMidlet создается так же, как это происходит для new Object()
    Вы можете сослаться на вышеупомянутый экземпляр как this

  2. startApp() - это типичный "метод шага" согласно Шаблонный шаблон
    учитывая ваш опыт Java SE, я ожидаю, что это звучит знакомо Здесь нет никакой магии - думайте об этом как о некоторой структуре, вызывающей startApp() в ходе выполнения последовательности жизненного цикла, которая невидима для вас. Ищите в сети что-то вроде жизненного цикла мидлета , если вас интересует более подробная информация.

  3. при последнем утверждении в startApp этот метод действительно завершается - вы здесь. Но, кроме того, на самом деле ничего волшебного не происходит - экземпляр TestMidlet жив и исправен, работает под «средой MIDP» до тех пор, пока пользователь не остановит ваше приложение или ваш код не вызовет notifyDestroyed () на экземпляре TestMidlet

  4. относительно сборки мусора, вы можете смело применять общее понимание, взятое здесь из Java SE, за исключением отсутствующего метода Object.finalize() (будьте готовы к тому, что в MIDP отсутствуют некоторые другие методы и классы, к которым вы привыкли в Java SE)

  5. этот безымянный экземпляр TestMidlet возвращается в действие в том смысле, что его метод commandAction () начинает выполняться - , если , вы правильно установили прослушиватель команд и добавили команду. И, в частности, вы все еще можете получить доступ к этому таинственному безымянному экземпляру TestMidlet в его методе commandAction, используя «квалифицированное» JLS 15.8.4 Квалифицированное , как TestMidlet.this

Учитывая, насколько вы путаетесь со всеми этими командами и слушателями, я бы порекомендовал избавиться от , который реализует CommandListener в вашем экспериментальном коде, примерно так:

public class TestMidlet extends MIDlet {

    List mainForm;
    Command comSelect;

    protected void startApp() throws MIDletStateChangeException {

        mainForm = new List("Menu",List.IMPLICIT);

        mainForm.append("this one?",null);
        mainForm.append("or this one?",null);
        mainForm.append("Exit",null);

        comSelect=new Command("Select",Command.ITEM,1);
        mainForm.addCommand(comSelect); // note addCommand here
        mainForm.setSelectCommand(comSelect); // convenient thing BTW

        mainForm.setCommandListener(new CommandListener() {
            public void commandAction(Command c,Displayable d) {
                // we'll end up here when the user makes a selection in mainForm.                   
                List list = (List)d;
                // note d refers to mainForm here, that's why it's OK to cast above
                if (list.getString(list.getSelectedIndex()).equals("Exit")) {
                    // if user selected exit
                    TestMidlet.this.notifyDestroyed(); // exit the midlet
                }
            }
        });
        // display the form
        Display.getDisplay(this).setCurrent(mainForm);
        // startApp finishes here
    }
}

У меня все это прямо?

Не совсем. Учитывая ваши вопросы, похоже, что вы переросли уровень страниц "Java ME для чайников" , так что пришло время перейти к более серьезным ресурсам.

Вещи, которые стоит проверить:

Имейте в виду, что существует более новая версия спецификации MIDP - JSR 271 , хотя я бы не советовал углубляться в нее, если вы определенно не знаете, что вы нацеливаетесь на эту версию.

Некоторые трудности, с которыми вы сталкиваетесь, связаны с тем фактом, что ваш фон по существу не связан с интерфейсом GUI / ActionListener . Будьте готовы, что потребуется некоторое время, чтобы приспособиться к «мышлению в стиле UI». Если вы еще не читали его, проверьте Учебное пособие по J2ME, часть 2: Пользовательские интерфейсы с MIDP 2.0 на java.net

...