Android通过代码实现多语言切换createConfigurationContextattachBaseContextgetResourcesupdateConfiguration

Posted Mars-xq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android通过代码实现多语言切换createConfigurationContextattachBaseContextgetResourcesupdateConfiguration相关的知识,希望对你有一定的参考价值。

updateConfiguration 过时兼容处理

@Override
public Resources getResources() //此方法会 多次 调用
    Configuration configuration = new Configuration();
    configuration.smallestScreenWidthDp = 900;
    //updateConfiguration 过时兼容处理
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) 
        return createConfigurationContext(configuration).getResources();
     else 
        Resources resources = super.getResources();
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        return resources;
    

自定义view时获取指定带configuration的context

private Context getSplitScreenContext() 
    Configuration newConfig = new Configuration();
    newConfig.setToDefaults();
    newConfig.smallestScreenWidthDp = MyApplication.mSmallestScreenWidthDp;
    Context context = mContext.createConfigurationContext(newConfig);
    return new ContextWrapper(context);


//
LayoutInflater.from(getSplitScreenContext())

参考

Android通过代码实现多语言切换

Android动态设置APP语言

测试demo 1: 重写 attachBaseContext

public class MyApplication extends Application 

    private static final String TAG = MyApplication.class.getSimpleName();

    @Override
    public void onCreate() 
        super.onCreate();
        int smallestScreenWidthDp1 = getApplicationContext().getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application onCreate: 1=========" + smallestScreenWidthDp1);//600
        int smallestScreenWidthDp2 = getBaseContext().getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application onCreate: 2=========" + smallestScreenWidthDp2);//600
    

    @Override
    protected void attachBaseContext(Context newBase) 
        int smallestScreenWidthDp = newBase.getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application attachBaseContext: 1=========" + smallestScreenWidthDp);//720
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 600;
        super.attachBaseContext(newBase.createConfigurationContext(configuration));
        Log.e(TAG, "Application attachBaseContext: 2=========" + smallestScreenWidthDp);//720
    

public class MainActivity8 extends AppCompatActivity 
    private static final String TAG = MainActivity8.class.getSimpleName();
  
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main8);

        Context baseContext = getBaseContext();
        Context applicationContext = getApplicationContext();
        
            Log.e(TAG, "this: ========" + this);//【803afaa】
            Log.e(TAG, "getBaseContext(): ========" + baseContext);//【93c79b】
            //getApplication 和 getApplicationContext 一样地址
            Log.e(TAG, "getApplication(): ========" + getApplication()); //【@29f6738】
            Log.e(TAG, "getApplicationContext(): ========" + applicationContext);//【29f6738】
        

        
            // getResources() 和 getBaseContext().getResources() 在 activity 中同一个对象【ca23311】
            // getApplicationContext().getResources() 为另一个对象 【cc51c76】
            Log.e(TAG, "getResources(): 1=======" + getResources());//【ca23311】
            Log.e(TAG, "getResources(): 2========" + baseContext.getResources());//【ca23311】
            Log.e(TAG, "getResources(): 3========" + applicationContext.getResources());//【cc51c76】

            //activity 中 attachBaseContext 仅仅会影响以下2个:
            int smallestScreenWidthDp1 = getResources().getConfiguration().smallestScreenWidthDp;
            Log.e(TAG, "smallestScreenWidthDp: 1========" + smallestScreenWidthDp1);//900
            int smallestScreenWidthDp2 = baseContext.getResources().getConfiguration().smallestScreenWidthDp;
            Log.e(TAG, "smallestScreenWidthDp: 2========" + smallestScreenWidthDp2);//900

            //application 中 attachBaseContext 仅仅会影响以下:
            int smallestScreenWidthDp3 = applicationContext.getResources().getConfiguration().smallestScreenWidthDp;
            Log.e(TAG, "smallestScreenWidthDp: 3========" + smallestScreenWidthDp3);//600
        
    

    @Override
    protected void attachBaseContext(Context newBase) 
        int smallestScreenWidthDp = newBase.getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "activity attachBaseContext: 1=========" + smallestScreenWidthDp);//720
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 900;
        super.attachBaseContext(newBase.createConfigurationContext(configuration));
        Log.e(TAG, "activity attachBaseContext: 2=========" + smallestScreenWidthDp);//720
    

日志打印:

MyApplication: Application attachBaseContext: 1=========720
MyApplication: Application attachBaseContext: 2=========720
MyApplication: Application onCreate: 1=========600
MyApplication: Application onCreate: 2=========600

MainActivity8: activity attachBaseContext: 1=========720
MainActivity8: activity attachBaseContext: 2=========720
MainActivity8: this: ========com.xq.myapplication.MainActivity8@6070295
MainActivity8: getBaseContext(): ========androidx.appcompat.view.ContextThemeWrapper@22f444e
MainActivity8: getApplication(): ========com.xq.myapplication.MyApplication@744096f
MainActivity8: getApplicationContext(): ========com.xq.myapplication.MyApplication@744096f
MainActivity8: getResources(): 1=======android.content.res.Resources@db2067c
MainActivity8: getResources(): 2========android.content.res.Resources@db2067c
MainActivity8: getResources(): 3========android.content.res.Resources@2aebb05
MainActivity8: smallestScreenWidthDp: 1========900
MainActivity8: smallestScreenWidthDp: 2========900
MainActivity8: smallestScreenWidthDp: 3========600

测试demo 2: 重写 attachBaseContext 和 getResources

  • 重写 attachBaseContext 和 重写 getResources 都可以改变 configuration
  • 生命周期 attachBaseContext -> getResources -> onCreate : 所以getResources会覆盖attachBaseContext
