发布网友 发布时间:2022-04-23 12:07
共3个回答
热心网友 时间:2023-07-16 21:35
1、Launcher进程启动过程可以由下面图看到Launcher进程是如何被创建启动:ActivityManager通过发送Intend来启动Launcher。Intentintent=newIntent(mTopAction,mTopData!=null?Uri.parse(mTopData):null);intent.setComponent(mTopComponent);if(mFactoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL){intent.addCategory(Intent.CATEGORY_HOME);}startActivityLocked(null,intent,null,null,0,aInfo,null,null,0,0,0,false,false);复制代码因此,如果你要开机启动一个替换Launcher的程序,只要在程序里面加入action.MAIN、category.HOME、category.DEFAULT就可以。如果出现多个程序都加入这种intent,系统会弹出让你选择哪个作为启动器。2、Launcher初始化——LauncherApplication。Application类,我想大部分做Android应用的朋友都用过,每个Android应用默认都有一个Application类,你也可以继承Application类,然后加入自己代码。Application是一个全局的应用类,在AndroidManifest.xml我们也可以找到Application标签。复制代码Android四大组件的声明都需要放到application标签里面,默认使用的是系统的Application类,如果你在项目里面重载了它。就需要在标签,name属性下写上你的新的Application类名。Launcher里面就是继承了Application为LauncherApplication。应用启动的时候首先会加载Application。我们可以看到Launcher主类Launcher.java的onCreate函数里面,第一个就是获取Application的实例。LauncherApplicationapp=((LauncherApplication)getApplication());复制代码接下来我们看看LauncherApplication里面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是一些返回接口。@OverridepublicvoidonCreate(){super.onCreate();//获取屏幕大小,主要用来区分手机还是平板finalintscreenSize=getResources().getConfiguration().screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK;sIsScreenLarge=screenSize==Configuration.SCREENLAYOUT_SIZE_LARGE||screenSize==Configuration.SCREENLAYOUT_SIZE_XLARGE;//屏幕密度sScreenDensity=getResources().getDisplayMetrics().density;//IconCahe里面保存了界面所有应用图标的绘画需要的数据,这个到时候具体分析再说。//加入这东西的主要原因是为了提高绘画界面的效率mIconCache=newIconCache(this);//数据库加载类,LauncherModel是Launcher里面非常重要的一个类,相当于MVC模式里面的//Model功能,管理数据和初始化数据mModel=newLauncherModel(this,mIconCache);//下面注册了一些*,主要包含APK文件更新删除等数据变化的时候接收的通知//接收通知后,主要是用来更新Launcher里面的数据库。因为桌面应用图标数据,只会加载一次IntentFilterfilter=newIntentFilter(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_REMOVED);filter.addAction(Intent.ACTION_PACKAGE_CHANGED);filter.addDataScheme("package");registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);filter.addAction(Intent.ACTION_LOCALE_CHANGED);filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);registerReceiver(mModel,filter);filter=newIntentFilter();filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);registerReceiver(mModel,filter);//contentresolver则是用于管理所有程序的contentprovider实例ContentResolverresolver=getContentResolver();//注册内容观察者,监听application数据库变化,回调resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI,true,mFavoritesObserver);}复制代码上面是LauncherApplication最主要的工作,初始化整个Launcher的一些关键类,和注册一些*。主要都是用来监听应用的安装更新删除等导致Launcher数据库变化的操作。Launcher数据都是使用contentprovider来提供数据。其中注册的监听接口是privatefinalContentObservermFavoritesObserver=newContentObserver(newHandler()){@OverridepublicvoidonChange(booleanselfChange){//重新加载界面数据mModel.startLoader(LauncherApplication.this,false);}};复制代码LauncherSettings.Favorites.CONTENT_URI里面数据发生变化的时候,都会调用mModel.startLoader()接口,重新加载Launcher的数据。startLoader的具体操作,我后面分析LauncherModel类的时候会分析。这一块涉及Launcher所有数据加载。剩下的接都是返回初始化时候创建的对象或者获取屏幕密度、获取是否大屏幕。后面很多处理都需要判断是否是大屏幕,4.0以后手机平板都共用一套系统,导致多了很多处理。3、Launcher.java初始化Launcher.java是Launcher里面最主要的类,是一个Activity。启动的第一个组件。既然是Activity,我们要分析它初始化,毫无疑问,需要找到onCreate()里面分析。把主要一些分析用注释方式写在代码里面,这样比较方便阅读。
热心网友 时间:2023-07-16 21:36
微软的
热心网友 时间:2023-07-16 21:36
一、修改Android Studio(以下简称AS)的内存配置
因为在导入源码时需要消耗大量内存,所以先修改IDEA_HOME/bin/studio.vmoptions(x86的机器修改studio.vmoptions)中-Xms和-Xmx的值。文档中使用的是748m, 可自行修改。
二、配置AS的JDK、SDK
在IDE中添加一个没有classpath的JDK, 这样可以确保使用源码里的库文件
并将其作为要使用的SDK的Java SDK。
三、生成导入AS所需配置文件(*.ipr)
①编译源码(为了确保生成了.java文件,如R.java;如果编译过,则无需再次编译)
②检查out/host/linux-x86/framework/目录下是否有idegen.jar
如果idegen.jar不存在,执行:
mmm development/tools/idegen/
在5.0.1的源码中会生成res.java的文件夹,导致idegen.jar运行时抛FileNotFoundException,这是idegen的代码不够严谨造成的。
我的分享里有修改这个bug的patch,或者直接使用我分享的idegen.jar。
③执行
development/tools/idegen/idegen.sh
等待出现类似下面的结果:
Read excludes: 5ms
Traversed tree: 44078ms
这时会在源码的根目录下生成android.ipr和android.iml两个IntelliJ IDEA(AS是基于IntelliJ IDEA社区版开发的)的配置文件
Tips:
AS在导入代码时比较慢,建议先修改android.iml,将自己用不到的代码exclude出去.可以仿照过滤.repo文件夹的语法,如:
<excludeFolder url="file://$MODULE_DIR$/.repo" />
<excludeFolder url="file://$MODULE_DIR$/abi" />
<excludeFolder url="file://$MODULE_DIR$/art" />
删除掉所有不需要的mole-library项
这样在导入时就会跳过abi和art文件夹.过滤的越多,AS的处理速度就会越快.
④在AS中打开源码根目录下新生成的android.ipr
如果在导入时AS出现
则建议按照其给定的解决方法来解决(网址:http://confluence.jetbrains.com/display/IDEADEV/Inotify+Watches+Limit)
四、解决源码中跳转错误问题
①为当前工程设置正确的SDK和JDK
②设置'Moles'的依赖
先将所有依赖删掉(注意:这里删除全部只是为了方便。如果确实用到了.jar,在将它们的路径添加进来就可以了.
如:5.0.1的ContactsCommon用到了geocoder-2.9.jar和libphonenumber-6.2.jar)
点击指向的'Jars or directories'选项,依次将frameworks和external文件夹添加进来.如:
注:推荐把frameworks和external这两个移到最上面,这样在代码跳转时会优先从这两个文件夹下查找,而不是在Android.jar中查找。
其它版本的代码在添加frameworks时可能会显示成:
没有关系,只是显示问题,点击OK还是会把frameworks路径添加进去的.
如果还有代码跳转错误,请仿照上面的步骤将相应代码的路径或jar文件添加到其Dependencies标签页中即可.
五、DEBUG源码
可以通过给刚导入的工程在'Moles'中添加'Android Framework'来让AS将它作为一个Android工程,从而方便调试代码.
可以来添加Android Framework支持.
在代码中加断点,然后选择'Run'->'Attach debugger to Android process'
在弹出的选择进程(Choose Process)对话框中,勾选显示所有进程,选择要DEBUG的代码所在的进程,点击OK即可.
六、其它
代码中很多地方提示Call requires API Level x.... 出现这个问题是因为AS将工程当做安卓应用程序工程了,且源码中没有指定minSdkVersion.
只需在源码根目录加一个声明minSdkVersion的AndroidManifest.xml文件即可(分享了一个AndroidManifest.xml)。
也可以考虑使用build.gradle来解决该问题。