Android opensource: Settings study _ How the android component responds to language changes

Source: Internet
Author: User
Tags constant definition

The android components mentioned here mainly refer to Activity, Service, ContentProvider and BroadcastReceiver in android.

In the process of developing the android source code, we all get the same android source code, but the hardware platform is quite different, so it will lead to various problems. Thus, android development becomes more and more exciting!

This blog is inspired by the source code of Settings. I will share my experience with you!

After setting the language, I found that the language remains unchanged in some places. At this time, I think of the onConfigurationChanged method. Let's take a look at this method.

Public interface ComponentCallbacks

This interface includes two methods, one of which is the onConfigurationChanged method.
Activity, Service, and ContentProvider all implement this interface. Therefore, we can rewrite this method in the Code to facilitate callback processing. So when will this method be called back?

Abstract voidonConfigurationChanged (Configuration newConfig)
Called by the system when the device configuration changes while your component is running.

When the device configuration changes, callback is triggered. You may be wondering, what are the device configurations?
Android: configChanges = ["mcc", "mnc", "locale ",
"Touchscreen", "keyboard", "keyboardHidden ",
"Navigation", "screenLayout", "fontScale", "uiMode ",
"Orientation", "screenSize", "smallestScreenSize"]
Note that if Activity is used in combination with the onConfigurationChanged method, you must add the following in its menifest. xml:
Android: configChanges attributes.

Therefore, if necessary, you can rewrite this method in the above three components for your own logic processing!

If you change the language in Settings, you can register a broadcast in our other apps to receive the change!
Yes, of course!

Register a broadcast:
[Java]
<Span style = "font-size: 18px;"> <span style = "font-family: 'comic Sans MS ';"> IntentFilter filter = new IntentFilter ();
Filter. addAction (Intent. ACTION_CONFIGURATION_CHANGED );
RegisterReceiver (receiver, filter); </span>

Receive broadcast:
[Java]
<Span style = "font-size: 18px;"> <span style = "font-family: 'comic Sans MS ';"> private BroadcastReceiver receiver ER = new BroadcastReceiver (){

@ Override
Public void onReceive (Context context, Intent intent ){
String action = intent. getAction ();
If ("android. intent. action. CONFIGURATION_CHANGED". equals (action )){
// To do
}
}
};</Span> </span>

Do not forget to cancel registration at the appropriate location:
UnregisterReceiver (receiver );

In this way, it is more flexible than directly rewriting the onConfigurationChanged method, because some android components that do not implement this interface are still relatively easy to receive broadcasts! In my blog later, I will share with you how custom views receive broadcasts!

For more information about Intent. ACTION_CONFIGURATION_CHANGED, see the sdk documentation.

Some people say that I only care about the action that changes the language of the device? Yes!

Intent. ACTION_LOCALE_CHANGED

If you are interested, refer to/frameworks/base/services/java/com/android/server/am/ActivityManagerService. java. The key code is as follows:
[Java]
<Span style = "font-size: 18px;"> <span style = "font-family: 'comic Sans Ms';"> /**
* 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.
*/
Public boolean updateConfigurationLocked (Configuration values,
ActivityRecord starting ){
Int changes = 0;

Boolean kept = true;

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 ){
SaveLocaleLocked (values. locale,
! Values. locale. equals (mConfiguration. locale ),
Values. userSetLocale );
}
 
MConfigurationSeq ++;
If (mConfigurationSeq <= 0 ){
MConfigurationSeq = 1;
}
NewConfig. seq = mConfigurationSeq;
MConfiguration = newConfig;
Slog. I (TAG, "Config changed:" + newConfig );

AttributeCache ac = AttributeCache. instance ();
If (ac! = Null ){
Ac. updateConfiguration (mConfiguration );
}
 
If (Settings. System. hasInterestingConfigurationChanges (changes )){
Message msg = mHandler. obtainMessage (UPDATE_CONFIGURATION_MSG );
Msg. obj = new Configuration (mConfiguration );
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 (mConfiguration );
}
} 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 );
If (kept ){
// If this didn't result in the starting activity being
// Destroyed, then we need to make sure at this point that all
// Other activities are made visible.
If (DEBUG_SWITCH) Slog. I (TAG, "Config didn't destroy" + starting
+ ", Ensuring others are correct .");
MMainStack. ensureActivitiesVisibleLocked (starting, changes );
}
}

If (values! = Null & mWindowManager! = Null ){
MWindowManager. setNewConfiguration (mConfiguration );
}

Return kept;
} </Span>

The Code contains the two Intent actions mentioned above.

In addition, save the source code for setting locale information:
[Java]
<Span style = "font-size: 18px;"> <span style = "font-family: 'comic Sans Ms';"> /**
* Save the locale. You must be inside a synchronized (this) block.
*/
Private void saveLocaleLocked (Locale l, boolean isDiff, boolean isPersist ){
If (isDiff ){
SystemProperties. set ("user. language", l. getLanguage ());
SystemProperties. set ("user. region", l. getCountry ());
}
 
If (isPersist ){
SystemProperties. set ("persist. sys. language", l. getLanguage ());
SystemProperties. set ("persist. sys. country", l. getCountry ());
SystemProperties. set ("persist. sys. localevar", l. getVariant ());
}
} </Span>


The android system sends a lot of broadcasts, but how do you remember so many actions? You don't need to remember. Let's take a good look at the constant definition of the Intent class. It's very clear. If you're diligent and researching enough, it's not a problem!

From mark in working

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.