21

我现在已经在一些教程中看到了这一点……但是,Android 源代码怎么可能没有 main 方法并且仍然可以运行。

例如(来自http://developer.android.com/guide/tutorials/hello-world.html):

public class HelloAndroid extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

运行,但没有主要!

我还认为使用诸如 onCreate(或 formLoad 等)之类的东西是不好的,因为构造函数应该完成这项工作,而且这种内置方法有时会很臭。但是 onCreate 是一个入口点吗?即使没有主线?

如果有多个活动怎么办......这些内置事件处理程序是否存在层次结构?OnCreate 胜过一切?否则,应用程序如何知道要运行什么或在哪里进入程序?

谢谢!

4

13 回答 13

14

每个应用程序都将拥有自己的虚拟机。要在其空间 (VM) 内运行应用程序,必须有一个 main 方法。

活动不是为启动应用程序而调用的实际类。有一个名为 Application 的类,它将是要启动的应用程序的根类。

如果没有 main 方法,虚拟机如何识别应用程序的启动方式?

框架有名为 Process、VMRuntime 的类,它们负责启动应用程序。这确实处理主要方法。

为了更好的理解,研究一下Android的Zygote服务。处理 Applicationmanager Service、ActivityStack Activity Threadds 等。

于 2012-12-14T11:08:01.997 回答
9

运行,但没有主要!

当然。许多您可能认为是 Java“应用程序”的东西并没有自己的main()方法。例如,IIRC、servlet、WAR 等没有main()方法——main()方法(如果有的话)在容器中。

但是 onCreate 是一个入口点吗?

onCreate()是一种方法。

如果有多个活动怎么办......这些内置事件处理程序是否存在层次结构?

并不真地。

OnCreate 胜过一切?

并不真地。

否则,应用程序如何知道要运行什么或在哪里进入程序?

应用程序不“知道要运行什么或在哪里进入程序”。

Android 应用程序是一篮子组件。某些组件可能与主屏幕启动器中的图标相关联。某些组件可能与计划的计时器相关联,例如 cron 作业或 Windows 计划任务。某些组件可能与系统事件相关联,例如将设备放入汽车底座或从汽车底座中取出时。这些组件将在适当的时候自动创建和使用(例如,当用户点击主屏幕启动器中的图标时)。然而,其他组件仅在您的代码明确要求时才会创建和使用。

将 Android 应用程序视为一个单一的控制台模式 Java 程序会给您带来无穷无尽的麻烦。

于 2010-11-19T02:15:34.047 回答
6

实际上,这种类型的模式并不是 Android 特有的,但只要中间有一些框架,就会发生这种情况。一些基本示例是 java Applet 和 Servlet。一些答案已经提供了正确的答案,但我会尝试详细说明一下。

当你启动一个 Java 应用程序时,你启动了一个 JVM,然后你需要向其中加载一些东西:所以你需要一个静态方法(主方法),因为 JVM 中还没有你可以引用的对象。

如果中间有某种框架,它将启动 JVM 并开始使用自己的服务对象填充它:编写代码然后意味着编写自己的对象(这将是给定“模板”的子类)。然后框架可以注入(加载)您的对象。框架服务对象通过调用“模板”超类中定义的生命周期方法来管理注入对象的生命周期。

因此,例如,当您向浏览器提供小程序时,您不会启动静态 main 方法:您只需要提供 java.applet.Applet 的子类,它实现了一些作为回调来管理生命周期的实例方法(init、paint , 停止...)。浏览器将启动 JVM,实例化启动小程序所需的内容,加载您的小程序并调用它。

同样,使用 servlet,您可以继承 javax.servlet.http.HttpServlet 类并实现一些实例(非静态)方法(doGet、doPost...)。Web 容器(例如 Tomcat)将负责启动 JVM、实例化启动 servlet 所需的内容、加载您的 servlet 并调用它。

Android 中的模式几乎相同:您所做的就是创建一个 android.app.Activity 的子类。当你启动一个应用程序时,系统会在清单中查找应该启动哪个活动,然后“框架”加载它并调用它的实例方法(onCreate、onPause、onResume...)。

于 2014-01-15T11:40:22.550 回答
6

您在清单文件中告诉它在启动时运行哪一个。没有 main() 因为不必有,main 可能是用于“常规”Java 应用程序的约定,但不适用于浏览器小程序之类的东西。系统创建活动对象并调用其中的方法,这些方法可能称为或不称为 main。在这种情况下,它不是。

onCreate 与 main 和构造函数不同,因为它可以在单个活动上调用两次,例如如果进程被终止并且用户导航回活动。请参阅http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

于 2010-11-19T02:15:18.217 回答
4

在 Java 程序中,我们需要一个 main() 方法,因为在执行字节码时,JVM 会在类中搜索 main() 方法并开始执行。

在 Android 中,Dalvik 虚拟机旨在找到一个类,该类是 Activity 的子类,并且设置为从其 onCreate() 方法开始执行应用程序,因此不需要 main() 方法。

Dalvik 虚拟机调用方法的顺序基于称为 android 生命周期的优先级顺序,有关 android 生命周期的更多信息,请查看 Android 生命周期下面的链接:https ://developer.android.com/guide/components/activities/活动生命周期.html

于 2017-06-26T17:22:41.920 回答
2

android 程序员应该像手背一样学习这一点,它简单地解释了一切,并且在将来创建活动时会有所帮助。 http://developer.android.com/reference/android/app/Activity.html

于 2013-06-06T16:29:36.877 回答
2

虽然没有特定的主入口点,但意图过滤器描述了启动应用程序时启动的活动。它们在 AndroidManifest.xml 中进行控制,如下所述:

http://developer.android.com/guide/topics/intents/intents-filters.html

其中描述了记事本应用程序示例:

此过滤器声明 Note Pad 应用程序的主要入口点。标准的 MAIN 动作是一个入口点,它不需要 Intent 中的任何其他信息(例如,没有数据规范),而 LAUNCHER 类别表示该入口点应该列在应用程序启动器中。

于 2011-04-25T10:25:57.890 回答
1

Applet 也没有 main() 方法。这仅取决于您的代码是如何打包的。

于 2010-11-19T06:27:12.393 回答
1

有一个主要的,它只是碰巧不在你的手中。毕竟,main任何语言的函数都没有什么特别之处。它只是您的代码开始执行的入口点。Android 操作系统希望应用程序具有一定的结构,并根据您遵循的约定调用您的代码。

于 2010-11-19T02:17:13.707 回答
1

我发现这特别有用...

http://developer.android.com/guide/topics/fundamentals.html#appcomp

于 2010-11-19T02:23:38.327 回答
0

我认为乔纳森的回答是朝着正确的方向发展的。他说操作系统需要某种结构。该结构有一个名称,即“状态机”。在这种情况下,Android 将其称为“活动生命周期”。Rob 提供了一个文档链接,其中包含该状态机的重要图表,尽管文本有点枯燥。快速搜索还发现了以下链接,该链接解释得很清楚:http ://www.android-app-market.com/android-activity-lifecycle.html

于 2012-09-26T06:59:22.297 回答
0

Android UI框架封装了一些Java常用的细节,可以学习android UI框架的源码

于 2010-11-19T02:27:23.693 回答
-2

在 Java 中,有一个 main 即使它没有被列为main(). 单击图标后获得的页面,无论其名称如何,都是main().

于 2012-10-11T16:35:27.733 回答