皮皮网

【ea源码翻译】【mtd源码包】【原型制作源码】launcher3源码分析

2024-12-24 11:20:21 来源:蜂窝论坛源码

1.1.3-用JMCCC简单启动MC
2.三分钟带你了解Android 系统启动流程详解
3.如何设置系统唯一的 launcher
4.如何启动一个被home的android应用程序

launcher3源码分析

1.3-用JMCCC简单启动MC

       在上文中,源码我们已经成功设置了基础的分析Java环境,接下来将构建Minecraft的源码启动器。请注意,分析如果你使用的源码是JMCCC 3,其语法与2版本存在差异,分析ea源码翻译建议先阅读章节1.7(链接未给出)。源码

       游戏文件并非凭空而来,分析虽然启动器本身有下载功能,源码但这里我们先自己准备游戏文件夹,分析即.minecraft文件夹。源码你可以通过下载整合包或使用其他启动器(如官方、分析HMCL或PCL)下载游戏,源码然后将文件夹导入项目。分析

       导入文件时,源码只需将文件拖入项目文件夹,系统会弹出窗口进行选择。如果出现“.minecraft文件夹已存在,是mtd源码包否覆盖?”的提示,选择“覆盖”或“全部覆盖”即可。也可直接在资源管理器中操作,将文件夹直接拖入项目。

       删除原有的“Hello World!”代码,使用Ctrl+D快捷键,然后开始编写启动器。启动Minecraft大致需要几个步骤:

       首先,创建游戏容器,原型制作源码通过Launcher类的Launcher方法来创建。初次使用时会提示未引用“Launcher”和“LauncherBuilder”,这时通过鼠标悬停并选择“import”进行引用。

       接下来,设置启动参数。LaunchOption类中有版本控制、登录方式和游戏文件夹等参数,尽管可以用中文,但建议使用英文以避免问题。永恒冒险 源码添加引用后,可能需要添加try/catch语句来处理可能出现的异常。

       异常处理是捕捉并处理程序运行中的异常,Java要求使用Checked Exception。有两种处理方式:一是使用“throws IOException”,将异常抛给调用者自行处理;二是使用try/catch,捕获异常并进行日志记录。

       最后一步是使用launch方法启动游戏,但同样需要在try/catch语句中执行。unity vive 源码启动时可能有多种异常情况,根据需要选择合适的异常处理方式。

       以下是完成后的源代码示例:

       完成后,运行程序,你应能看到初步的启动效果。

三分钟带你了解Android 系统启动流程详解

       Android系统的核心运行机制——Activity Manager Service (AMS)掌控着系统组件的管理和调度,包括应用进程的生命周期管理。面试中,面试官常问关于启动流程、system_server在Zygote中的角色等问题。以下是对这些核心点的分析:

       1. 系统启动流程:启动从电源按钮按下开始,引导程序执行,分为两个阶段——检测RAM并加载第二阶段程序,接着设置网络等,为内核运行做准备。内核启动后,swapper进程和kthreadd进程相继启动,初始化内存管理和驱动。

       2. Zygote与system_server:system_server并非由init直接启动,而是通过Zygote进程孵化,因为这样可以实现更高效的应用进程创建。Zygote负责孵化应用进程,避免system_server过载。

       3. 死锁与IPC通信:Zygote不采用Binder机制进行进程间通信,可能是因为其设计策略注重性能和效率,避免了复杂的跨进程通信机制。

       4. 深入理解:图示中,Loader层负责引导,Kernel层启动内核和驱动,Native层孵化守护进程和系统服务,如System Server和Media Server。Zygote进程孵化Launcher和各种App进程,提供用户界面和服务。

       掌握Android系统启动流程和底层机制对于开发者至关重要,尤其在竞争激烈的行业中。为了应对挑战,建议系统学习,例如《Android Framework源码开发揭秘》提供深入剖析,涵盖了启动流程、IPC通信、核心组件解析等内容,适合有一定经验的开发者提升技术理解。

