1.1.3-用JMCCC简单启动MC
2.三分钟带你了解Android 系统启动流程详解
3.å¦ä½è®¾ç½®ç³»ç»å¯ä¸ç launcher
4.å¦ä½å¯å¨ä¸ä¸ªè¢«homeçandroidåºç¨ç¨åº
1.3-用JMCCC简单启动MC
在上文中,源码我们已经成功设置了基础的分析Java环境,接下来将构建Minecraft的源码启动器。请注意,分析如果你使用的源码是JMCCC 3,其语法与2版本存在差异,分析编译源码和原生代码区别建议先阅读章节1.7(链接未给出)。源码
游戏文件并非凭空而来,分析虽然启动器本身有下载功能,源码但这里我们先自己准备游戏文件夹,分析即.minecraft文件夹。源码你可以通过下载整合包或使用其他启动器(如官方、分析HMCL或PCL)下载游戏,源码然后将文件夹导入项目。分析
导入文件时,源码只需将文件拖入项目文件夹,系统会弹出窗口进行选择。如果出现“.minecraft文件夹已存在,是html 效果源码否覆盖?”的提示,选择“覆盖”或“全部覆盖”即可。也可直接在资源管理器中操作,将文件夹直接拖入项目。
删除原有的“Hello World!”代码,使用Ctrl+D快捷键,然后开始编写启动器。启动Minecraft大致需要几个步骤:
首先,创建游戏容器,ffmpeg player源码通过Launcher类的Launcher方法来创建。初次使用时会提示未引用“Launcher”和“LauncherBuilder”,这时通过鼠标悬停并选择“import”进行引用。
接下来,设置启动参数。LaunchOption类中有版本控制、登录方式和游戏文件夹等参数,尽管可以用中文,但建议使用英文以避免问题。boll源码同花顺添加引用后,可能需要添加try/catch语句来处理可能出现的异常。
异常处理是捕捉并处理程序运行中的异常,Java要求使用Checked Exception。有两种处理方式:一是使用“throws IOException”,将异常抛给调用者自行处理;二是使用try/catch,捕获异常并进行日志记录。
最后一步是使用launch方法启动游戏,但同样需要在try/catch语句中执行。android 定位源码启动时可能有多种异常情况,根据需要选择合适的异常处理方式。
以下是完成后的源代码示例:
完成后,运行程序,你应能看到初步的启动效果。
三分钟带你了解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ä¸çåºç¨ç¨åºä¿¡æ¯ååºæ¥ï¼ç¶å以快æ·å¾æ çå½¢å¼å±ç¤ºå¨æ¡é¢ä¸ï¼åé¢æ们å°ä¼çå°è¿ä¸ªè¿ç¨ã