天天看点

Android开发之fragment的可替代性的探讨

做Android的同学肯定都用过fragment,最常见的就是主界面+下面四个按钮,点击按钮四个fragment相互切换这种模式。

那么,fragment到底是什么东西呢?网上很多人都说fragment是activity的碎片,因为它与activity拥有类似的生命周期,非常方便管理,而且可以使代码分块,结构更加清晰。

这一点确实没错。

那么,除了在代码结构以及运用方便上带来的好处之外,fragment还有没有其他优势呢?

我们做Android app 直接体现出的就是交互是否流畅,换句话说,就是占用内存是否少,运行效率是否高?

那么,现在我用两种情况来做对比。

1。主界面上一个fragment,fragment装载的是一个LinearLayout。

2。主界面上一个直接是一个LinearLayout。

(当然LinearLayout里面就是你的一些业务逻辑之类的)

这就是最简单的两种情况。

那么,fragment能实现的,我们到底能不能直接用view来代替呢?

先上示例代码:

这里package com.example.vftest;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

public class TextActivity extends Activity{

    private Fragment f;
    private MyView v;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.f,null);
        v = new MyView(ll, this);

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        ((IV)v).onResum();
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        ((IV)v).onPause();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        ((IV)v).onStop();
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        ((IV)v).onDestory();
    }
}
写代码片
           
package com.example.vftest;

import android.app.Activity;
import android.widget.LinearLayout;

public class MyView implements IV {
    private LinearLayout layout;
    private Activity activity;

    public MyView(LinearLayout layout, Activity activity) {
        super();
        this.layout = layout;
        this.activity = activity;
    }

    //界面逻辑
    private void init(){

    }

    @Override
    public void onResum() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPause() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStop() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onDestory() {
        // TODO Auto-generated method stub

    }
}
           
package com.example.vftest;

public interface IV {
    void onResum();
    void onPause();
    void onStop();
    void onDestory();
}
           

大家在这里看到了,如果只是单纯的为了代码结构清晰,我用普通的view同样可以实现,并且还可以灵活的实现接口(可以只实现我需要实现的接口);

1.网上有很多人说什么fragment是activity的碎片,所以在activity加载的时候可以提高效率,不会那么卡,其实这存粹是乱说的,fragment它内部也是去装载了一个容器,然后再用这个容器去加载布局,相当于在普通的view上面再套了一层,所以单纯从效率上来看,fragment只低不高。

2.还有人说是为了适配方便什么的,其实我想说,所谓适配就是在不同的文件夹下写不同的布局,就我上面的那个例子,普通的view也完全可以实现,跟fragment根本没有半毛钱关系。

3.至于很多人都说fragment用起来顺手,那是因为不用我们自己去实现activity的一些生命周期的回调方法罢了。

4。关于fragment的缺点,相信很多用过fragment的同学都遇到过各种各样的问题吧,最常见的应该就是两个fragment的重叠问题了,比如当我们按home键返回桌面去打个电话什么的,然后再回到这个app,这个时候,可能出现内存不足,系统将这个主界面回收了的情况,当我们再进去的时候,系统默认会恢复之前的fragment,但是之前的引用却不指向之前的fragment了,所以会出现无法操作之前的fragment的情况,有人提出的解决方法是将fragment保存到栈里去,重建过后再去栈里寻找,如果有直接用,没有则新建,但是这样又会有一个问题,也就是虽然ffragment的引用虽然有了,但是fragment里面的成员变量的引用又丢失了。

这个问题的解决方法其实 还是在activity的onsaveInstance里面,把super.onsaveInstance()去掉就好了。这是为什么呢,因为从源码可以看到,每次当activity判断自己可能会被销毁的时候,都会执行这个方法 去把fragment保存到内存中,重建再恢复,所以才导致了以上那个问题。

5.fragment还有其他很多问题,因为它的生命周期太过复杂,尤其是数据量大的时候,并且是小概率事件。所以如果真要追求代app功能的完美,最好还是自己写一套管理系统。当然,简单的app,用用也无妨。