如何设置系统唯一的 launcher

       ã€€ã€€å®šä¹‰ä¸€ä¸ªç§æœ‰çš„filter选项,然后用这个选项来过滤HOME.

       ã€€ã€€ä¸€èˆ¬æƒ…况下我们使用Manifest中定义的<category android:name="android.intent.category.HOME"来过滤的,

       ã€€ã€€æˆ‘们现在增加一个私有的HOME_FIRST过滤。

       ã€€ã€€åœ¨Intent.java(frameworks/base/core/java/android/content/Intent.java)中添加两行代码

       ã€€ã€€//lixinso:添加CATEGORY_HOME_FIRST

       ã€€ã€€@SdkConstant(SdkConstantType.INTENT_CATEGORY)

       ã€€ã€€public static final String CATEGORY_HOME_FIRST = "android.intent.category.HOME_FIRST";

       ã€€ã€€3)修改和CATEGORY_HOME相关的所有的地方,都改成HOME_FIRST,主要是framework中的这几个地方:

       ã€€ã€€frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中

       ã€€ã€€//intent.addCategory(Intent.CATEGORY_HOME);

       ã€€ã€€æ”¹æˆintent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso:

       ã€€ã€€//if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {

       ã€€ã€€æ”¹æˆif (r.intent.hasCategory(Intent.CATEGORY_HOME_FIRST)) { //lixinso: Intent.CATEGORY_HOME -> Intent.CATEGORY_HOME_FIRST

       ã€€ã€€frameworks/base/services/java/com/android/server/am/HistoryRecorder.java中

       ã€€ã€€// _intent.hasCategory(Intent.CATEGORY_HOME) &&

       ã€€ã€€æ”¹æˆ _intent.hasCategory(Intent.CATEGORY_HOME_FIRST) && //lixinso: Intent.CATEGORY_HOME->Intent.CATEGORY_HOME_FIRST

       ã€€ã€€frameworks/policies/base/mid/com/android/internal/policy/impl/MidWindowManager.java中

       ã€€ã€€//mHomeIntent.addCategory(Intent.CATEGORY_HOME);

       ã€€ã€€æ”¹æˆ mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso

       ã€€ã€€frameworks/policies/base/mid/com/android/internal/policy/impl/RecentApplicationsDialog.java中

       ã€€ã€€//new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);

       ã€€ã€€æ”¹æˆ new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0); //lixinso

       ã€€ã€€frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java中

       ã€€ã€€//mHomeIntent.addCategory(Intent.CATEGORY_HOME);

       ã€€ã€€æ”¹æˆ mHomeIntent.addCategory(Intent.CATEGORY_HOME_FIRST); //lixinso

       ã€€ã€€frameworks/policies/base/phone/com/android/internal/policy/impl/RecentApplicationsDialog.java中

       ã€€ã€€//ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),0);

       ã€€ã€€æ”¹æˆ ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME_FIRST),0); //lixinso

       ã€€ã€€4) 写一个自己的Launcher.

       ã€€ã€€å¯ä»¥å‚考android sample中的Launcher,或者android源代码中的 /packages/apps/Launcher 来写。

       ã€€ã€€åœ¨Launcher中标记其是不是Launcher的最关键的代码时Manifest中的filter:android:name="android.intent.category.HOME"

       ã€€ã€€çŽ°åœ¨æˆ‘们定义了自己的filter,那么,我们在我们自己写的Launcher中将Manifest改为:

       ã€€ã€€<application android:process="android.process.acore3" android:icon="@drawable/icon" android:label="@string/app_name">

       ã€€ã€€<activity android:name=".FirstAppActivity"

       ã€€ã€€android:label="@string/app_name">

       ã€€ã€€<intent-filter>

       ã€€ã€€<action android:name="android.intent.action.MAIN" />

       ã€€ã€€<category android:name="android.intent.category.HOME_FIRST" />

       ã€€ã€€<category android:name="android.intent.category.DEFAULT" />

       ã€€ã€€<category android:name="android.intent.category.MONKEY" />

       ã€€ã€€</intent-filter>

       ã€€ã€€</activity>

       ã€€ã€€</application>

       ã€€ã€€ç„¶åŽå°†ç¼–译好的apk放到/out/target/product/generic/system/app目录下。

       ã€€ã€€5)将Android自带的Launcher删除掉,包括源代码(packages/apps/Launcher)和apk(/out/target/product/generic/system/app/Launcher.apk)。

       ã€€ã€€6)

       ã€€ã€€åšå®Œè¿™äº›å·¥ä½œï¼Œå°±å¯ä»¥é‡æ–°ç¼–译Android了,我们可以编译修改过的几个相关的包。

       ã€€ã€€å¦‚果之前编译过了Android源码,可以用mmm命令来编译部分的改动。

       ã€€ã€€è¿™é‡Œéœ€è¦è¿™æ ·ç¼–译:

       ã€€ã€€$ . build/envsetup.sh

       ã€€ã€€$ mmm frameworks/base

       ã€€ã€€$ mmm frameworks/base/services/java

       ã€€ã€€$ mmm frameworks/policies/base/mid

       ã€€ã€€$ mmm frameworks/policies/base/phone

       ã€€ã€€7)

       ã€€ã€€ç¼–译完成后重新生成img文件。

       ã€€ã€€$ make snod

       ã€€ã€€8) 现在可以启动Android模拟器来看效果了。

       ã€€ã€€é¦–先设置环境变量:

       ã€€ã€€$ export ANDROID_PRODUCT_OUT= ./out/target/product/generic

       ã€€ã€€ç„¶åŽåˆ‡æ¢åˆ°

       ã€€ã€€$ cd ./out/host/linux-x/bin

       ã€€ã€€è¿è¡Œ

       ã€€ã€€$ ./emulator

       ã€€ã€€è¿™æ ·æˆ‘们启动的模拟器里面用的image就是我们刚才编译好的自己定制的东西了。

       ã€€ã€€ä»Žæ¨¡æ‹Ÿå™¨ä¸Šå¯ä»¥çœ‹åˆ°å¯åŠ¨çš„Launcher是我们自己的Launcher,不会出现默认的Launcher了,也不会出现选择界面。

