ide configurationnchanged

QNetworkConfigurationManager Class | Qt 4.8
QNetworkConfigurationManager
QNetworkConfigurationManager Class
class manages the network configurations provided by the system.
Header: #include &QNetworkConfigurationManager&
Qt 4.7 Inherits:
Public Types
{ CanStartAndStopInterfaces, DirectConnectionRouting, SystemSessionSupport, ApplicationLevelRoaming, ..., NetworkSessionRequired }
Public Functions
(QObject * parent = 0)
virtual ()
QList&QNetworkConfiguration& (QNetworkConfiguration::StateFlags filter = 0) const
QNetworkConfigurationManager::Capabilities () const
QNetworkConfiguration (const QString & identifier) const
QNetworkConfiguration () const
bool () const
29 public functions inherited from
Public Slots
1 public slot inherited from
void (const QNetworkConfiguration & config)
void (const QNetworkConfiguration & config)
void (const QNetworkConfiguration & config)
void (bool isOnline)
1 signal inherited from
Additional Inherited Members
1 property inherited from
7 static public members inherited from
8 protected functions inherited from
Detailed Description
class manages the network configurations provided by the system.
provides access to the network configurations known to the system and enables applications to detect the system capabilities (with regards to network sessions) at runtime.
abstracts a set of configuration options describing how a network interface has to be configured to connect to a particular target network.
maintains and updates the global list of QNetworkConfigurations. Applications can access and filter this list via (). If a new configuration is added or an existing one is removed or changed the (), () and () signals are emitted respectively.
The () can be used when intending to immediately create a new network session without caring about the particular configuration. It returns a
configuration. If there are not any discovered ones an invalid configuration is returned.
Some configuration updates may require some time to perform updates. A WLAN scan is such an example. Unless the platform performs internal updates it may be required to manually trigger configuration updates via (). The completion of the update process is indicated by emitting the () signal. The update process ensures that every existing
instance is updated. There is no need to ask for a renewed configuration list via ().
See also .
Member Type Documentation
enum QNetworkConfigurationManager::Capabilityflags QNetworkConfigurationManager::Capabilities
Specifies the system capabilities of the bearer API. The possible values are:
ConstantValueDescription
QNetworkConfigurationManager::CanStartAndStopInterfaces0xNetwork sessions and their underlying access points can be started and stopped. If this flag is not set
can only monitor but not influence the state of access points. On some platforms this feature may require elevated user permissions. This option is platform specific and may not always be available.
QNetworkConfigurationManager::DirectConnectionRouting0xNetwork sessions and their sockets can be bound to a particular network interface. Any packet that passes through the socket goes to the specified network interface and thus disregards standard routing table entries. This may be useful when two interfaces can reach overlapping IP ranges or an application has specific needs in regards to target networks. This option is platform specific and may not always be available.
QNetworkConfigurationManager::SystemSessionSupport0xIf this flag is set the underlying platform ensures that a network interface is not shut down until the last network session has been . This works across multiple processes. If the platform session support is missing this API can only ensure the above behavior for network sessions within the same process. In general mobile platforms (such as Symbian/S60) have such support whereas most desktop platform lack this capability.
QNetworkConfigurationManager::ApplicationLevelRoaming0xThe system gives applications control over the systems roaming behavior. Applications can initiate roaming (in case the current link is not suitable) and are consulted if the system has identified a more suitable access point.
QNetworkConfigurationManager::ForcedRoaming0xThe system disconnects an existing access point and reconnects via a more suitable one. The application does not have any control over this process and has to reconnect its active sockets.
QNetworkConfigurationManager::DataStatistics0xIf this flag is set
can provide statistics about transmitted and received data.
QNetworkConfigurationManager::NetworkSessionRequired0xIf this flag is set the platform requires that a network session is created before network operations can be performed.
The Capabilities type is a typedef for &Capability&. It stores an OR combination of Capability values.
Member Function Documentation
QNetworkConfigurationManager::QNetworkConfigurationManager( * parent = 0)
Constructs a
with the given parent.
Note that to ensure a valid list of current configurations immediately available, updating is done during construction which causes some delay.
[virtual] QNetworkConfigurationManager::~QNetworkConfigurationManager()
Frees the resources associated with the
&& QNetworkConfigurationManager::allConfigurations( filter = 0) const
Returns the list of configurations which comply with the given filter.
By default this function returns all (defined and undefined) configurations.
A wireless network with a particular SSID may only be accessible in a certain area despite the fact that the system has a valid configuration for it. Therefore the filter flag may be used to limit the list to discovered and possibly connected configurations only.
If filter is set to zero this function returns all possible configurations.
Note that this function returns the states for all configurations as they are known at the time of this function call. If for instance a configuration of type WLAN is defined the system may have to perform a WLAN scan in order to determine whether it is actually available. To obtain the most accurate state () should be used to update each configuration's state. Note that such an update may require some time. It's completion is signalled by (). In the absence of a configuration update this function returns the best estimate at the time of the call. Therefore, if WLAN configurations are of interest, it is recommended that () is called once after
instantiation (WLAN scans are too time consuming to perform in constructor). After this the data is kept automatically up-to-date as the system reports any changes.
QNetworkConfigurationManager::capabilities() const
Returns the capabilities supported by the current platform.
[signal] void QNetworkConfigurationManager::configurationAdded(const
This signal is emitted whenever a new network configuration is added to the system. The new configuration is specified by config.
[signal] void QNetworkConfigurationManager::configurationChanged(const
This signal is emitted when the
of config changes.
QNetworkConfigurationManager::configurationFromIdentifier(const
& identifier) const
Returns the
for identifier; otherwise returns an invalid .
See also ().
[signal] void QNetworkConfigurationManager::configurationRemoved(const
This signal is emitted when a configuration is about to be removed from the system. The removed configuration, specified by config, is invalid but retains name and identifier.
This function was introduced in
QNetworkConfigurationManager::defaultConfiguration() const
Returns the default configuration to be used. This function always returns a disc otherwise an invalid configuration.
In some cases it may be required to call () and wait for the () signal before calling this function.
See also ().
bool QNetworkConfigurationManager::isOnline() const
Returns true if the system is considered to be connected to another device via an acti otherwise returns false.
This is equivalent to the following code snippet:
&& activeConfigs = mgr.(::Active)
if (activeConfigs.count() & 0)
(mgr.isOnline())
(!mgr.isOnline())
See also ().
[signal] void QNetworkConfigurationManager::onlineStateChanged(bool isOnline)
This signal is emitted when the device changes from online to offline mode or vice versa. isOnline represents the new state of the device.
The state is considered to be online for as long as () returns a list with at least one entry.
This signal is emitted when the configuration update has been completed. Such an update can be initiated via ().
Initiates an update of all configurations. This may be used to initiate WLAN scans or other time consuming updates which may be required to obtain the correct state for configurations.
This call is asynchronous. On completion of this update the () signal is emitted. If new configurations are discovered or old ones were removed or changed the update process may trigger the emission of one or multiple (), () and () signals.
If a configuration state changes as a result of this update all existing
instances are updated automatically.
See also ().
& 2015 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.
The documentation provided herein is licensed under the terms of the
as published by the Free Software Foundation.
Qt and respective logos are trademarks of The Qt Company Ltd.
in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners.android4.0 字体和各个组件相应configration变化 - j2eedengzhangtao - ITeye技术网站
博客分类:
/system/fonts/下:
&&& DroidSans.ttf(英文字体)
&&& DroidSans-Bold.ttf (粗体)
&&& DroidSansFallback.ttf (中文字体)
&&& Roboto-Regular.ttf (系统英文数字文件常规体)
实现思路:
&&& 下载好(一般就需要下面两个字体文件,如果不需要切换字母数字,只需要
DroidSansFallback.ttf)
&&& Roboto-Regular.ttf
&&& DroidSansFallback.ttf,覆盖在/system/fonts/下
重启。
&&&
问题: 在源码环境,实现不重启和不要root的切换字体。
想要不重启可以切换字体,就要像字体大小和语言切换那样,改动Configration后,
让各个组件刷新从新加载资源。
所以查看源码,
android语言切换是在packages/apps/Settings/com/android/settings/LocalePicker.java的updateLocale()函数中调用.
**
&&&& * Requests the system to update the system locale. Note that the system looks halted
&&&& * for a while during the Locale migration, so the caller need to take care of it.
&&& public static void updateLocale(Locale locale) {&
&&&&&&& try {&
&&&&&&&&&&& IActivityManager am = ActivityManagerNative.getDefault();&
&&&&&&&&&&& Configuration config = am.getConfiguration();&
&&&&&&&&&&& config.locale =&
&&&&&&&&&&& // indicate this isn't some passing default - the user wants this remembered&
&&&&&&&&&&& config.userSetLocale =&
&&&&&&&&&&& am.updateConfiguration(config);&
&&&&&&&&&&& // Trigger the dirty bit for the Settings Provider.&
&&&&&&&&&&& BackupManager.dataChanged("com.android.providers.settings");&
&&&&&&& } catch (RemoteException e) {&
&&&&&&&&&&& // Intentionally left blank&
&&&&&&& }&
从注释可以看出, 只要本地local改变就会调用该函数. 查看ActivityManagerNative的getDefault()可以看到, 该函数返回的是远程服务对象ActivityManagerServices.java在本地的一个代理.& 最终调用的是ActivityManagerService.java中的updateConfiguration()函数.
[java] view plaincopy
public void updateConfiguration(Configuration values) {&
&&&&&&& enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,&
&&&&&&&&&&&&&&& "updateConfiguration()");&
&&&&&&& synchronized(this) {&
&&&&&&&&&&& if (values == null && mWindowManager != null) {&
&&&&&&&&&&&&&&& // sentinel: fetch the current configuration from the window manager&
&&&&&&&&&&&&&&& values = puteNewConfiguration();&
&&&&&&&&&&& }&
&&&&&&&&&&& if (mWindowManager != null) {&
&&&&&&&&&&&&&&& mProcessList.applyDisplaySize(mWindowManager);&
&&&&&&&&&&& }&
&&&&&&&&&&& final long origId = Binder.clearCallingIdentity();&
&&&&&&&&&&& if (values != null) {&
&&&&&&&&&&&&&&& Settings.System.clearConfiguration(values);&
&&&&&&&&&&& }&
&&&&&&&&&&& updateConfigurationLocked(values, null, false, false);&
&&&&&&&&&&& Binder.restoreCallingIdentity(origId);&
&&&&&&& }&
该函数, 首先进行的是权限的校验. 然后调用updateConfigurationLocked()函数.
[java] view plaincopy
/**
&&&& * Do either or both things: (1) change the current configuration, and (2)
&&&& * make sure the given activity is running with the (now) current
&&&& * configuration.& Returns true if the activity has been left running, or
&&&& * false if &var&starting&/var& is being destroyed to match the new
&&&& * configuration.
&&&& * @param persistent TODO
&&& public boolean updateConfigurationLocked(Configuration values,&
&&&&&&&&&&& ActivityRecord starting, boolean persistent, boolean initLocale) {&
&&&&&&& int changes = 0;&
&&&&&&& boolean kept =&
&&&&&&& if (values != null) {&
&&&&&&&&&&& Configuration newConfig = new Configuration(mConfiguration);&
&&&&&&&&&&& changes = newConfig.updateFrom(values);&
&&&&&&&&&&& if (changes != 0) {&
&&&&&&&&&&&&&&& if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {&
&&&&&&&&&&&&&&&&&&& Slog.i(TAG, "Updating configuration to: " + values);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);&
&&&&&&&&&&&&&&& if (values.locale != null && !initLocale) {&
&&&&&&&&&&&&&&&&&&& saveLocaleLocked(values.locale,&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& !values.locale.equals(mConfiguration.locale),&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& values.userSetLocale, values.simSetLocale);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& mConfigurationSeq++;&
&&&&&&&&&&&&&&& if (mConfigurationSeq &= 0) {&
&&&&&&&&&&&&&&&&&&& mConfigurationSeq = 1;&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& newConfig.seq = mConfigurationS&
&&&&&&&&&&&&&&& mConfiguration = newC&
&&&&&&&&&&&&&&& Slog.i(TAG, "Config changed: " + newConfig);&
&&&&&&&&&&&&&&& final Configuration configCopy = new Configuration(mConfiguration);&
&&&&&&&&&&&&&&& AttributeCache ac = AttributeCache.instance();&
&&&&&&&&&&&&&&& if (ac != null) {&
&&&&&&&&&&&&&&&&&&& ac.updateConfiguration(configCopy);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& // Make sure all resources in our process are updated&
&&&&&&&&&&&&&&& // right now, so that anyone who is going to retrieve&
&&&&&&&&&&&&&&& // resource values after we return will be sure to get&
&&&&&&&&&&&&&&& // the new ones.& This is especially important during&
&&&&&&&&&&&&&&& // boot, where the first config change needs to guarantee&
&&&&&&&&&&&&&&& // all resources have that config before following boot&
&&&&&&&&&&&&&&& // code is executed.&
&&&&&&&&&&&&&&& mSystemThread.applyConfigurationToResources(configCopy);&
&&&&&&&&&&&&&&& if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {&
&&&&&&&&&&&&&&&&&&& Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);&
&&&&&&&&&&&&&&&&&&& msg.obj = new Configuration(configCopy);&
&&&&&&&&&&&&&&&&&&& mHandler.sendMessage(msg);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& for (int i=mLruProcesses.size()-1; i&=0; i--) {&
&&&&&&&&&&&&&&&&&&& ProcessRecord app = mLruProcesses.get(i);&
&&&&&&&&&&&&&&&&&&& try {&
&&&&&&&&&&&&&&&&&&&&&&& if (app.thread != null) {&
&&&&&&&&&&&&&&&&&&&&&&&&&&& if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + app.processName + " new config " + mConfiguration);&
&&&&&&&&&&&&&&&&&&&&&&&&&&& app.thread.scheduleConfigurationChanged(configCopy);&
&&&&&&&&&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&&&&&& } catch (Exception e) {&
&&&&&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);&
&&&&&&&&&&&&&&& intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY&
&&&&&&&&&&&&&&&&&&&&&&& | Intent.FLAG_RECEIVER_REPLACE_PENDING);&
&&&&&&&&&&&&&&& broadcastIntentLocked(null, null, intent, null, null, 0, null, null,&
&&&&&&&&&&&&&&&&&&&&&&& null, false, false, MY_PID, Process.SYSTEM_UID);&
&&&&&&&&&&&&&&& if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {&
&&&&&&&&&&&&&&&&&&& broadcastIntentLocked(null, null,&
&&&&&&&&&&&&&&&&&&&&&&&&&&& new Intent(Intent.ACTION_LOCALE_CHANGED),&
&&&&&&&&&&&&&&&&&&&&&&&&&&& null, null, 0, null, null,&
&&&&&&&&&&&&&&&&&&&&&&&&&&& null, false, false, MY_PID, Process.SYSTEM_UID);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&&&&
&&&&&&&&&&& }&
&&&&&&& }&
&&&&&&& if (changes != 0 && starting == null) {&
&&&&&&&&&&& // If the configuration changed, and the caller is not already&
&&&&&&&&&&& // in the process of starting an activity, then find the top&
&&&&&&&&&&& // activity to check if its configuration needs to change.&
&&&&&&&&&&& starting = mMainStack.topRunningActivityLocked(null);&
&&&&&&& }&
&&&&&&& if (starting != null) {&
&&&&&&&&&&& kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);&
&&&&&&&&&&& // And we need to make sure at this point that all other activities&
&&&&&&&&&&& // are made visible with the correct configuration.&
&&&&&&&&&&& mMainStack.ensureActivitiesVisibleLocked(starting, changes);&
&&&&&&& }&
&&&&&&& if (values != null && mWindowManager != null) {&
&&&&&&&&&&& mWindowManager.setNewConfiguration(mConfiguration);&
&&&&&&& }&
整个语言切换就在这个函数中完成. 咋一看似乎没感觉到该函数做了哪些事情. 我们首先来看注释: Do either or both things: (1) change the current configuration, and (2)
make sure the given activity is running with the (now) current. configuration大概意思是: 这个函数做了两件事情. (1). 改变当前的configuration. 意思就是让改变的configuration更新到当前configuration. (2) 确保所有正在运行的activity都能更新改变后的configuration.(这点是关键.) . 我们按照这个思路看看android是如何更新configuration. 查看代码 , 首先看到 这个函数首先判断values是否为空, 这里values肯定不为空的, 然后changes = newConfig.updateFrom(values); 我们看看updateFrom做了什么操作.
[java] view plaincopy
/**
&&&& * Copy the fields from delta into this Configuration object, keeping
&&&& * track of which ones have changed.& Any undefined fields in
&&&& * &var&delta&/var& are ignored and not copied in to the current
&&&& * Configuration.
&&&& * @return Returns a bit mask of the changed fields, as per
&&&& * {@link #diff}.
&&& public int updateFrom(Configuration delta) {&
&&&&&&& int changed = 0;&
&&&&&&& ...&
&&&&&&& if (delta.locale != null&
&&&&&&&&&&&&&&& && (locale == null || !locale.equals(delta.locale))) {&
&&&&&&&&&&& changed |= ActivityInfo.CONFIG_LOCALE;&
&&&&&&&&&&& locale = delta.locale != null&
&&&&&&&&&&&&&&&&&&& ? (Locale) delta.locale.clone() :&
&&&&&&&&&&& textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);&
&&&&&&& }&
&&&&&&& if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))&
&&&&&&& {&
&&&&&&&&&&& userSetLocale =&
&&&&&&&&&&& changed |= ActivityInfo.CONFIG_LOCALE;&
&&&&&&& }&
&&&&&&& ...&
因为语言改变了, 那么 (!locale.equals(delta.locale)) 是true. changed 大于0, 然后return changed. 回到ActivityManagerService.java的updateConfigurationLocked函数, 因为changed不为0 , 所以走if这个流程.& 继续看代码
[java] view plaincopy
for (int i=mLruProcesses.size()-1; i&=0; i--) {&
&&&&&&&&&&&&&&&&&&& ProcessRecord app = mLruProcesses.get(i);&
&&&&&&&&&&&&&&&&&&& try {&
&&&&&&&&&&&&&&&&&&&&&&& if (app.thread != null) {&
&&&&&&&&&&&&&&&&&&&&&&&&&&& if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + app.processName + " new config " + mConfiguration);&
&&&&&&&&&&&&&&&&&&&&&&&&&&& app.thread.scheduleConfigurationChanged(configCopy);&
&&&&&&&&&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&&&&&& } catch (Exception e) {&
&&&&&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& }&
首先看到的是mLurProcesses 是ArrayList&ProcessRecord&类型.& LRU : Least Recently Used保存所有运行过的进程.& ProcessRecord进程类, 一个apk文件运行时会对应一个进程. app.thread. 此处的thread代表的是ApplicationThreadNative.java类型.& 然后调用其scheduleConfigurationChanged();& 查看该函数
[java] view plaincopy
public final void scheduleConfigurationChanged(Configuration config)&
&&&&&&&&&&& throws RemoteException {&
&&&&&&& Parcel data = Parcel.obtain();&
&&&&&&& data.writeInterfaceToken(IApplicationThread.descriptor);&
&&&&&&& config.writeToParcel(data, 0);&
&&&&&&& mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,&
&&&&&&&&&&&&&&& IBinder.FLAG_ONEWAY);&
&&&&&&& data.recycle();&
又是通过binder调用, 所以 , binder在android中是一个很重要的概念. 此处远程调用的是ActivityThread.java中的私有内部内ApplicationThread
[java] view plaincopy
& private class ApplicationThread extends ApplicationThreadNative {&
&&&&&&& private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";&
&&&&&&& private static final String ONE_COUNT_COLUMN = "%21s %8d";&
&&&&&&& private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";&
&&&&&&& private static final String TWO_COUNT_COLUMNS_DB = "%21s %8d %21s %8d";&
&&&&&&& private static final String DB_INFO_FORMAT = "& %8s %8s %14s %14s& %s";&
&&&&&&& ...&
&&&&&&& public void scheduleConfigurationChanged(Configuration config) {&
&&&&&&&&&&& updatePendingConfiguration(config);&
&&&&&&&&&&& queueOrSendMessage(H.CONFIGURATION_CHANGED, config);&
&&&&&&& }&
&&&&&&& ...&
而ApplicationThread中的handler的CONFIGURATION_CHANGED是调用handleConfigurationChanged()
[java] view plaincopy
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {&
&&&&&& ArrayList&ComponentCallbacks2& callbacks =&
&&& ...&&&&&&&& ...&
&&&&&& applyConfigurationToResourcesLocked(config, compat);&
&&&&&& ...&
&&&&&& callbacks = collectComponentCallbacksLocked(false, config);&
&&&&&& ...&
&&&&&& if (callbacks != null) {&
&&&&&&&&&& final int N = callbacks.size();&
&&&&&&&&&& for (int i=0; i&N; i++) {&
&&&&&&&&&&&&&& performConfigurationChanged(callbacks.get(i), config);&
&&&&&&&&&& }&
这个函数首先是调用applyConfigurationToResourcesLocked(). 看函数名大概可以推测: 将configuration应用到resources.这里configuration改变的是local 本地语言. 那而resources资源包含不就包含了语言, 图片这些资源吗.
[java] view plaincopy
final boolean applyConfigurationToResourcesLocked(Configuration config,&
&&&&&&&&&&& CompatibilityInfo compat) {&
&&&&&&& int changes = mResConfiguration.updateFrom(config);&
&&&&&&& DisplayMetrics dm = getDisplayMetricsLocked(null, true);&
&&&&&&& if (compat != null && (mResCompatibilityInfo == null ||&
&&&&&&&&&&&&&&& !mResCompatibilityInfo.equals(compat))) {&
&&&&&&&&&&& mResCompatibilityInfo =&
&&&&&&&&&&& changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT&
&&&&&&&&&&&&&&&&&&& | ActivityInfo.CONFIG_SCREEN_SIZE&
&&&&&&&&&&&&&&&&&&& | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;&
&&&&&&& }&
&&&&&&& ...&
&&&&&&& Resources.updateSystemConfiguration(config, dm, compat);&
&&&&&&& ...&
&&&&&&& Iterator&WeakReference&Resources&& it =&
&&&&&&&&&&& mActiveResources.values().iterator();&
&&&&&&& while (it.hasNext()) {&
&&&&&&&&&&& WeakReference&Resources& v = it.next();&
&&&&&&&&&&& Resources r = v.get();&
&&&&&&&&&&& if (r != null) {&
&&&&&&&&&&&&&&& if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "&
&&&&&&&&&&&&&&&&&&&&&&& + r + " config to: " + config);&
&&&&&&&&&&&&&&& r.updateConfiguration(config, dm, compat);&
&&&&&&&&&&&&&&& //Slog.i(TAG, "Updated app resources " + v.getKey()&
&&&&&&&&&&&&&&& //&&&&&&& + " " + r + ": " + r.getConfiguration());&
&&&&&&&&&&& } else {&
&&&&&&&&&&&&&&& //Slog.i(TAG, "Removing old resources " + v.getKey());&
&&&&&&&&&&&&&&& it.remove();&
&&&&&&&&&&& }&
&&&&&&& }&
&&&&&&& return changes != 0;&
Resources.updateSystemConfiguration()清除一部分系统资源, 并且将config更新到Resources, 而Resources包含了一个AssetManager对象, 该对象的核心实现是在AssetManager.cpp中完成的. 然后循环清空mActivityResources资源. 再回到handleConfigurationChanged()函数, 执行完updateSystemConfiguration后, 会循环该进程的所有activity:
if (callbacks != null) {
&&&&&&&&&&& final int N = callbacks.size();
&&&&&&&&&&& for (int i=0; i&N; i++) {
&&&&&&&&&&&&&&& performConfigurationChanged(callbacks.get(i), config);
&&&&&&&&&&& }
&&&&&&& }
再来看performConfigurationChanged的实现:
[java] view plaincopy
private final void performConfigurationChanged(&
&&&&&&&&&&& ComponentCallbacks2 cb, Configuration config) {&
&&&&&&& // Only for Activity objects, check that they actually call up to their&
&&&&&&& // superclass implementation.& ComponentCallbacks2 is an interface, so&
&&&&&&& // we check the runtime type and act accordingly.&
&&&&&&& Activity activity = (cb instanceof Activity) ? (Activity) cb :&
&&&&&&& if (activity != null) {&
&&&&&&&&&&& activity.mCalled =&
&&&&&&& }&
&&&&&&& boolean shouldChangeConfig =&
&&&&&&& if ((activity == null) || (activity.mCurrentConfig == null)) {&
&&&&&&&&&&& shouldChangeConfig =&
&&&&&&& } else {&
&&&&&&&&&&& // If the new config is the same as the config this Activity&
&&&&&&&&&&& // is already running with then don't bother calling&
&&&&&&&&&&& // onConfigurationChanged&
&&&&&&&&&&& int diff = activity.mCurrentConfig.diff(config);&
&&&&&&&&&&& if (diff != 0) {&
&&&&&&&&&&&&&&& // If this activity doesn't handle any of the config changes&
&&&&&&&&&&&&&&& // then don't bother calling onConfigurationChanged as we're&
&&&&&&&&&&&&&&& // going to destroy it.&
&&&&&&&&&&&&&&& if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {&
&&&&&&&&&&&&&&&&&&& shouldChangeConfig =&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&& }&
&&&&&&& }&
&&&&&&& if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb&
&&&&&&&&&&&&&&& + ": shouldChangeConfig=" + shouldChangeConfig);&
&&&&&&& if (shouldChangeConfig) {&
&&&&&&&&&&& cb.onConfigurationChanged(config);&
&&&&&&&&&&& if (activity != null) {&
&&&&&&&&&&&&&&& if (!activity.mCalled) {&
&&&&&&&&&&&&&&&&&&& throw new SuperNotCalledException(&
&&&&&&&&&&&&&&&&&&&&&&&&&&& "Activity " + activity.getLocalClassName() +&
&&&&&&&&&&&&&&&&&&&&&&& " did not call through to super.onConfigurationChanged()");&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& activity.mConfigChangeFlags = 0;&
&&&&&&&&&&&&&&& activity.mCurrentConfig = new Configuration(config);&
&&&&&&&&&&& }&
&&&&&&& }&
该函数判断configuration是否改变, 如果改变那么shouldChangeConfig为true. 然后调用activity的onConfigurationChange(config);
[java] view plaincopy
/**
&&& * Called by the system when the device configuration changes while your
&&& * activity is running.& Note that this will &em&only&/em& be called if
&&& * you have selected configurations you would like to handle with the
&&& * {@link android.R.attr#configChanges} attribute in your manifest.& If
&&& * any configuration change occurs that is not selected to be reported
&&& * by that attribute, then instead of reporting it the system will stop
&&& * and restart the activity (to have it launched with the new
&&& * configuration).
&&& * &p&At the time that this function has been called, your Resources
&&& * object will have been updated to return resource values matching the
&&& * new configuration.
&&& * @param newConfig The new device configuration.
&& public void onConfigurationChanged(Configuration newConfig) {&
&&&&&& mCalled =&
&&&&&& mFragments.dispatchConfigurationChanged(newConfig);&
&&&&&& if (mWindow != null) {&
&&&&&&&&&& // Pass the configuration changed event to the window&
&&&&&&&&&& mWindow.onConfigurationChanged(newConfig);&
&&&&&& if (mActionBar != null) {&
&&&&&&&&&& // D the action bar will need to access&
&&&&&&&&&& // view changes from above.&
&&&&&&&&&& mActionBar.onConfigurationChanged(newConfig);&
查看注释, 大概意思是:& 如果你的activity运行 , 设备信息有改变(即configuration改变)时由系统调用. 如果你在manifest.xml中配置了configChnages属性则表示有你自己来处理configuration change. 否则就重启当前这个activity.& 而重启之前, 旧的resources已经被清空, 那么就会装载新的资源, 整个过程就完成了语言切换后 , 能够让所有app使用新的语言. 语言切换流程大概分为三步:
第一步:& 判断configuration的local是否已经改变, 如果改变则将local更新到当前的configuration
第二步: 清空旧的资源.
第三步: 重启所有所有进程并加装新资源.
能让activity响应的关键是接口ComponentCallbacks
dengzhangtao
浏览: 273026 次
来自: 上海
楼主,我这里有个问题!我这里有个自己制作的font.ttf,这 ...
既然springMVC比struts好那么多的话那struts ...
楼上的很给力啊。。3Q
目前收集了160多个不错的Android开源项目汇总到 htt ...}

我要回帖

更多关于 system configuration 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信