Android 系统回收处理

# Android APP回收

1.  Application回收

测试环境:

a). 新建一个Android工程,自定义一个Application和Activity A、B,启动入口为A,A启动后,立即启动B;

b). B启动后,按home键放入后台,在开发环境DDMS中点击关闭进程,然后回到手机桌面,点击APP图标进入应用;

测试现象:

a)、执行了Application的onCreate方法,执行了Activity B的onCreate方法,**并没有执行Activity A的onCreate方法**

#### 结论:

a)、Application被系统回收后,再次进入APP,APP会启动Application和被回收前(Task顶)的Activity

b)、在Application建议不要存成员变量、静态变量、数组、数据结构等与Activity、Service、fragment等常用组件生命周期相关的数据。

c)、Application中能够维护的是,和ApplicationContext生命周期一致的组件和数据,如lib库的初始化,Toast显示、关闭等。

d)、两个组件之前的数据传递,应该使用intent传值,setResult、eventbus、广播等其他方式进行传递,不要讲要传递的数据保存在Appcation里面去做读取操作。

e)、不建议在Application中保存对有Activity、Service、fragment等有生命周期的系统组件或其它被管理的组件持有引用,因为这样做有可能会带来一定的内存泄漏,需要妥善引用和释放。

2. Activity回收机制

Activity的回收处理在日常项目中相对比较容易处理,重写onSaveInstanceState方法,存入需要保存的数据,在onCreate中取出保存数据即可。

a).切换到后台时,依次执行onPause 、onSaveInstanceState 、onStop方法;

b).进入系统设置,切换系统语言,在回到桌面,启动应用,当前activity开始重启

c).activity在重启时,依次执行onDestroy、onCreate、onStart、onRestoreInstanceState、onResume方法。

#### 结论

可以将每一个Activity作为单独的模块来处理,这个模块的输入,输出。并且在他的生命周期中,能接受人机交互的数据输入和其它组件(如广播,Service、接口回调)的传值,这部分数据暂称为过程中输入。当然它也可以发送事件到其它组件去,这里暂不讨论。

a).输入:建议使用Intent传值,在activity被回收后重启时,仍然能从getIntent中获取到输入

b).输出:建议使用setResult方式输出,startActivityFroResult启动的Activity B, 系统被重启后,仍然能通过setResult将Activity B中的数据返回到A的onActivityResult中(如果用广播需要使用粘性广播)

c).过程中输入,这部分的数据需要开发者根据Activity的业务流程选择性或是全部存储到onSaveInstanceState中,在onCreate方法里面,如果savedInstanceState参数不为空,则表示该activity是被系统重启过了的activity,需要从savedInstanceState取出数据,恢复activity状态。

3. Fragment回收机制

Fragment一般会被Activity加载,所以当Activity被重启时,所以Fragment的回收机制需要首先在Activity里面处理

Activity中处理如下代码:

'' if (savedInstanceState == null) {

''  BackUpFragment f = BackUpFragment.newInstance("testbackUp");

''            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

''            fragmentTransaction.replace(R.id.fg_backup, f, "tag");

''            fragmentTransaction.commit();

''        } else {

''            BackUpFragment f = (BackUpFragment) getSupportFragmentManager().findFragmentByTag("tag");

''            if (f == null) {

''                // 创建fragment

''                f = BackUpFragment.newInstance("testbackUp");

''                FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

''                fragmentTransaction.replace(R.id.fg_backup, f, "tag");

''                fragmentTransaction.commit();

''            }

''        }

需要注意的时候,将Fragment放入容器时,记得设置Tag,重启时可以根据Tag找到Fragment

Fragment中的处理代码为:

'' @Override

''    public View onCreateView(LayoutInflater inflater, ViewGroup container,

''                              Bundle state) {

''        if (state != null) {

''            LogUtils.v("true");

''            mData = state.getString("key");

''        } else {

''            LogUtils.v("false");

''        }

''        View rootView = inflater.inflate(R.layout.fg_backup, container, false);

''

''        TextView tv = (TextView) rootView.findViewById(R.id.tv_fg_show);

''        tv.setText(mData);

''        return rootView;

''

''    }

''

'' @Override

''    public void onSaveInstanceState(Bundle outState) {

''        super.onSaveInstanceState(outState);

''        outState.putString("key", mData);

''    }

另外在Fragment嵌套在ViewPager的时候,并非自己添加fragment到FragmentManager中的情况,

需要查看下层代码在添加时是否有给Fragment设置tag,如果设置,则可以在重启后通过代码找到Fragment:

'' if (savedInstanceState != null) {

''            for (int i=0; i<4; i++) {

''                BackUpFragment fragment = (BackUpFragment)

''                        getSupportFragmentManager().findFragmentByTag("android:switcher:" + pager.getId() + ":" + i);

''                if (fragment == null) {

''                    fragment = BackUpFragment.newInstance("fragment" + i);

''                } else {

''                    LogUtils.v("TableLayoutFragmentActivity getBackUp fragment "+i);

''                }

''                mFragmentList.add(fragment);

''            }

''        } else {

''            for (int i=0; i<4; i++) {

''                BackUpFragment fragment = BackUpFragment.newInstance("fragment"+i);

''                mFragmentList.add(fragment);

''            }

''        }

####结论

Fragment回收策略的考虑比Activity麻烦,总结而言有两点:

a).添加Fragment的时候记得给Tag,在Activity中通过fragment通过Tag找到可以使用的Fragment

b).在Fragment中通过onSaveInstanceState方法保存过程输入数据,重启后在onCreateView中获取过程输入数据

你可能感兴趣的:(Android 系统回收处理)