【问题标题】:Where is main() in Android?Android中的main()在哪里?
【发布时间】:2023-04-01 09:35:01
【问题描述】:

我是 Android 新手,正在研究框架,这迫使我提出这个问题。由于我们在 Android 中扩展 Activity,因此必须在 Activity 中的某个位置存在 main,或者存在 Activity 实现的包含 main 的隐藏类。

我到处找,但找不到。如果有人能给出一个明确的想法,我将不胜感激。

【问题讨论】:

    标签: java android


    【解决方案1】:

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

    在Android的情况下,Dalvik虚拟机(在android 5.0 DVM被Android Runtime取代后)被设计为找到一个类,它是Activity的子类,并且被设置为一个LAUNCHER来开始执行应用程序来自其onCreate() 方法,因此不需要main() 方法。

    更多信息请查看Activity的生命周期。

    【讨论】:

    • @BasimallaSebastin 如果这能最好地回答你的问题,请接受这个作为答案。
    • 您的解释描述了当用户打开应用程序时Android如何决定启动哪个Activity,但这与底层应用程序框架启动过程无关(这实际上是相当复杂的)。 main() 方法在 Android 框架类 android.app.ActivityThread 中。此方法创建主 (UI) Thread,在其上设置 Looper 并启动事件循环。 Android 框架的其他部分处理启动/停止操作系统进程、启动应用程序、活动和服务以及其他组件等。
    • @DavidWasser,你是对的,但我试图尽可能简单地回答它。 OP 无法理解 main() 并回答如果我们开始解释 ActivityThread、Looper 等没有任何意义。
    • 实际上,Application 类(或Application 的子类)的onCreate()ActivityonCreate() 之前被调用。此外,还有一些以ServiceBroadcastReceiver 开头而不是Activity 开头的Android 应用程序。
    【解决方案2】:

    其实main()方法就是Android框架类android.app.ActivityThread。此方法为 OS 进程创建主 (UI) Thread,在其上设置 Looper 并启动事件循环。

    Android 框架负责创建和销毁操作系统进程、启动应用程序、启动活动、服务和其他组件。 ActivityManager 是 Android 框架的一部分,它负责协调和管理不同的组件。

    Android 的架构与您习惯的独立 Java 应用程序有些不同。最大的不同是您的所有组件(ActivityServiceBroadcastReceiver 等)不一定运行在同一个 OS 进程或同一个虚拟机 (VM) 中。可以让来自单个应用程序的组件在不同的操作系统进程中运行,也可以让来自不同应用程序的组件在同一操作系统进程中运行。在传统Java中,main()方法是在创建OS进程并且虚拟机完成初始化后,虚拟机调用的方法。

    【讨论】:

    • +1 但非常准确地说,主线程和 UI 线程在 android 上可能不一样。见stackoverflow.com/questions/40784584/…
    • @YTerle 感谢您的链接。对于所有意图和目的(即:普通应用程序),主线程和 UI 线程是相同的。如果您阅读链接的答案,则只有一个例外,这是 Android 框架本身的一部分。
    【解决方案3】:

    Android 使用 java 语言,但使用修改后的运行时模型执行。正如其他人所说,每个包中都包含一个清单。启动点在此清单中指定。转到 android 站点并完成基本教程。这将使您了解创建/部署/运行过程和基本的应用生命周期。

    【讨论】:

      【解决方案4】:

      阅读 this 博客文章,了解 Android 应用程序是如何启动的:

      在 Android 系统启动过程中,Linux 内核首先调用 进程“初始化”。 init 读取文件“/init.rc”和“init.device.rc”。 “init.device.rc”是设备特定的,在虚拟设备上这个文件 被称为“init.goldfish.rc”。

      init.rc 通过程序“/system/bin/app_process”启动进程“Zygote”。 Zygote 加载核心 Java 类和 对它们进行初始处理。这些类可以被重用 Android 应用程序,因此这一步使他们更快地 开始。一旦 Zygote 的初始工作完成,进程就会监听 一个套接字并等待请求。

      如果您查看 ZygoteInit 类,您会找到 main 方法。

      正如其他人所提到的,这个main() 方法涉及设置Android 应用程序环境。对于开发者而言,起点是 Launcher 活动的onCreate() 方法。

      【讨论】:

      • 实际上,Application 类(或Application 的子类)的onCreate()onCreate()Activity 之前调用。此外,有些 Android 应用程序以ServiceBroadcastReceiver 开头,而不是Activity
      • ZygoteInit 的链接是 (A) “死”和 (B) 拼写错误。
      【解决方案5】:

      在 Android 中,操作系统使用 Dalvik 虚拟机。应用程序执行的主要入口点封装在框架内。您可能想看看“What is Android?

      事实上,Android 中的每个 Activity 都可以被认为是一个独立的应用程序,具有自己的生命周期。

      【讨论】:

      • 是的....那更抽象。我很欣赏你的回答,但如果它是一个 java 类,它没有 main 并且它会启动。
      【解决方案6】:
      onCreate() Method....See lifecycle of android class (Activity).....
      

      http://developer.android.com/reference/android/app/Activity.html

      【讨论】:

      • 感谢您的回答,但如果它是一个 java 类,它怎么会没有 main 并且它会启动
      • 第一个Android应用必须以Activity开头(这是java类扩展Activity)...然后先调用oncreate
      【解决方案7】:

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

      onCreate 不同于main() 方法和构造函数,因为它可以在单个活动上调用两次,例如如果进程被终止并且用户导航回活动。见this

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

      【讨论】:

      • 感谢您的回答,但如果它是一个 java 类,它怎么会没有 main 并且它会启动
      【解决方案8】:

      当你启动一个新进程运行一个App/Service,最后在ActivityManagerService.java中,有:

      final String entryPoint = "android.app.ActivityThread";
      
      return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                      runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                      startTime);
      

      最终调用 Process.start。这和标准的java是一样的,你传入一个类,然后VM创建一个新进程并执行ActivityThread.java的main():

      public static void main(String[] args) {
               ......
          Looper.loop();
      
          throw new RuntimeException("Main thread loop unexpectedly exited");
      }
      

      主函数会触发一些动作,发送IPC消息通知ActivityManager进程启动成功,然后在通知发起新进程启动的进程该事件后,ActivityManager会通知新进程做真正的activity启动过程,根据manifest创建Activity类,然后调用OnCreate等。

      这里有一些完全错误的答案,得到了很多选票,希望温和派等可以检查一下。

      【讨论】:

        【解决方案9】:

        查看它从 main() 开始的堆栈帧。

        【讨论】:

          猜你喜欢
          • 2016-02-21
          • 2018-04-30
          • 1970-01-01
          • 2016-02-07
          • 2014-10-15
          • 2023-04-02
          • 2017-02-13
          • 2019-10-14
          相关资源
          最近更新 更多