1

The following code is leaking the activity context:

This is actually inside an asyncTask in the onPostExecute

ChatCustomAdapter customAdapter = new ChatCustomAdapter(mContext,   chatData, Typeface.createFromAsset(getAssets(), "font/Helvetica-Bold.ttf"));
mChatList.setAdapter(customAdapter);

inside the adapter the context is used for

inflater = LayoutInflater.from(mContext);

Am I holding a reference to the context? if so how do I release it?

LeakCanary is telling me that the ListView (mChatList) is leaking the context and if i remove setAdapter the leak has gone.

LeakCanary screen shot

Rob85
  • 1,719
  • 1
  • 23
  • 46
  • What is 'Chat instance', is it a singleton that holds a reference to context? If so, there will be a leak. – WenChao Jan 12 '17 at 22:07
  • @WenChao Chat is the activity which just displays a list using the adapter so i presumed that it is leaking the context for the Chat activity – Rob85 Jan 12 '17 at 22:10

2 Answers2

1

EDIT: You can try to wrap your mChatList with WeakReference, for exp:

class ChatTask extends AsyncTask {
  private WeakReference<ListView> mListRef;

  public ChatTask(ListView chatList) {
    mListRef = new WeakReference<ListView>(chatList);
  }

  public void onPostExecute() {
    ListView chatList = mListRef.get();
    if (chatList != null) {
        Context context = chatList.getContext();
        ChatCustomAdapter customAdapter = new ChatCustomAdapter(context, chatData, 
                Typeface.createFromAsset(context.getAssets(), "font/Helvetica-Bold.ttf"));
        chatList.setAdapter(customAdapter);
    }
  }
}

If it still not work, you could try to follow this post


I assume that you create the inflater inside the ChatCustomAdapter constructor and keep that inflater as global variable to use later in getView method?
If that true, I think you should try to remove the variable inflater and inside getView method, create a local inflater by LayoutInflater.from(parentView.getContext);
Hope that helps.

Community
  • 1
  • 1
justHooman
  • 3,044
  • 2
  • 17
  • 15
  • i definitely like this and thought it had fixed it but my leak must be else where as it is still leaking i will update the question now with the LeakCanary screen shot – Rob85 Jan 12 '17 at 21:32
  • i have added the screen shot does it make more sense to you ? – Rob85 Jan 12 '17 at 21:34
  • @Rob85 I updated the answer, pls check if it could help. – justHooman Jan 12 '17 at 23:12
  • Thanks for your help on this, i have found the cause, maybe you can explain better as i don't understand it - see my answer – Rob85 Jan 13 '17 at 10:36
  • @Rob85, Sorry, the leak will depend on how you store the variable `mContext` and `ChatButton`, from just the code you reveal, I cannot found the issue. – justHooman Jan 13 '17 at 17:29
0

ok so i have found the problem but i do not understand it so maybe some can comment and explain or answer with why it does this. the leak was in the Chat activity. to get to the Chat activity i have a button in the previous activity:

    ChatButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View arg0)
        {
            Intent intent = new Intent(mContext, Chat.class);
            mContext.startActivity(intent);
        }
    });

when i start the activity i was starting it from

mContext.startActivity(intent)

if i change this to just

startActivity(intent);

it doesn't leak.

Edit

it does still leak

Rob85
  • 1,719
  • 1
  • 23
  • 46