• Android 应用运行期间系统配置(系统语言、字体大小等)改变引发的问题修改


    关于此问题的官方文档:https://developer.android.com/guide/topics/resources/runtime-changes.html

    问题:系统配置发生改变后,会导致back stack中的activity重新走一遍生命周期,从而会引发一些逻辑问题以及状态显示相关的问题。

    解决方法:1.按官方文档来。

           缺点:很明显,需要制定规范,每个activity都需要注意,沟通+维护都会有潜在问题。

           2.由于项目中遇到此问题已经处于维护阶段,针对每个activity按官方文档修改已不太现实,只能简单粗暴的修改:

          (1) 当前处于非主界面,系统配置发生变化后跳转至主界面(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK

          (2)所有activity中带有fragment的,对fragments进行缓存,activity创建时优先读取缓存对fragment

    代码:

    AndroidManifest登录成功的主界面会监听配置改变的事件:

    1 <activity
    2     android:name=".activity.MainActivity"
    3     android:configChanges="locale|layoutDirection|navigation|fontScale"
    4     android:screenOrientation="portrait">
    5 </activity>

    MainActivity监听:

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            Logger.i("@@@@@@","ON Main Activity Cfg change ");
    
            super.onConfigurationChanged(newConfig);
    
            Intent goToMainActivity = new Intent(getApplicationContext(), MainActivity.class);
            goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);; // Will clear out your activity history stack till now
            startActivity(goToMainActivity);
        }

    带有fragment的activity(以下为使用ViewPager管理fragment的修改方法):

    重写onResumeFragments方法,把fragment放入fragmentManager中进行缓存

    1 @Override
    2     protected void onSaveInstanceState(Bundle outState) {
    3         super.onSaveInstanceState(outState);
    4         android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    5         fragmentManager.putFragment(outState, ChannelsFragment.class.getName(), fmChannels);
    6         Logger.d(LOG_TAG,"mainActivity onSaveInstanceState");
    7     }

    onCreate时尝试从缓存中读取:

    1     if(savedInstanceState!=null){
    2             Logger.d(LOG_TAG,"mainActivity onCreate");
    3             fmChannels = (ChannelsFragment) getSupportFragmentManager().getFragment(savedInstanceState,ChannelsFragment.class.getName());
    8 }
         if(fmChannels==null){
          Logger.d(LOG_TAG,"fmChannels is null");
        fmChannels = new ChannelsFragment();
         }

    关于VIewPager使用缓存fragment链接:https://stackoverflow.com/questions/7951730/viewpager-and-fragments-whats-the-right-way-to-store-fragments-state

    里面提到了使用FragmentPageAdapter.instantiateItem(View, int)同样也可以实现缓存读取,也更方便一点。

      附阿里Android开发手册中:

    添 加 Fragment 时 , 确 保 FragmentTransaction#commit() 在 Activity#onPostResume()或者 FragmentActivity#onResumeFragments()内调用。 不要随意使用 FragmentTransaction#commitAllowingStateLoss()来代替,任何 commitAllowingStateLoss()的使用必须经过 code review,确保无负面影响。

    推荐的做法是在 Activity 的onPostResume() 或 onResumeFragments() ( 对 FragmentActivity ) 里 执 行 FragmentTransaction.commit(),如有必要也可在 onCreate()里执行。不要随意改用FragmentTransaction.commitAllowingStateLoss()或者直接使用 try-catch 避免crash,这不是问题的根本解决之道,当且仅当你确认 Activity 重建、恢复状态时,本次 commit 丢失不会造成影响时才可这么做。

    正例:

    public class MainActivity extends FragmentActivity { FragmentManager fragmentManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2);
    fragmentManager = getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); MyFragment fragment = new MyFragment(); ft.replace(R.id.fragment_container, fragment);
    ft.commit();
    } }

    反例:

    public class MainActivity extends FragmentActivity { FragmentManager fragmentManager; @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
    super.onSaveInstanceState(outState, outPersistentState); fragmentManager = getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); MyFragment fragment = new MyFragment(); ft.replace(R.id.fragment_container, fragment);
    ft.commit(); }
    }
  • 相关阅读:
    常用类练习题(用字符串常用类判断输入的一段话是否为回文)
    面向对象综合练习题(动物乐园)
    多态练习题(通过UML建模语言来实现饲养员喂养动物)
    UML建模语言使用的概述
    多态练习题(员工使用不同的交通工具回家)
    多态练习题(宠物医院治疗小动物的问题 ,多态的应用:向上类型传递)
    接口练习题(书信接口)
    接口练习题(实现接口功能拓展的两种方法)
    Oracle rman 各种恢复
    Oracle rman 全备份的一个小例子
  • 原文地址:https://www.cnblogs.com/kelisi-king/p/8510684.html
Copyright © 2020-2023  润新知