`
isiqi
  • 浏览: 16483116 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

launcher.apk的分析报告

阅读更多

Launcher.apk是android runtime的一部分,是系统起来运行的第一个应用程序。它的主要功能就是设置桌面背景图片,加载两个widget(桌面的小应用程序),分别是clock 和search。然后设置menu按键后的内容,并实现具体的功能。Oncreate()是它运行的第一个函数。

Oncreate()

clip_image001|--setMinimumHeapSize(4M)

|--mInflater = getLayoutInflater() 新建一个layout的解压缩器

|--setWallpaperDimension() 设置横屏和竖屏的坐标参数

|-- enableSensors(); 检查sensor是否已经打开

|-- enableOpenGL(); 检查opengl是否已经打开

|-- setupViews(); 主要是画桌面背景

|--registerIntentReceivers(); 注册IntentReceivers来监测状态的变化以便相应的产生动作

|-- registerContentObservers(); 注册ContentObservers

|--restoreState() 保存状态

|--startLoaders() 用来加载其他应用程序和用户items,函数具体实现在LauncherModel.java中

clip_image002 |--loadApplications() Loads the list of installed applications in mApplications.

|--new ApplicationsAdapter()

|--mLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT) (mLoader是一个线程)

|--new ApplicationsLoader() (mApliacationsLoader是一个线程)

clip_image003 |--Intent(Intent.ACTION_MAIN, null) 其他应用程序Manifest.xml中会用到

|--mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)

|--Launcher launcher = mLauncher.get() {AllAppsGridView.java}

|--PackageManager manager = launcher.getPackageManager()

|-- manager.queryIntentActivities(mainIntent, 0)

|--ChangeNotifier action = new ChangeNotifier(applicationList) (ChangeNotifier 是一个线程)

|--用一个循环把所有的app都加载进来

|--loadUserItems()

|--launcher.onDesktopItemsLoaded() {launcher.java中onDesktopItemsLoaded()}

clip_image004[4] |--bindDesktopItems() Refreshes the shortcuts shown on the workspace

|--ItemInfo item = shortcuts.get(i)

|--switch (item.itemType)

|--case Settings.Favorites.ITEM_TYPE_APPLICATION:

case Settings.Favorites.ITEM_TYPE_SHORTCUT:

|-- createShortcut((ApplicationInfo) item)

|-- createShortcut() 新建一个快捷方式

|--case Settings.Favorites.ITEM_TYPE_USER_FOLDER

|-- 建立一个新的USER_FOLDER(用户文件夹)

|-- default:

|-- createWidget(mInflater, widget)

|--openUserFolder() 建立一个新的USER_FOLDER(用户文件夹)

|--new DesktopItemsLoader(launcher) DesktopItemsLoader是一个线程

clip_image005 |--int itemType = c.getInt(itemTypeIndex)

|--switch (itemType)

case Settings.Favorites.ITEM_TYPE_APPLICATION:

case Settings.Favorites.ITEM_TYPE_SHORTCUT:

|--intent = Intent.getIntent(c.getString(intentIndex))

|--case Settings.Favorites.ITEM_TYPE_USER_FOLDER

|--findOrMakeFolder(userFolders, id)

|--case Settings.Favorites.CONTAINER_DESKTOP

|--desktopItems.add(folderInfo) 添加到桌面上

|--case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK:

case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH:

case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:

clip_image006[4] |--switch (itemType)

|--case Settings.Favorites.ITEM_TYPE_WIDGET_CLOCK

|--Widget.makeClock() 添加一个时钟在当前界面上

|--case Settings.Favorites.ITEM_TYPE_WIDGET_SEARCH

|--Widget.makeSearch() 在当前界面上添加一个google search

|--case Settings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME

|--Widget.makePhotoFrame() 在当前界面添加一章小图片

还有一个重要的部分就是当menu按键按下时定义的内容。下面是函数的调用情况以及函数的功能

OnCreateOptionsMenu() 来定义menu的菜单

clip_image007 ADD 、SEARCH_SETTING、NOTIFICATION、WALLPAPER_SETTING、SETTING

OnPrepareOptionsMenu() display the menu

clip_image008[4]

OnOptionsItemSelected() 当选择了Menu中的选项时执行相应动作

clip_image009|--MENU_ADD

|--addItems()

|--showAddDilog()

|--showDialog()

|--MENU_WALLPAPER_SETTING

|--startWallpaper() {home.java}

|--intent(ACTION_SET_WALLPAPER) 启动一个intent来设置背景图片

|--MENU_SEARCH

|--onSearchRequested() {SearchInvoke.java}

|--MENU_NOTIFICATIONS

|--showNotifications()

|--getSystemService(STATUB_BAR_SERVICE) 启动系统的sevice来显示notification

|--MENU_SETTING

|--Intent(android.provider.Settings.ACTION_SETTINGS) 启动一个intent来进行系统的设置

startActivityForResult(Intent intent, int requestCode)用来启动一个intent并接收从它返回的数据,用setResult()来设置返回值,用onActivityResult(int requestCode, int resultCode, Intent data)对返回的数据进行相应的处理。

onActivityResult(int requestCode, int resultCode, Intent data)

|--completeAddShortcut(data, mAddItemCellInfo, !mDesktopLocked);

(requestCode=REQUEST_CREATE_SHORTCUT)

|-- sModel.addDesktopItem(info) {LauncherModel.java}

|-- mDesktopItems.add(info) 将ItemInfo info 加入到ArrayList<iteminfo>中</iteminfo>

|-- createShortcut(info)

|-- createShortcut() 新建一个快捷方式

|--completeAddPhotoFrame(data, mAddItemCellInfo); Add a PhotFrame to the workspace

(requestCode=REQUEST_CHOOSE_PHOTO)

|--completeUpdatePhotoFrame(data, mAddItemCellInfo); Updates a workspace PhotoFrame

(requestCode=REQUEST_UPDATE_PHOTO)

相关知识链接:

ContentObservers http://tech.it168.com/j/2008-02-25/200802250125273.shtml

Widget http://baike.baidu.com/view/704016.htm

IntentReceivers http://bbs2.chinaunix.net/archiver/tid-1320757.html

Intent http://developer.android.com/reference/android/content/Intent.html

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

相关知识:

Activity 知识:

activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上,当activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowIsFloating的主题集合),或者嵌入到其他的activity(使用ActivityGroup)。大部分的Activity子类都需要实现以下两个接口:

onCreate(Bundle)接口是初始化activity的地方. 在这儿通常可以调用setContentView(int)设置在资源文件中定义的UI, 使用findViewById(int) 可以获得UI中定义的窗口.

onPause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(通常用于ContentProvider保存数据).

为了能够使用Context.startActivity(),所有的activity类都必须在AndroidManifest.xml文件中定义有相关的“activity”项。

activity类是Android 应用生命周期的重要部分。

Activity生命周期

在系统中的Activity被一个Activity栈所管理。当一个新的Activity启动时,将被放置到栈顶,成为运行中的Activity,前一个Activity保留在栈中,不再放到前台,直到新的Activity退出为止。

Activity有四种本质区别的状态:

在屏幕的前台(Activity栈顶),叫做活动状态或者运行状态(active or running)

如果一个Activity失去焦点,但是依然可见(一个新的非全屏的Activity 或者一个透明的Activity 被放置在栈顶),叫做暂停状态(Paused)。一个暂停状态的Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被杀掉。

如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(Stopped)。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,Stopped的Activity将被杀掉。

如果一个Activity是Paused或者Stopped状态,系统可以将该Activity从内存中删除,Android系统采用两种方式进行删除,要么要求该Activity结束,要么直接杀掉它的进程。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。

下面的图显示了Activity的重要状态转换,矩形框表明Activity在状态转换之间的回调接口,开发人员可以重载实现以便执行相关代码,带有颜色的椭圆形表明Activity所处的状态。

clip_image011

在上图中,Activity有三个关键的循环:

整个的生命周期,从onCreate(Bundle)开始到onDestroy()结束。Activity在onCreate()设置所有的“全局”状态,在onDestory()释放所有的资源。例如:某个Activity有一个在后台运行的线程,用于从网络下载数据,则该Activity可以在onCreate()中创建线程,在onDestory()中停止线程。

可见的生命周期,从onStart()开始到onStop()结束。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等,例如:可以在onStart中注册一个IntentReceiver来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。onStart(),onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。

前台的生命周期,从onResume()开始到onPause()结束。在这段时间里,该Activity处于所有Activity的最前面,和用户进行交互。Activity可以经常性地在resumed和paused状态之间切换,例如:当设备准备休眠时,当一个Activity处理结果被分发时,当一个新的Intent被分发时。所以在这些接口方法中的代码应该属于非常轻量级的。

Activity的整个生命周期都定义在下面的接口方法中,所有方法都可以被重载。所有的Activity都需要实现onCreate(Bundle)去初始化设置,大部分Activity需要实现onPause()去提交更改过的数据,当前大部分的Activity也需要实现onFreeze()接口,以便恢复在onCreate(Bundle)里面设置的状态。

public class Activity extends ApplicationContext {

protected void onCreate(Bundle icicle);

protected void onStart();

protected void onRestart();

protected void onResume();

protected void onFreeze(Bundle outIcicle);

protected void onPause();

protected void onStop();

protected void onDestroy();

}

startActivity(Intent)接口用于启动一个新的activity,新的activity将被放置到activity栈顶。使用一个单一的参数:描述activity的执行动作的Intent。

有时候我们希望在activity结束的时候获得activity的反馈结果,例如:在一个activity中,让用户在一个联系人列表中选择某一个人,在该页面结束的时候,能够返回选中的人员信息。要做到这一点,需要调用startSubActivity(Intent, int)接口进行启动,第二个参数为调用者的标识。结果将在onActivityResult(int, int, String, Bundle)中返回。

当一个activity退出时,可以调用setResult(int)返回数据给上一级的activity。它必须支持结果编码,可以是标准的RESULT_CANCELED, RESULT_OK,或者从RESULT_FIRST_USER开始的自定义编码。此外,还可以返回一个字符串(通常是URL的某一项数据),也可以返回一个包含任意内容的包。所有的返回信息都会反馈到上一级的Activity.onActivityResult()接口,并带有上一级activity提供的原始标识号。

如果一个子activity失败了(如崩溃了),父activity将会接收到一个RESULT_CANCELED的结果编码。

public class MyActivity extends Activity

{

...

static final int PICK_CONTACT_REQUEST = 0;

protected boolean onKeyDown(int keyCode, KeyEvent event)

{

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {

// When the user center presses, let them pick a contact.

startSubActivity(

new Intent(Intent.PICK_ACTION,

new ContentURI(”content://contacts”)),

PICK_CONTACT_REQUEST);

return true;

}

return false;

}

protected void onActivityResult(int requestCode, int resultCode,

String data, Bundle extras)

{

if (requestCode == PICK_CONTACT_REQUEST) {

if (resultCode == RESULT_OK) {

// A contact was picked. Here we will just display it

// to the user.

startActivity(new Intent(Intent.VIEW_ACTION, data));

}

}

}

}

保存持久状态

一般来说,activity有两种持久状态需要处理:共享的文档类数据(典型的是使用了content provider存储在SQLite中),内在的状态(如用户的嗜好)。

针对内容提供的数据,google建议采用“编辑到位”的用户模型,也就是说,用户的编辑动作是立即有效的,无须进行额外的确认步骤,支持这个模式只需要简单遵守下面的两个规则:

当创建一个新的文档时,相关的数据库条目和文件都是立即创建的,例如:用户选择写一个新的电子邮件,一旦开始写,则新的电子邮件条目创建出来了。所以如果进入其他的activity,则这封电子邮件将会出现在草稿箱中。

当一个activity的onPause()接口被调用时,它应该提交用户的修改到内容提供者或者文件中。这样确保其他将要运行的activity能够看到这些变化。在整个activity的生命周期中,有很多时候都需要频繁提交数据,例如:在启动一个新的activity之前,在结束自己的activity之前,在输入字段进行切换的时候等等。

这个模型是为了防止用户在activity之间浏览时的数据丢失,允许系统在activity停止后的任何时间里安全地杀掉activity(因为系统资源要用在其他地方)。注意:这样意味着在activity里按了“返回”键并不等于“取消”,它意味着activity的当前数据被保存下来,离开了activity。在一个activity中要取消编辑动作必须有另外一套机制来实现,比如一个清晰的“恢复”或者“撤销”动作。

可以在content package里面查看更多的内容提供者信息,有一些重要的方面,在activity调用和activity之间的数据传递的不同。

activity也提供了一些API用于管理内在的状态,可以用在如浏览器中用户设置的缺省主页等。

activity的持久状态由getPreferences(int)来进行管理,允许获取或者修改一套“名字/值”的对。为了在多个应用程序组件(activities, receivers, services, providers)之间共享持久状态,可以使用Context.getSharedPreferences()接口获取一个共享对象。(注意:不可能跨越应用程序包来共享数据,但是可以使用内容提供者来做)

下面是一个例子,进行持久性设置:

public class CalendarActivity extends Activity { ... static final int DAY_VIEW_MODE = 0; static final int WEEK_VIEW_MODE = 1; private SharedPreferences mPrefs; private int mCurViewMode; protected void onCreate(Bundle icicle) { super.onCreate(icicle); SharedPreferences mPrefs = getSharedPreferences(); mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE); } protected void onPause() { super.onPause(); SharedPreferences.Editor ed = mPrefs.edit(); ed.putInt("view_mode", mCurViewMode); ed.commit(); } }

权限许可

当activity在manifest的<activity> 标签中进行了声明,就有能力进行启动。其他的应用程序为了能够启动这个activity,需要在他们自己的manifest资源文件中的<uses-permission>元素中进行声明。</uses-permission></activity>

更多的权限和安全问题,可以参见Security Model 文档。

进程的生命周期

Android系统试图确保一个应用进程尽可能长久,但是在内存减少的时候最终要删除旧的进程。像Activity Lifecycle描述的一样,决定哪一个进程被删除是依据于和用户打交道的状态。一般来说,基于运行的activity的进程有四种状态,下面列出了重要的顺序,Android系统在杀掉重要进程之前先杀掉次要的进程。

前台的activity(activity在屏幕的最前面,正和用户进行交互)是最重要的,如果这个activity使用的内存超过了设备提供的内存,作为最后手段才杀掉这个activity的进程。通常在这一点上表明设备已经达到了memory paging state(?),因为需要确保用户界面的交互。

可见的activity(对用户可见,但不是在前台,如位于前台弹出对话框下面的界面)是很重要的,一般不会杀掉这个进程,除非为了确保前台activity的运行不得已而杀之。

后台的activity(对用户不可见,已经暂停)不再重要,系统可以安全杀掉这个进程,回收内存给其他前台或者可见的进程。当用户按下“返回”键浏览这个activity(使它重新在屏幕上可见),它的onCreate(Bundle)接口将被调用,在暂停的时候由于已经调用过onFreeze(Bundle)接口重置了状态,因此这个activity能够重新以相同的设置启动。

空进程是没有activity组件和其他应用程序组件(Service or IntentReceiver)的进程,在系统内存变低的时候很快就被删除了。出于这个原因,任何在activity之外的后台操作必须在IntentReceiver 或者Service的环境下执行,这样才能确保进程能够一直运行。

有时候activity希望能够执行一些长时间的操作,自立存在于activity的生命周期之外。例如:相机应用程序允许用户上传一幅图片到网站,上传将花费很长的时间,应用程序应该允许用户离开正在执行的程序。为了完成这些,activity应该启动一个Service来执行上传任务,在上传区间,系统能够给进程一个良好的优先级别(比那些不可见的进程更高的优先级别),而不用考虑源activity是否处于暂停,停止或者结束状态。

分享到:
评论

相关推荐

    e支付.apk 分析报告1

    《e支付.apk 分析报告解析》 e支付是一款被分析的应用程序,其APK文件名为"ezhifu.apk",文件大小为2.04MB,具有MD5值425ef3bfc70c546f1d2de8d91be9e37d,SHA1值759c53fb71f5b38c89ee8e53548e7a5b937d1c65,以及SHA...

    Ace Scanner.apk 分析报告1

    【Ace Scanner.apk 分析报告】 Ace Scanner 是一个名为 "Ace Scanner" 的应用程序,其最新版本为 2.13.0.APK。该应用的主要功能可能是文本扫描,由 ImpressMedium 开发。根据分析报告,该应用的包名为 `...

    拆豆豆.apk 分析报告1

    【拆豆豆.apk 分析报告1】 本分析报告针对名为“拆豆豆”的应用程序,其版本号为1.0.8.APK,由摸瓜APP分析平台(mogua.co)生成。该应用的包名为“chaiduoduo.top”,在分析过程中未发现任何域名、URL或邮箱线索。...

    GXB.apk 分析报告1

    【GXB.apk 分析报告1】 本报告主要分析了一个名为"GXB"的APK应用,版本号为2.0.28,包名为`m.ue5`。该应用由摸瓜APP分析平台(mogua.co)生成报告,其中包含了关于域名、URL和邮箱的线索。分析日期为2022年2月2日11...

    Vbitex.apk 分析报告1

    【Vbitex.apk 分析报告】 Vbitex是一款被分析的应用程序,其APK文件名为`Vbitex.apk`,文件大小为4.58MB,具有MD5值`69e1bfc296c132581890f1e962e5edf2`,SHA1值`0ebe90e25f4d6daafd1ee25f0ab5009f9c341abb`,以及...

    风喵加速器.apk 分析报告1

    【风喵加速器.apk 分析报告】 风喵加速器是一款Android应用,其APK文件名为1.2.0.7.APK,由摸瓜APP分析平台(mogua.co)进行分析。该应用的主要功能可能是提供网络加速服务,帮助用户优化网络连接,提升在线体验。其...

    有伴汇铺.apk 分析报告1

    【有伴汇铺.apk 分析报告】 这篇分析报告针对的是名为"有伴汇铺"的Android应用程序,其版本号为0.0.1。该APP的包名为`com.huipu.app`,由摸瓜APP分析平台(mogua.co)生成。分析日期为2022年2月3日,文件大小为6.06MB...

    Nova Launcher Prime 6.1.5.apk

    PRIME功能解锁| 分析已停用 说明: 1。卸载以前版本的Nova Launcher和Tesla Unread插件 2. 从我的软件包(而非Google Play)安装Nova Launcher和Tesla Unread插件。 3.享受! 这是补丁版,完全解锁的主要功能。不...

    mylauncher.apk

    通过对classes.dex的分析,我们可以了解应用的核心功能和逻辑。 3. **AndroidManifest.xml**:这是Android应用的配置文件,它定义了应用的基本元数据,如应用名称、所需权限、使用的Activity、Service、...

    Launcher依赖的jar包

    完成以上步骤后,`Launcher2`源码应该能够在Eclipse中成功编译并运行,允许开发者进行调试、分析和修改以满足特定需求或定制化功能。理解这些依赖和配置对于深入研究`Launcher`的工作原理和优化启动器性能至关重要。

    Apex_Launcher_Pro_v4.9.9.apk

    Analytics(分析)/ Crashlytics(崩溃)已禁用。 安装说明! 1.卸载先前版本的Apex Launcher和Apex Notifier插件 2.从我的程序包(而不是Google Play)中安装Apex Launcher和Apex Notifier插件! 3.享受!

    Nova_Launcher_Pro_v6.2.9.apk

    优化的图形和清理的资源&lt;改进的结果(5.73 MB apk大小); 语言:EN,RU; 删除了默认壁纸; 残疾人率和社交菜单; 禁用/删除不需要的权限+接收者和服务; Analytics(分析)/ Crashlytics(崩溃)已禁用。 ...

    Launcher3-android7.1.2

    使用Android Studio 2.3.1进行编译打包,意味着开发者可以利用该IDE提供的各种工具进行调试、性能分析和代码优化。此外,Android Studio还支持Gradle构建系统,使得依赖管理和版本控制更为简便。 总结起来,...

    android_APK文件对照

    #### 二、具体APK分析 1. **AccountAndAyncSettings.apk** - **功能描述**:用于管理账户同步设置,包括联系人同步、日历同步等。 - **可否删除**:通常建议保留,除非你确定不再需要使用任何与账户相关的同步服务...

    Android平台ROM的定制及精简教程

    - `Bugreport.apk`: Bug报告应用,用于收集设备信息和错误报告。 - `Calculator.apk`: 计算器应用。 - `Calendar.apk`: 日历应用。 - `CalendarProvider.apk`: 提供日历服务。 - `Camera.apk`: 摄像头应用。 -...

    Android操作系统详解[收集].pdf

    - **Launcher.apk**:启动器应用,负责桌面布局和应用图标显示。 - **Maps.apk**:谷歌地图应用程序,提供地图导航功能。 - **MediaProvider.apk**:多媒体播放服务提供者,支持音频和视频播放。 - **Mms.apk**:...

    史上最全datadalvik-cache 下可删除的文件对应列表

    - **launcher.apk**:这是一款默认的启动器应用,属于系统级应用。 综上所述,在`datadalvik-cache`目录下,我们可以看到各种类型的应用程序文件。其中,第三方应用相关的.dex文件及APK文件通常可以安全地删除,...

    Smart_Launcher_Pro_v5.4_b012.apk

    真正的智能 发射器 简单,轻便,快速是Smart Launcher的口号,它是创新的自定义启动器,在2016年1月被Google选为Play商店中最好的应用程序之一。 最多可放置9个屏幕 ...禁用分析; 广告已删除。

    Launcher测试报告.doc

    此测试报告针对ScreenLock4.0_V0702_3.apk和TaxLauncher_V0702.apk两个验收版本进行了详尽的测试,以确保其满足功能性和用户体验的要求。 测试环境包括特定的客户端型号Polo,搭载Android 4.0.3系统,内核版本3.0.8...

Global site tag (gtag.js) - Google Analytics