LauncherApplication 作为Launcher唯一的应用程序实例,一般会用来保存一些全局的数据,做一些全局的初始化工作。

1. 加入节点:


<application
android:name="com.android.launcher2.LauncherApplication"
android:label="@string/application_name"
android:icon="@mipmap/ic_launcher_home"
android:hardwareAccelerated="true"
android:largeHeap="@bool/config_largeHeap"
android:supportsRtl="true">


android:hardwareAccelerated="true"  整个程序使用硬件加速,3.0才有。

android:largeHeap                   是否使用大内存。可以通过ActivityManager.getMemoryClass() 

android:supportsRtl="true"     是否支持从右到左的布局,支持的话,Activity中使用:layoutDirection="rtl"


2.主要工作:

<1.创建全局数据并初始化:

public LauncherModel mModel;
public IconCache mIconCache;

其中 

mModel 是一个 BroadcastReceiver。

mIconCache 是图片的缓存。mModel 持有对图标缓存的引用。


mModel关心的广播Activon有:

(1)ACTION_PACKAGE_REMOVED  ACTION_PACKAGE_CHANGED 应用程序包卸载及包信息改变的广播。

(2)ACTION_EXTERNAL_APPLICATIONS_AVAILABLE SD卡上程序可用。 ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE SD卡上程序不可用,         ACTION_LOCALE_CHANGED 语言环境改变时的广播。ACTION_CONFIGURATION_CHANGED 也是语言改变时会发出?
(3)INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED 通知全局搜索提高者已经改变了。

<2.设置一个监听器,来监听数据库中 favorites表的改变。  注册一个ContentResolver,用来响应 favorite 表的改变。这个表在 launcher.db数据库中。workspace 正是根据里面的数据来加载的。



注:
与包相关的Broadcast Action还有:


ACTION_PACKAGE_ADDED 一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
ACTION_PACKAGE_REPLACED 一个新版本的应用安装到设备,替换之前已经存在的版本
ACTION_PACKAGE_CHANGED 一个已存在的应用程序包已经改变,包括包名
ACTION_PACKAGE_REMOVED 一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
ACTION_PACKAGE_RESTARTED 用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)
ACTION_PACKAGE_DATA_CLEARED 用户已经清楚一个包的数据,包括包名(清除包程序不能接收到这个广播)


需要注意对一个 Receiver注册多个 IntentFilter的方法。



源码:


/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.android.launcher2;

import android.app.Application;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Handler;

import com.android.launcher.R;

import java.lang.ref.WeakReference;

public class LauncherApplication extends Application {
public LauncherModel mModel;
public IconCache mIconCache;
private static boolean sIsScreenLarge;
private static float sScreenDensity;
private static int sLongPressTimeout = 300;
private static final String sSharedPreferencesKey = "com.android.launcher2.prefs";
WeakReference<LauncherProvider> mLauncherProvider;

@Override
public void onCreate() {
super.onCreate();

// set sIsScreenXLarge and sScreenDensity *before* creating icon cache
sIsScreenLarge = getResources().getBoolean(R.bool.is_large_screen);
sScreenDensity = getResources().getDisplayMetrics().density;

mIconCache = new IconCache(this);
mModel = new LauncherModel(this, mIconCache);

// Register intent receivers
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
registerReceiver(mModel, filter);
filter = new IntentFilter();
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 = new IntentFilter();
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
registerReceiver(mModel, filter);
filter = new IntentFilter();
filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
registerReceiver(mModel, filter);

// Register for changes to the favorites
ContentResolver resolver = getContentResolver();
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true,
mFavoritesObserver);
}

/**
* There's no guarantee that this function is ever called.
*/
@Override
public void onTerminate() {
super.onTerminate();

unregisterReceiver(mModel);

ContentResolver resolver = getContentResolver();
resolver.unregisterContentObserver(mFavoritesObserver);
}

/**
* Receives notifications whenever the user favorites have changed.
*/
private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
// If the database has ever changed, then we really need to force a reload of the
// workspace on the next load
mModel.resetLoadedState(false, true);
mModel.startLoaderFromBackground();
}
};

LauncherModel setLauncher(Launcher launcher) {
mModel.initialize(launcher);
return mModel;
}

IconCache getIconCache() {
return mIconCache;
}

LauncherModel getModel() {
return mModel;
}

void setLauncherProvider(LauncherProvider provider) {
mLauncherProvider = new WeakReference<LauncherProvider>(provider);
}

LauncherProvider getLauncherProvider() {
return mLauncherProvider.get();
}

public static String getSharedPreferencesKey() {
return sSharedPreferencesKey;
}

public static boolean isScreenLarge() {
return sIsScreenLarge;
}

public static boolean isScreenLandscape(Context context) {
return context.getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE;
}

public static float getScreenDensity() {
return sScreenDensity;
}

public static int getLongPressTimeout() {
return sLongPressTimeout;
}
}