public class MyApplication extends Application 

    private static final String TAG = MyApplication.class.getSimpleName();

    @Override
    public void onCreate() 
        super.onCreate();
        int smallestScreenWidthDp1 = getApplicationContext().getResources().getConfiguration().smallestScreenWidthDp;
        //getResources()会覆盖attachBaseContext()
        Log.e(TAG, "Application onCreate: 1=========" + smallestScreenWidthDp1);//300
        int smallestScreenWidthDp2 = getBaseContext().getResources().getConfiguration().smallestScreenWidthDp;
        //getResources()会覆盖attachBaseContext()
        Log.e(TAG, "Application onCreate: 2=========" + smallestScreenWidthDp2);//300
    

    @Override
    protected void attachBaseContext(Context newBase) //此方法会 1 次调用
        int smallestScreenWidthDp = newBase.getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application attachBaseContext: 1=========" + smallestScreenWidthDp);//720不会变
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 600;
        super.attachBaseContext(newBase.createConfigurationContext(configuration));
        Log.e(TAG, "Application attachBaseContext: 2=========" + smallestScreenWidthDp);//720不会变
    

    @Override
    public Resources getResources() //此方法会 多次 调用
        Resources resources = super.getResources();
        int smallestScreenWidthDp1 = resources.getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application getResources: 1=========" + smallestScreenWidthDp1);
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 300;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        int smallestScreenWidthDp2 = resources.getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "Application getResources: 2=========" + smallestScreenWidthDp2);
        return resources;
    

public class MainActivity8 extends AppCompatActivity implements View.OnTouchListener 
    private static final String TAG = MainActivity8.class.getSimpleName();

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main8);

        Context baseContext = getBaseContext();
        Context applicationContext = getApplicationContext();
        
            Log.e(TAG, "this: ========" + this);//【803afaa】
            Log.e(TAG, "getBaseContext(): ========" + baseContext);//【93c79b】
            //getApplication 和 getApplicationContext 一样地址
            Log.e(TAG, "getApplication(): ========" + getApplication()); //【@29f6738】
            Log.e(TAG, "getApplicationContext(): ========" + applicationContext);//【29f6738】
        

        
            // getResources() 和 getBaseContext().getResources() 在 activity 中同一个对象【ca23311】
            // getApplicationContext().getResources() 为另一个对象 【cc51c76】
            Log.e(TAG, "getResources(): 1=======" + getResources());//【ca23311】
            Log.e(TAG, "getResources(): 2========" + baseContext.getResources());//【ca23311】
            Log.e(TAG, "getResources(): 3========" + applicationContext.getResources());//【cc51c76】

            //activity 中 attachBaseContext 仅仅会影响以下2个:
            int smallestScreenWidthDp1 = getResources().getConfiguration().smallestScreenWidthDp;
            //getResources()会覆盖attachBaseContext()
            Log.e(TAG, "smallestScreenWidthDp: 1========" + smallestScreenWidthDp1);//900
            int smallestScreenWidthDp2 = baseContext.getResources().getConfiguration().smallestScreenWidthDp;
            //getResources()会覆盖attachBaseContext()
            Log.e(TAG, "smallestScreenWidthDp: 2========" + smallestScreenWidthDp2);//900

            //application 中 attachBaseContext 仅仅会影响以下:
            int smallestScreenWidthDp3 = applicationContext.getResources().getConfiguration().smallestScreenWidthDp;
            Log.e(TAG, "smallestScreenWidthDp: 3========" + smallestScreenWidthDp3);//300
        
    

    @Override
    protected void attachBaseContext(Context newBase) //此方法会 1 次调用
        int smallestScreenWidthDp = newBase.getResources().getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "activity attachBaseContext: 1=========" + smallestScreenWidthDp);//720不会变
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 1200;
        super.attachBaseContext(newBase.createConfigurationContext(configuration));
        Log.e(TAG, "activity attachBaseContext: 2=========" + smallestScreenWidthDp);//720不会变
    

    @Override
    public Resources getResources() //此方法会 多次 调用
        Resources resources = super.getResources();
        int smallestScreenWidthDp1 = resources.getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "activity getResources: 1=========" + smallestScreenWidthDp1);
        Configuration configuration = new Configuration();
        configuration.smallestScreenWidthDp = 900;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        int smallestScreenWidthDp2 = resources.getConfiguration().smallestScreenWidthDp;
        Log.e(TAG, "activity getResources: 2=========" + smallestScreenWidthDp2);
        return resources;
    

打印

MyApplication: Application attachBaseContext: 1=========720
MyApplication: Application attachBaseContext: 2=========720
MyApplication: Application getResources: 1=========600
MyApplication: Application getResources: 2=========300
MyApplication: Application onCreate: 1=========300
MyApplication: Application onCreate: 2=========300

MyApplication: Application getResources: 1=========300
MyApplication: Application getResources: 2=========300
MyApplication: Application getResources: 1=========300
MyApplication: Application getResources: 2=========300
MyApplication: Application getResources: 1=========300
MyApplication: Applic

以上是关于Android通过代码实现多语言切换createConfigurationContextattachBaseContextgetResourcesupdateConfiguration的主要内容,如果未能解决你的问题,请参考以下文章

Android 内多语言切换实现

Android app应用多语言切换功能实现

不只是切换多语言Android

Android国际化多语言切换

Android:应用多语言切换,国际化实现

Android 产品研发-->实现国际化(多语言)