`
anson_xu
  • 浏览: 512973 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类

Launcher的启动过程

阅读更多

1.  Launcher的启动过程

从网络上找了一段关于Launcher 的启动过程的文章,作为学习 Launcher 的背景知识:

Linux kernel 启动以后会通过 a pp_main 进程来初始化android Runtime Java运行环境,而 zygote A ndroid的第一个进程。所有的android的应用以及大部分系统服务都是通过zygote fork出来的子进程( 我现在看到的只有native的service manager不是zygote fork出来的) 。在system server中启动的若干系统服务中与我们启动进程相关的就是 Acitivity Manager
  当 systerm server启动好所有服务以后,系统就进入”system ready”状态,这个时候Activity Manager就登场了。 Activity Manager光看代码行就知道是一个重量级的服务,它主要管理Activity之间的跳转,以及进程的生命周期。当 Activity Manager发现系统已经启动好以后它就会发出一个intent:

  1. Intent intent =  new  Intent(mTopAction, mTopData !=  null  ? Uri.parse(mTopData) :  null );  
  2. intent.setComponent(mTopComponent);  
  3. if  (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  4.     intent.addCategory(Intent.CATEGORY_HOME);  
  5. }  

通过这个category类型为home的intent,Activity Manager就会通过:
 
  1. startActivityLocked( null , intent,  null null , 0, aInfo,  
  2.  null null , 0, 0, 0,  false false );  

启动 Home 进程了。而这个启动Home进程的过程实际上还是去通过zygote fork出的一个子进程。

因此只要在manifest中具备这样的intent-filter都可以在开机的时候作为Home启动:

  1. <intent-filter>  
  2. <action android:name="android.intent.action.MAIN"  />  
  3. <category android:name="android.intent.category.HOME" />  
  4. <category android:name="android.intent.category.DEFAULT"  />  
  5. </intent-filter>  

多个home之间的switch会在开始的时候有个选择,至于这个选择好像是package manager来实现的,没有仔细研究过。

2.UI结构

通过 launcher/Res/Layout-land/launcher.xml 分析可以得到主屏幕的UI 结构:

 

整个homescreen是一个包含三个child view的FrameLayout(com.android.launcher.DragLayer)。


第一个child就是桌面 com.android.launcher.Workspace。这个桌面又包含三个child。每个child就对应一个桌面。这就是你在 Android上看到的三个桌面。每个桌面上可以放置下列对象:应用快捷方式,appwidget和folder。


第二个child是一个 SlidingDrawer控件,这个控件由两个子控件组成。一个是com.android.launcher.HandleView,就是 Android桌面下方的把手,当点击这个把手时,另一个子控件,com.android.launcher.AllAppsGridView就会弹出, 这个子控件列出系统中当前安装的所有类型为category.launcher的Activity。


第三个child是com.android.launcher.DeleteZone。当用户在桌面上长按一个widget时,把手位置就会出现一个垃圾桶形状的控件,就是这个控件。

3.应用程序代码分析

Launcher 中的 AndroidManifest.xml 可以看出整个Launcher 的代码结构。

首先,是一些权限的声明。例如:

  1. <uses-permission android:name= "android.permission.CALL_PHONE"  />  
  2. <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"  />  
 

这部分可以略过;

其次,Application 的构成,如上图:

 

(1) Launcher HomeScreen Activity


  1. <intent-filter>  
  2.  <action android:name="android.intent.action.MAIN"  />  
  3.  <category android:name="android.intent.category.HOME" />  
  4.  <category android:name="android.intent.category.DEFAULT"  />  
  5. <category android:name="android.intent.category.MONKEY"  /> </intent-filter>  

上面这段代码就标志着它是开机启动后Home Activity 。通过 Launcher.java onCreat() 的分析我们可以大致把握屏幕的主要活动:

 

  1. protected   void  onCreate(Bundle savedInstanceState) {  
  2.         super.onCreate(savedInstanceState);  
  3. //把xml文件的内容实例化到View中   
  4.         mInflater = getLayoutInflater();  
  5. //监听应用程序控件改变事件   
  6.         mAppWidgetManager = AppWidgetManager.getInstance(this );  
  7.         mAppWidgetHost = new  LauncherAppWidgetHost( this , APPWIDGET_HOST_ID);  
  8.         mAppWidgetHost.startListening();  
  9. // 用于调试?       
  10.         if  (PROFILE_STARTUP) {  
  11.             android.os.Debug.startMethodTracing("/sdcard/launcher" );  
  12.         }  
  13.   //监听locale,mcc,mnc是否改变,如果改变,则重写新配置   
  14.       //mcc:mobile country code(国家代码China 460); mnc:mobile network code(网络代码)   
  15.         checkForLocaleChange();  
  16.        /*This allows such applications to have a virtual wallpaper that is larger than the physical screen, matching the size of their workspace.*/   
  17.         setWallpaperDimension();  
  18. //显示主屏幕UI元素,workspace,slidingdrawer(handleview and appgridview),deletezone   
  19.         setContentView(R.layout.launcher);  
  20. //Finds all the views we need and configure them properly.   
  21. //完成workspace,slidingdrawer,deletezone的各种事件操作和监听   
  22.         setupViews();  
  23. //Registers various intent receivers.   
  24. //允许其他应用对本应用的操作   
  25.         registerIntentReceivers();  
  26. //Registers various content observers.   
  27. //例如,注册一个内容观察者跟踪喜爱的应用程序   
  28.         registerContentObservers();  
  29. //重新保存前一个状态(目的??)   
  30.         mSavedState = savedInstanceState;  
  31.         restoreState(mSavedState);  
  32. //调试?   
  33.         if  (PROFILE_STARTUP) {  
  34.             android.os.Debug.stopMethodTracing();  
  35.         }  
  36. //Loads the list of installed applications in mApplications.   
  37.         if  (!mRestoring) {  
  38.             startLoaders();  
  39.         }  
  40.         // For handling default keys??   
  41.         mDefaultKeySsb = new  SpannableStringBuilder();  
  42.         Selection.setSelection(mDefaultKeySsb, 0);  
  43.     }  
 

方法 onActivityResult(): 完成在workspace 上增加 shortcut appwidge Livefolder

方法 onSaveInstantceState() onRestoreInstanceState() :为了防止 Sensor Land Port 布局自动切换时数据被置空,通过 onSaveInstanceState 方法可以保存当前窗口的状态,在即将布局切换前将当前的 Activity 压入历史堆栈。如果我们的 Activity 在后台没有因为运行内存吃紧被清理,则切换时回触发 onRestoreIntanceState()


(2) WallpaperChooser :设置墙纸。

同理我们从onCreat() 作为入口来分析这个活动的主要功能。

  1. public   void  onCreate(Bundle icicle) {  
  2.         super.onCreate(icicle);  
  3. //设置允许改变的窗口状态,需在 setContentView 之前调用   
  4.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  5. / /添加墙纸资源,将资源标识符加入到动态数组中  
  6.         findWallpapers();  
  7. //显示墙纸设置屏幕的UI元素,Imageview,Gallery and Button(LinearLayout)   
  8.         setContentView(R.layout.wallpaper_chooser);  
  9. //图片查看功能的实现   
  10.         mGallery = (Gallery) findViewById(R.id.gallery);  
  11.         mGallery.setAdapter(new  ImageAdapter( this ));  
  12.         mGallery.setOnItemSelectedListener(this );  
  13.         mGallery.setCallbackDuringFling(false );  
  14. //Button事件监听,点击选择setWallpaper(Resid)   
  15.         findViewById(R.id.set ).setOnClickListener( this );  
  16.         mImageView = (ImageView) findViewById(R.id.wallpaper);  
  17.     }  
 

 

(3) default_searchable

对于home 中任意的 Acitivty ,使能系统缺省 Search 模式,这样就可以使用 android 系统默认的 search UI


 

(4) InstallShortcutReceiver

继承自BroadcastReceiver ,重写 onReceier() 方法,对于发送来的 Broadcast (这里指 Intent )进行过滤( IntentFilt )并且响应(这里是 InstallShortcut() )。这里分析下 onReceive():

  1. <!-- Enable system- default  search mode  for  any activity  in  Home -->  
  2. <!-- Intent received used to install shortcuts from other applications -->  
  3. public   void  onReceive(Context context, Intent data) {  
  4.        //接受并过滤Intent   
  5. if  (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {  
  6.             return ;  
  7.         }  
  8.       //获取屏幕   
  9.         int  screen = Launcher.getScreen();  
  10. //安装快捷方式   
  11.         if  (!installShortcut(context, data, screen)) {  
  12.             //如果屏幕已满,搜寻其他屏幕   
  13.             for  ( int  i = 0; i < Launcher.SCREEN_COUNT; i++) {  
  14.                 if  (i != screen && installShortcut(context, data, i))  break ;  
  15.             }  
  16.         }  
  17.     }  
 

其中 IntallShortcut() 方法:首先,对传入的坐标进行判断(findEmptyCell() , 如果是空白位置,则可以放置快捷方式;其次,缺省情况下,我们允许创建重复的快捷方式,具体创建过程( addShortcut() )就是把快捷方式的信息传入数据库( addItemToDatabase() )。


(5) UninstallShortcutReceiver

同理,UninstallShortcutReceiver() 继承自 BroadcastReceiver() ,实现 onReceiver() 方法。定义一个 ContentResolver 对象完成对数据库的访问和操作(通过 URI 定位),进而删除快捷方式 。


 

(6) LauncherProvider

继承自ContentProvider() ,主要是建立一个数据库来存放 HomeScreen 中的数据信息,并通过内容提供者来实现其他应用对 launcher 中数据的访问和操作。

重写了ContentProvider() 中的方法

getType():返回数据类型。如果有自定义的全新类型,通过此方法完成数据的访问。

query():查询数据。传入 URI ,返回一个 Cursor 对象,通过 Cursor 完成对数据库数据的遍历访问。

I nsert():插入一条数据。

bulkInsert():大容量数据的插入。

delete():删除一条数据。

update():更改一条数据。

sendNotify():发送通知。

DatabaseHelper 继承自一个封装类 SQLiteOpenHelper(), 方便了数据库的管理和维护。

重写的方法:

onCreate():创建一个表。其中 db.execSQL() 方法执行一条 SQL 语句,通过一条字符串执行相关的操作。当然,对 SQL 基本语句应该了解。

onUpgrade():升级数据库。

HomeScreen 数据库操作的一些方法:

addClockWidget(),addSearchWidget,addShortcut,addAppShortcut,

loadFavorites(),launcherAppWidgetBinder(),convertWidget(), updateContactsShortcuts (),

copyFromCursor( )

补充:

AddAdapter (AddAdapter.java)列出了这四个类型对象。当用户在桌面空白处长按时,下列函数序列被执行:

Launcher::onLongClick -->

Launcher::showAddDialog -->

Launcher::showDialog(DIALOG_CREATE_SHORTCUT); -->

Launcher::onCreateDialog -->

Launcher::CreateShortcut::createDialog:这个函数创建一个弹出式对话框,询问用户是要添加什么(快捷方式,appwidget, 文件夹和墙纸)其内容就来自AddAdapter。

DesktopItemsLoader 负责将桌面上所有的对象从content provider中提取。

线程private  ApplicationsLoader  mApplicationsLoader负责从包管理器中获取系统中安装的应用列表。(之后显示在AllAppsGridView上)。ApplicationsLoader::run实现:
1)通过包管理器列出系统中所有类型为Launcher,action为MAIN的activity;
2)对每一个Activity,
       a) 将Activity相关元数据信息,如title, icon, intent等缓存到appInfoCache;
         b) 填充到ApplicationsAdapter 中。填充过程中用到了一些小技巧,每填充4(UI_NOTIFICATION_RATE)个activity更新一下相应view。

在Launcher::onCreate中,函数startLoaders被调用。而该函数接着调用loadApplications和loadUserItems,分别获取系统的应用列表,以及显示在桌面上的对象列表(快捷方式,appwidget,folder等)。
Launcher 上排列的所有应用图标由AllAppsGridView对象呈现。这个对象是一个GridView。其对应的Adapter是 ApplicationsAdapter,对应的model则是ApplicationInfo数组。数组内容是由ApplicationsLoader 装载的。

分享到:
评论

相关推荐

    android系统从systemserver开始的launcher启动详细流程

    通过处理消息队列来实现对Launcher启动过程的监控。 ##### 回到ActivityManagerService.startHomeActivityLocked 这是启动Launcher的另一个重要环节,确保系统能够正确识别并启动Launcher。 ##### ...

    在android模拟器中调试Launcher模块代码

    5.1 使用`adb shell am start -W`命令,可以查看 Launcher 启动过程的详细性能数据,帮助优化启动时间。 5.2 如果需要调试特定的Intent处理,可以在模拟器上长按应用图标,选择“Open with”选项,然后选择调试版的...

    android2.3 launcher分析三

    **Launcher 启动过程** - Launcher 的启动涉及 Android 系统服务的初始化,包括 ActivityManagerService 和 PackageManagerService。 - 主Activity(Launcher)在系统启动后被启动,通过 Intent ACTION_MAIN 和 ...

    android系统从systemserver开始的launcher启动详细流程.doc

    Android 系统启动流程是一个复杂的过程,从 SystemServer 开始到 Launcher 的启动涉及到多个组件和服务的协作。本文将详细介绍 Android 系统从 SystemServer 开始的 Launcher 启动流程,并对其中的关键组件和服务...

    Android Launcher 分析

    #### 一、Launcher启动过程解析 Android Launcher 的启动流程是一个非常重要的概念,对于理解Android系统的启动机制以及如何定制自己的Launcher应用有着关键的作用。 **1.1 Linux Kernel 启动与Android Runtime ...

    Car Launcher桌面启动器自定义配置白痴教程(内含桌面主题启动器APK).rar

    "需要清空别的文件 直接升级" 表明在升级过程中,用户需要确保U盘内没有其他无关文件,以保证升级过程的顺利进行,且原有数据将被保留,这意味着Car Launcher在升级时对用户个人设置的兼容性较好。 【标签】 虽然...

    Android 启动Launcher

    ### Android启动Launcher详解 #### 一、LauncherApplication的初始化过程 ...通过以上步骤,Launcher完成了从启动到展示桌面的整个过程。这一系列操作确保了用户能够快速且流畅地访问他们常用的程序和功能。

    浅谈android性能优化之启动过程(冷启动和热启动)

    Android 应用程序启动优化之冷启动和热启动详解 一、应用程序启动方式 ...了解 Android 应用程序的启动过程对于优化应用程序的性能非常重要,可以根据应用程序的启动方式和启动过程来进行相应的优化处理。

    Zygote启动流程-systemServer启动流程-homeLauncher启动

    通过对Zygote启动流程以及systemServer和Home Activity启动过程的详细解析,我们不仅了解了Android系统启动过程中的关键步骤和技术细节,还深入了解了ART虚拟机的工作原理。这些深入的理解对于开发者来说至关重要,...

    机顶盒launcher

    "机顶盒launcher"是一种专为智能电视或机顶盒设计的应用启动器,它采用了"tab+viewpager"的组合模式来提供用户界面。在Android系统中,Launcher是用户与设备交互的入口,用于展示和启动各种应用程序。下面将详细探讨...

    Game Launcher for miHoYo - 米家游戏启动器.zip

    对于《米家游戏启动器》这样的游戏启动器来说,开发者可能会利用.NET的多线程能力优化游戏的下载和更新过程,同时利用C#的强类型和面向对象特性来组织和管理复杂的游戏数据。 "说明.txt"文件通常是提供关于压缩包...

    javalauncher

    在开发和调试Java应用程序时,理解Java Launcher的工作机制可以帮助我们更好地控制程序的启动过程,解决类加载、依赖管理和性能优化等问题。 此外,Java Launcher还与Java的模块系统(Java Platform Module System...

    Androidlauncher开发.pdf

    同时,我们还需要了解 Android 系统的启动过程,包括 Linux Kernel 的启动、App_main 进程的初始化、zygote 的 fork 过程、Activity Manager 的启动等。只有了解这些基础知识,我们才能开发出一个功能强大且美观的 ...

    Android_launcher源码全面分析

    1、Launcher进程启动过程 当用户按下桌面应用图标时,系统会启动一个新的进程用于运行Launcher应用。这个过程中,系统会加载必要的资源和组件,准备启动界面。 2、Launcher初始化――LauncherApplication ...

    Android 4.4.2 Launcher3 源码 eclipse 可直接编译

    4. **Intent解析**:分析Intent的创建和解析过程,理解如何通过Intent启动不同应用。 5. **内存管理**:学习Android的内存管理和垃圾回收机制,优化Launcher3的性能。 6. **动画效果**:查看源码中如何实现平滑的...

    Android代码-Launcher3

    Launcher3的启动流程(一) 细说ItemInfo Launcher3的启动流程(二) Launcher3分析之拖动图标的流程——按下 Launcher3分析之拖动图标的流程——移动 Launcher3分析之拖动图标的流程——放下 PagedView的原理 – ...

    android Launcher2.2源码

    这一过程涉及到ActivityManagerService的调度,以及Intent的解析,源码中的`com.android.launcher2.Launcher$LoaderCallbacks`类处理了数据加载的逻辑。 6. **动态壁纸与小部件** Android 2.2支持动态壁纸和小部件...

    Launcher.rar基于AS

    用户可以通过Launcher启动其他应用程序,设置桌面壁纸,以及管理手机上的应用。 当我们谈论基于Android Studio(简称AS)的Launcher源码调试时,这意味着我们将使用Google提供的强大集成开发环境(IDE)来分析和...

    Launcher2源码分析

    当Launcher启动时,它需要加载壁纸、快捷方式、文件夹等大量数据。这个过程由ContentProvider、Loader和CursorAdapter共同完成。ContentProvider负责从系统数据库中读取数据,Loader则在后台线程中异步加载数据,...

    分析Android Activity的启动过程

    分析Android Activity的启动过程 Android Activity的启动过程是一个复杂的过程,涉及到多个组件之间的交互和协作。本文将从源码的角度分析Activity的启动过程,并详细介绍其中的每一个步骤。 步骤1: Launcher向...

Global site tag (gtag.js) - Google Analytics