【问题标题】:How can I solve this memory leak? Actually, where is the memory leak?我该如何解决这个内存泄漏?实际上,内存泄漏在哪里?
【发布时间】:2017-03-22 00:54:49
【问题描述】:

我想创建一个简单的待办事项应用程序,将数据存储在共享首选项中。因此,我创建了一个名为 PrefManager 的类,其中包含我在连接管理首选项中的所有方法。在这种情况下,方法“getSharedPreferences”需要一个上下文。没关系,但我必须在我的其他类中都使用这个类,包括 recyclerView 适配器类。

所以我做了这个“解决方案”(ToDoActivity):

public static PrefManager mPrefManager;
private RecyclerView mRecyclerView;
private ToDoRecyclerViewAdapter adapter;
private Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_to_do);

    context = getApplicationContext();
    adapter = new ToDoRecyclerViewAdapter(this);
    mPrefManager = new PrefManager(context, adapter);
    mPrefManager.setupThePreferences();
    ...

并到处进口:

   import static bla.bla.bla.ToDoActivity.mPrefManager;

但我收到此错误:

不要将 Android 上下文类放在静态字段中(对 PrefManager 的静态引用,其中字段上下文指向 Context);这是内存泄漏(也会破坏 Instant Run)。静态字段会泄漏上下文。

我怎样才能让它变得更好?我该如何解决这个问题?

编辑

我在 RecycleView 适配器中通过删除一个项目来使用它:

 public class ToDoRecyclerViewAdapter extends RecyclerView.Adapter <ToDoRecyclerViewAdapter.ViewHolder>

那里:

holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
     @Override
     public boolean onLongClick(View v) {

         int identifier = holder.myTodo.getIdentifier();
         removeTodo(position);
         mPrefManager.deleteThePref(identifier);

         return false;
    }
});

或者在我的 Todo 创建活动中:

public class CreateActivity extends Activity

那里:

btnCreateExit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mPrefManager.saveNewToDo(editTodoTitle.getText().toString(), spinnerTodoPriority.getSelectedItemPosition(), editTodoDescription.getText().toString(), date);
        finish();
    }
});

【问题讨论】:

  • 我建议你不要把adapter传给PrefManager,它更像是你保存数据和获取数据的工具。并且该工具可以从任何地方获取instanseof context。
  • 您能解释一下吗?我只是在学习这个。 :)
  • 你想去哪里PrefManager ?活动还是什么?如果可能的话,显示PrefManager
  • 已编辑。我添加了一些示例。
  • 我认为你不应该这样使用public static PrefManager mPrefManager;。因为这个静态对象将保存上下文(来自适配器)并且 GC 无法回收 Activity。

标签: java android memory memory-leaks


【解决方案1】:
  • TodoActivity中,声明PrefManager并为其生成getter

    private PrefManager mPrefManager;
    public PrefManager getmPrefManager{
        return mPrefManager;
    }
    
  • Adapter中,当你删除一个项目时:

     removeTodo(position);
     ((TodoActivity)context).getmPreManager().deleteThePref(identifier);
    
  • PrefManager 重新创建构造函数并仅传递context

    public PrefManager(Context context){
         super();
         context.getSharedPreferences(...);
    }
    
  • CreateActivity,新建一个PrefManager

    mPrefManager = new PrefManager(context);
    mPrefManager.setupThePreferences();
    

【讨论】:

  • 上帝保佑你,它的工作原理:) 但我还有一个愚蠢的问题:当我只传递一个context 时,我如何得到一个adapter? (因为它是一个全新的对象,不是吗?)或者它的工作只是因为方法 setupThePreferences() 不使用 adapter
  • 你想把适配器放在哪里?通常当前的适配器只能从当前的Activity中获取。
【解决方案2】:

尝试扩展您的活动以访问您的 ToDoActivity。

例如:

public class AnotherActivity extends ToDoActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);

context = getApplicationContext();
adapter = new ToDoRecyclerViewAdapter(this);
mPrefManager = new PrefManager(context, adapter);
mPrefManager.setupThePreferences();
...
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多