Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

Как найти утечку памяти с помощь LeakCanary в Android приложении?

#java #android #android_fragment


Помогите пожалуйста найти утечку памяти.

Вот скриншот найденной утечки с помощью LeakCanary:



Пример кода фрагмента:

public class TheaterFragment extends Fragment {

Typeface face;
private View view;
private RelativeLayout rl;
private LinearLayout linearLayout;
private int wordLheigh, screenWidht, wordLength, margin, btnHeight;
private String word;
private float scale;
private Animation anim;
private int tangelSound, whooshSound;
private SoundPool mSoundPool2;
private int soundMusic;
private boolean startAnim = false;
private LayoutAnimationController controller;

@Override
public void onStart(){
        super.onStart();
    if (!word.equals("suoh") && startAnim) {

        anim = AnimationUtils.loadAnimation(getActivity(), R.anim.theater);
        anim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                mSoundPool2.play(whooshSound, soundMusic, soundMusic, 0, 0, 1);
                rl.setClickable(false);

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                // linearLayout.startLayoutAnimation();
                startAnim = false;

                Animation anim1 = AnimationUtils.loadAnimation(getActivity(), R.anim.blueword);
                anim1.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        mSoundPool2.play(tangelSound, soundMusic, soundMusic, 0,
wordLength, 0.5f);

                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        // rl.setClickable(true);
                    }
                });

                controller = new LayoutAnimationController(anim1, 0.5f);
                linearLayout.setLayoutAnimation(controller);
                linearLayout.setLayoutAnimationListener(new Animation.AnimationListener() {
                    public void onAnimationEnd(Animation _animation) {
                        rl.setClickable(true);

                    }

                    public void onAnimationRepeat(Animation _animation) {
                    }

                    public void onAnimationStart(Animation _animation) {

                    }
                });

                linearLayout.setVisibility(View.VISIBLE);
                linearLayout.startLayoutAnimation();
            }
        });

        rl.setVisibility(View.VISIBLE);
        rl.startAnimation(anim);

    }
}

public void falseClickable(){
    rl.setClickable(false);
    rl.setEnabled(false);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    face = Typefaces.get(getContext(), getContext().getText(R.string.font_droidsans).toString());

    if (Build.VERSION.SDK_INT >= 21)
    {
        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();
        mSoundPool2 = new SoundPool.Builder()
                .setAudioAttributes(attributes)
                .build();
    } else {
        mSoundPool2 = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
    }

    tangelSound = mSoundPool2.load(getActivity(), R.raw.tangel, 1);
    whooshSound = mSoundPool2.load(getActivity(), R.raw.whoosh3, 1);

    scale = getArguments().getInt("scale");
    wordLheigh   = getArguments().getInt("wordLheigh");
    screenWidht = getArguments().getInt("screenWidht");
    word = getArguments().getString("word");
    wordLength = word.length();
    soundMusic = getArguments().getInt("soundMusic");
    startAnim = getArguments().getBoolean("startAnim");
    //Log.e("TylyTaay", Integer.toString(FINAL));
    margin = (int) (getResources().getDimension(R.dimen.word_btn_margin)+0.5f);
    btnHeight = (int) (screenWidht / 10 - 4 * margin +0.5f);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.fragment_theater, container, false);
    rl = (RelativeLayout) view.findViewById(R.id.theaterLayout);
    TextView tv1 = (TextView) view.findViewById(R.id.textView1);
    TextView tv2 = (TextView) view.findViewById(R.id.textView1);
    tv1.setTypeface(face);
    tv2.setTypeface(face);

    if (!word.equals("suoh")){
        linearLayout = (LinearLayout) view.findViewById(R.id.clonWordLayout);
        RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
wordLheigh);
        lparams.setMargins(0, screenWidht, 0, 0);
        linearLayout.setLayoutParams(lparams);
        setClon();
    } else {
        rl.setVisibility(View.VISIBLE);
    }
    return view;
}


@Override
public void onDestroy() {
    super.onDestroy();
    linearLayout.removeAllViews();
    linearLayout = null;

    RefWatcher refWatcher = MyApp.getRefWatcher(getActivity());
    refWatcher.watch(this);
}

private void setClon()
{
    Button btn;
    for(int i = 0; i < wordLength; i++)
    {
        btn = new Button(getActivity());
            char[] ch = {word.charAt(i)};
            String st = new String(ch);
        btn.setText(st);
        btn.setGravity(Gravity.CENTER);
        btn.setPadding(0, 0, 0, 0);
        btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.word_btn_text_size));
        btn.setBackgroundResource(R.drawable.btn_word_win);
        btn.setTextColor(getResources().getColorStateList(R.color.dark_gray));
        btn.setClickable(false);
        btn.setTypeface(face);
        LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(btnHeight,
btnHeight);
        lparams.setMargins(margin, 0,margin, 0);
        linearLayout.addView(btn, lparams); //Добавляем в LinearLayout

    }
    btn = null;
}

public void playSound(int nameSound ) {
    if (soundMusic == 1)
        mSoundPool2.play(nameSound,1,1,0,0,1);}


Пример кода в MainActivity, где вызываю фрагмент:

private void rightAnswer()
{
    if (imgZoom != null) {
        imgZoomBack(wordL);
    }
    wordL.blockWord(false);
    buttonL.blockBtn(false);
    gridView.setOnItemClickListener(null);

    //tf = new TheaterFragment(scale, wordLheigh, screenWidht, word, bar.tvDiamond,
bar.tvLevel, bar.imageView, wordId);
    if (tf == null) {
        tf = new TheaterFragment();
    }

    if (args == null) {
        args = new Bundle();
    }
    args.putFloat("scale", scale);
    args.putInt("wordLheigh", wordLheight);
    args.putInt("screenWidht", screenWidht);
    args.putInt("soundMusic", soundOnOff);
    args.putBoolean("startAnim", true);
    args.putString("word", word);

    //Log.e("TylyTaay", Integer.toString(wordId));
    args.putInt("wordId", wordId);

    tf.setArguments(args);
    args = null;

    getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.frameLayout, tf)
            .commit();

    YoYo.with(Techniques.SlideOutDown)
            .playOn(bar.tgDiamond);
    YoYo.with(Techniques.SlideOutDown)
            .playOn(bar.tgVolume);
    YoYo.with(Techniques.SlideOutDown)
            .playOn(bar.tvDiamond);
    YoYo.with(Techniques.SlideOutDown)
            .playOn(bar.tvLevel);
    bar.imageView.setVisibility(View.VISIBLE);
    YoYo.with(Techniques.SlideInDown)
            .playOn(bar.imageView);}

    


Ответы

Ответ 1



Из опыта работы с LeakСanary могу сказать одно: у меня сложилось такое ощущение, что он указывает не на то что утечки 100% есть, а на то, что утечки возможны. По коду: private View view; private RelativeLayout rl; private LinearLayout linearLayout; обнуляй при закрытии фрагмента

Комментариев нет:

Отправить комментарий