Android / Java:Fragment被销毁时TextInputEditText泄漏

时间:2018-12-15 11:43:15

标签: java android android-fragments memory-leaks leakcanary

我有一个Fragment,布局简单:
ConstraintLayout-> LinearLayout-> TextInputLayout-> TextInputEditText

看起来还可以,但是当我导航到另一个Fragment时,它威胁到了当前的 destroyed LeakCanary 向我显示了一个意外的内存泄漏,与TextInputEditText有关,即使我在null中将其设置为onDestroyView()

LeakCanary 报告:

ConstraintLayout leaked
-> InputMethodManager$ControlledInputConnectionWrapper.mInputConnection
-> EditableInputConnection.mTextView
-> TextInputEditText.mParent

MyFragment.java

public class MyFragment extends Fragment {
    private View view;
    private EditText et;

    public MyFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.my_layout, container, false);
        et   = view.findViewById(R.id.my_et);
        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        et    = null;
        view  = null;

        // No difference, if I  call super.onDestroyView(); here
    }
}

my_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_cl"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/my_et"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password"
                android:inputType="numberPassword" />   
        </android.support.design.widget.TextInputLayout>   
    </LinearLayout>    
</android.support.constraint.ConstraintLayout>

有什么主意吗?预先感谢!

编辑1
当我从布局中删除android.support.design.widget.TextInputEditText时,不会出现泄漏。

1 个答案:

答案 0 :(得分:1)

这不是解决方案,但可能会导致您找到解决方案。

由于您使用的是LeakCanary,请检查其AndroidExcludedRefs.java文件,其中包含Android SDK本身或某些制造商版本中的已知泄漏列表。

它包含InputMethodManager的几个已知泄漏,其中一个可能是您所看到的泄漏的原因。两者都包含指向可能的解决方法的“ Hack”链接。

public function index($id)
{
    $filelocation = 'img/';

    if (file_exists($filelocation . '' . $id)) {
        $im = file_get_contents($filelocation . '' . $id);
        header('content-type: image');
        echo $im;
    } else {

        define('WEBSERVICE', 'http://api.resmush.it/ws.php?img=');
        $s = 'http://www.example.com/hires/' . $id;
        $o = json_decode(file_get_contents(WEBSERVICE . $s));

        if (isset($o->error)) {
            die('Error');
        }
        $ch = curl_init($o->dest);
        $fp = fopen($filelocation . '' . $id, 'wb');
        curl_setopt($ch, CURLOPT_FILE, $fp);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_exec($ch);
        curl_close($ch);
        fclose($fp);
        // Load image
        $im = file_get_contents($filelocation . '' . $id);
        header('content-type: image');
        echo $im;

    }