【问题标题】:Holding context, activity or views as member of a class is bad performance?作为一个类的成员持有上下文、活动或视图是不好的表现吗?
【发布时间】:2014-03-05 21:06:01
【问题描述】:

我有一个红色的地方,将视图保留为活动的成员是不好的性能,因为每个视图都保留对其父上下文的引用,它将填满堆。这是真的吗?

想象一下这个活动:

public class MyActivity extends FragmentActivity{
   private RelativeLayout mainLayout;
   private LineraLayout menuLayout;
   private FrameLayout tableLayout;

   private Button buttonOk;
   private Button buttonCancel;

   @Override
   protected void onCreate(Bundle bundle){
      super.onCreate(bundle);

      mainLayout = (RelativeLayout) findViewById(R.id.mainlayout);
      // And inflating other views
   }
}

适配器呢?

public class MyAdapter extends BaseAdapter{

   private MyActivity activity;
   private ArrayList<MyObjects> myObjects;   

   public MyAdapter (MyActivity activity, ArrayList<MyObjects> myObjects){
      this.activity = activity;
      this.myObjects = myObjects;
   }
}

这是糟糕的表现吗?将活动作为参数而不是上下文传递是不是很糟糕?如果我想从适配器访问父类MyActivity 的公共方法怎么办?

非活动类

public MyDatabase{
   private Context context;
   private SQLiteDatabase db;

   public MyDatabase(Context context){
      this.context = context;
      this.db = new DatabaseHelper(context).getWritableDatabase();
   }

   public Object getData(int id){
      return db.query(params...);
   }

   public static class DatabseHelper extends SQLiteOpenHelper{
      public DatabaseHelper(Context context){
         super(context, "my_db", null, 1);
      }
   }
}

为什么人们说当类构造函数需要Context作为参数时,你应该传递getApplicationContext()而不是Activity?

【问题讨论】:

    标签: android memory reference memory-leaks


    【解决方案1】:

    这与性能不佳无关,而是与可能的内存泄漏有关。传递 getApplicationContext() 而不是 Activity 只是为了避免潜在的内存泄漏。

    活动将视图保留为成员并没有错,因为视图的上下文就是活动。如果activity不持有引用,每次访问视图时都需要调用findViewById,这确实会影响性能。关于适配器,传递activity而不是上下文仍然可以。

    【讨论】:

      【解决方案2】:

      Activity 实例传递给某个方法或在某处存储对它的引用是一种不好的做法,因为在配置更改期间,Android 会创建一个活动的新实例,而旧的实例应该由垃圾收集器删除。但是,如果有人持有对旧 Activity 对象的引用,则 GC 将不会收集它,直到对它的引用存在。所以会发生内存泄漏。

      但是在适配器构造函数的情况下,传递活动实例是完全可以的,因为适配器生命周期与活动生命周期耦合。通常会在活动结束后进行垃圾回收。

      getApplicationContext 返回当前进程的单个全局应用程序对象的上下文,因此可以在整个应用程序代码中安全地使用它。

      【讨论】:

        【解决方案3】:

        传递 Activity 的上下文是最终访问 Activity 的公共方法所需要的,因为无论以何种方式使用 getApplicationContext(),都必须在方法调用期间将其强制转换为 Activity。

        ((MainActivity)context).getMyPublicMehtods() inside the non Activity class.
        

        更多细节@makovkastar 已经很好地定义了它。 :)

        【讨论】:

          猜你喜欢
          • 2013-08-15
          • 2021-07-23
          • 1970-01-01
          • 2020-07-17
          • 2016-06-01
          • 2012-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多