Как предотвратить утечку активности при входе в Facebook 4.33.0? - PullRequest
0 голосов
/ 26 мая 2018

Уже есть похожие вопросы , но ответы были "используйте последнюю версию, и она будет исправлена".Тем не менее, я думаю, что я использую последнюю версию (4.33.0), но если я создаю простой проект (полный исходный код ниже) и поворачиваю экран, это все равно происходит.Ниже приведен журнал утечек из LeakCanary.

​In com.loser.facebooktest:1.0:1.
* com.loser.facebooktest.MainActivity has leaked:
* GC ROOT thread java.lang.Thread.contextClassLoader (named 'pool-2-thread-1')
* references dalvik.system.PathClassLoader.runtimeInternalObjects
* references array java.lang.Object[].[471]
* references static android.support.v4.content.LocalBroadcastManager.mInstance
* references android.support.v4.content.LocalBroadcastManager.mReceivers
* references java.util.HashMap.table
* references array java.util.HashMap$Node[].[14]
* references java.util.HashMap$Node.key
* references com.facebook.AccessTokenTracker$CurrentAccessTokenBroadcastReceiver.this$0
* references com.facebook.login.widget.LoginButton$2.this$0 (anonymous subclass of com.facebook.AccessTokenTracker)
* references com.facebook.login.widget.LoginButton.mContext
* leaks com.loser.facebooktest.MainActivity instance

Ниже приведен полный исходный код проекта, хотя я пропустил код, автоматически сгенерированный Android Studio (т. Е. Для запуска этого проекта вам необходимо создать стандартную версию).пустой проект и добавьте их ниже).

Если я удаляю btnLoginFacebook.fragment = this, утечка, по-видимому, не возникает, но этот код требуется для получения результата (который я не использовал в этом примере проекта для краткости), и я не смог вызвать btnLoginFacebook.fragment = null, потому что эта функция проверяет null и не разрешает null.Что я сделал не так?Как предотвратить утечку памяти?

BlankFragment

class BlankFragment : Fragment()
{
    var facebookManager:CallbackManager? = null;

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View?
    {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false)
    }


    override fun onStart()
    {
        super.onStart()
        facebookManager = CallbackManager.Factory.create();
        btnLoginFacebook.registerCallback(facebookManager, myCallback)
        btnLoginFacebook.fragment = this;
    }

    override fun onStop()
    {
        super.onStop()
        btnLoginFacebook.unregisterCallback(facebookManager);
        facebookManager = null;
    }

    var myCallback = object : FacebookCallback<LoginResult>
    {
        override fun onSuccess(loginResult: LoginResult)
        {
        }

        override fun onCancel()
        {
        }

        override fun onError(exception: FacebookException)
        {
        }
    }
}

MainActivity

class MainActivity : AppCompatActivity()
{
    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        supportFragmentManager
                .beginTransaction()
                .replace(R.id.placeholder, BlankFragment())
                .commit();
    }
}

MyApplication

class MyApplication : Application()
{
    private val refWatcher: RefWatcher? = null

    companion object
    {
        fun getRefWatcher(context: Context): RefWatcher?
        {
            val application = context.applicationContext as MyApplication;
            return application.refWatcher;
        }
    }

    override fun onCreate()
    {
        super.onCreate()

        if (LeakCanary.isInAnalyzerProcess(this))
        {
            return;
        }
        LeakCanary.install(this);
    }
}

frag_blank XML

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".BlankFragment">

    <com.facebook.login.widget.LoginButton
        android:id="@+id/btnLoginFacebook"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

Activity_main XML

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/placeholder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>

</android.support.constraint.ConstraintLayout>

манифест XML

<manifest package="com.loser.facebooktest"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET">
    </uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    </uses-permission>

    <application
        android:name=".MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
...