如何启动一个被home的android应用程序

       ã€€ã€€Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动的,SystemServer组件首先是启动ePackageManagerServic,由它来负责安装系统的应用程序,具体可以参考前面一篇文章Android应用程序安装过程源代码分析,系统中的应用程序安装好了以后,SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就可以使用这些应用程序了,整个过程如下图所示:

               下面详细分析每一个步骤。

               Step 1. SystemServer.main

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/services/java/com/android/server/SystemServer.java文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 1。

               Step 2. SystemServer.init1

               è¿™ä¸ªå‡½æ•°æ˜¯ä¸€ä¸ªJNI方法,实现在 frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 2。

               Step 3. libsystem_server.system_init

               å‡½æ•°system_init实现在libsystem_server库中,源代码位于frameworks/base/cmds/system_server/library/system_init.cpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 3。

               Step 4. AndroidRuntime.callStatic

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/core/jni/AndroidRuntime.cpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 4。

               Step 5. SystemServer.init2

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/services/java/com/android/server/SystemServer.java文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 5。

               Step 6. ServerThread.run

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/services/java/com/android/server/SystemServer.java文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 6。

               Step 7. ActivityManagerService.main

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件中:

       [java] view plaincopy

       public final class ActivityManagerService extends ActivityManagerNative  

               implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   

           ......  

         

           public static final Context main(int factoryTest) {   

               AThread thr = new AThread();  

               thr.start();  

         

               synchronized (thr) {   

                   while (thr.mService == null) {   

                       try {   

                           thr.wait();  

                       } catch (InterruptedException e) {   

                       }  

                   }  

               }  

         

               ActivityManagerService m = thr.mService;  

               mSelf = m;  

               ActivityThread at = ActivityThread.systemMain();  

               mSystemThread = at;  

               Context context = at.getSystemContext();  

               m.mContext = context;  

               m.mFactoryTest = factoryTest;  

               m.mMainStack = new ActivityStack(m, context, true);  

         

               m.mBatteryStatsService.publish(context);  

               m.mUsageStatsService.publish(context);  

         

               synchronized (thr) {   

                   thr.mReady = true;  

                   thr.notifyAll();  

               }  

         

               m.startRunning(null, null, null, null);  

         

               return context;  

           }  

         

           ......  

       }  

               è¿™ä¸ªå‡½æ•°é¦–先通过AThread线程对象来内部创建了一个ActivityManagerService实例,然后将这个实例保存其成员变量mService中,接着又把这个ActivityManagerService实例保存在ActivityManagerService类的静态成员变量mSelf中,最后初始化其它成员变量,就结束了。

               Step 8. PackageManagerService.main

               è¿™ä¸ªå‡½æ•°å®šä¹‰åœ¨frameworks/base/services/java/com/android/server/PackageManagerService.java文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 7。执行完这一步之后,系统中的应用程序的所有信息都保存在PackageManagerService中了,后面Home应用程序Launcher启动起来后,就会把PackageManagerService中的应用程序信息取出来,然后以快捷图标的形式展示在桌面上,后面我们将会看到这个过程。