关于 Java ME 应用程序中堆栈发生情况的基本查询
我以 Java SE 背景(基本上不涉及 GUI/ActionListener 经验)开始使用 Java ME,但由于缺少 main() 方法,我仍然有点迷失方向。也许我应该说我正确地学习了 Java SE,但我试图通过谷歌搜索大量“Java ME for dummies”页面来自学 Java ME,这并不理想。我原以为我会逃脱惩罚,但现在我不太确定了。
为了启动并运行 Java ME 脚本,我为基类编写代码,但没有静态 main() 方法。相反,我让类扩展 MIDlet,然后编写方法 startApp()、pauseApp() 和 destroyApp() 。不过,这些方法似乎不是静态的(从某种意义上说,我在这里看到的“hello World”应用程序不会将它们创建为静态方法)。
那么第一个问题是:当我开始在手机上运行 MIDlet 时,基类的实例实际上是在堆栈上创建的吗?
之后我就更加迷茫了。想必我的第一个问题的答案是肯定的,我可以将该实例称为“this”。现在在 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.
}
当启动 MIDlet 时,我怀疑在堆栈上创建了一个 TestMidlet 实例。然后运行 startApp() 方法,该方法创建一个表单并将其显示在屏幕上。现在,在我天真的眼中,接下来发生的事情是 startApp() 现在用完要执行的命令,然后完成。
第二个问题:我是否正确地假设(a)startApp()实际上完成了,但是(b)TestMidlet的实例由于某种原因无法用于垃圾回收,因为表单以某种方式通过commandListener保持它的活动状态?此时我真的不清楚是否存在当前正在运行的堆栈。据推测,重点是未命名的 TestMidlet 本身就是一个 CommandListener,因此仍然很忙,因此不希望可用于垃圾回收,尽管事实上我看不到任何引用它的内容。
最后,当用户在表单中做出选择时,这个未命名的 TestMidlet 实例会重新启动,因为它的 commandAction() 方法开始运行?特别是我仍然可以使用“this”在其 commandAction 方法中访问 TestMidlet 的这个神秘的未命名实例?
我有这一切吗?
I am coming to Java ME with a Java SE background (which involves essentially no GUI/ActionListener experience) and am still a little disorientated by the lack of a main() method. Perhaps I should say that I learnt Java SE properly but am attempting to teach myself Java ME by googling for lots of "Java ME for dummies" pages, which is not ideal. I had assumed that I'd get away with it, but am much less sure now.
To get a Java ME script up and running, I write code for a base class, but have no static main() method. Instead I make the class extend MIDlet and then write methods startApp(), pauseApp() and destroyApp() . These methods do not appear to be static though (in the sense that the "hello World" app I'm looking at here doesn't create them as static methods).
First question then: when I start running my MIDlet on, say, my phone, is an instance of the base class actually created on the stack?
After that, I'm even more confused. Presumably the answer to my first question is yes, and I can refer to the instance as "this". Now in StartApp() I'm going to create a Form and display it. So part of my code looks like this:
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.
}
When the MIDlet is launched, I suspect an instance of TestMidlet is created on the stack. The method startApp() is then run, which creates a form and displays it on the screen. Now to my naive eyes, what happens next is that startApp() now runs out of commands to execute, and then finishes.
Second question: am I right in assuming that (a) startApp() does actually finish but (b) the instance of TestMidlet for some reason does not become available for garbage collection, because somehow the form is keeping it alive via commandListener? I am really unclear, at this point, about whether there is a currently-running stack. Presumably the point is that the unnamed TestMidlet is itself a CommandListener and is hence still busy, so doesn't want to become available for garbage collection despite the fact that I can't see anything referring to it.
Finally, when the user makes a choice in the form, this unnamed instance of TestMidlet springs back into action in the sense that its commandAction() method starts running? And in particular I can still access this mysterious unnamed instance of TestMidlet in its commandAction method, using "this"?
Do I have all this straight?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您开始在手机上运行 MIDlet 时,会以与
new Object()
相同的方式创建 TestMidlet 实例您可以将上面的实例称为
this
startApp()
是一个典型的“步骤方法”,按照 模板方法模式考虑到您的 Java SE 背景,我希望这听起来很熟悉。这里真的没有什么魔力 - 将其视为在运行生命周期序列的过程中调用
startApp()
的框架,这对您来说是不可见的。如果您对更多详细信息感兴趣,请在网络上搜索MIDlet 生命周期之类的内容。在
startApp
中的最后一个语句处,这个方法确实完成了——你就在这里。但更进一步,实际上并没有什么神奇的事情发生 - TestMidlet 实例运行良好,在“MIDP 框架”下运行,直到用户停止您的应用程序或您的代码调用 notifyDestroyed() 在 TestMidlet 的实例上关于垃圾回收,您可以安全地应用来自 Java SE 的一般理解,保存缺少的方法
Object.finalize()< /code> (一般要做好准备,MIDP 缺少一些您在 Java SE 中习惯的其他方法和类)
这个未命名的 TestMidlet 实例会重新启动,因为它的 commandAction () 方法开始运行 - 如果您正确设置了命令侦听器并添加了命令。特别是,您仍然可以在其 commandAction 方法中访问这个神秘的未命名 TestMidlet 实例,使用“qualified this”JLS 15.8.4 限定 this 就像
TestMidlet.this
考虑到您对以下内容感到有多少困惑所有这些命令和侦听器,我建议在实验代码中删除 implements CommandListener ,大约如下:
不完全是。鉴于您的问题,您似乎已经过度增长了“Java ME for dummies”页面的级别,因此是时候切换到更严肃的资源了。
值得检查的事情有:
请记住,有是 MIDP 规范的较新版本 - JSR 271,尽管我不建议深入研究它,除非您明确知道您的目标是这个版本。
您遇到的一些困难来自于您的背景基本上不涉及 GUI/ActionListener 经验。请做好心理准备,适应“UI 风格思维”需要一些时间。如果您还没有阅读过,请查看 J2ME 教程,第 2 部分:java.net 上的 MIDP 2.0 用户界面
when you start running your MIDlet on your phone an instance of the TestMidlet is created in the same way as it happens for
new Object()
you can refer to above instance as
this
startApp()
is a typical "step method" as per Template method patterngiven your Java SE background I expect it sounds familiar. No magic here really - think of it as some framework invoking
startApp()
in the course of running life cycle sequence which is invisible to you. Search web for something like MIDlet life cycle if you're interested in more details.at the last statement in
startApp
this method finishes indeed - you are right here. But further, nothing magical happens really - TestMidlet instance is alive and well, running under "MIDP framework" until either user stops your application or your code invokes notifyDestroyed() on the instance of TestMidletregarding garbage collection, you can safely apply general understanding taked from Java SE here, save the missing method
Object.finalize()
(be generally prepared that MIDP lacks some other methods and classes you get used to in Java SE)this unnamed instance of TestMidlet springs back into action in the sense that its commandAction() method starts running - if you properly set command listener and added a command. And in particular you can still access this mysterious unnamed instance of TestMidlet in its commandAction method, using "qualified this" JLS 15.8.4 Qualified this like
TestMidlet.this
Given how much confusion you feel related to all these commands and listeners, I would recommend to get rid of implements CommandListener in your experimental code, about as follows:
Not quite. Given your questions it looks like you overgrown level of "Java ME for dummies" pages so that it's about time to switch to more serious resources.
Things worth checking are:
Keep in mind that there is a newer version of MIDP specification - JSR 271, although I would not recommend diving into it unless you definitely know that you are targeting this version.
Some of the difficulties you experience come from the fact that your background involves essentially no GUI/ActionListener experience. Be prepared that it will take some time to adjust to "UI style thinking". If you didn't read it yet, check J2ME Tutorial, Part 2: User Interfaces with MIDP 2.0 at java.net