内存泄漏发生。无法检测到泄漏并进行清洁

时间:2018-04-16 03:42:35

标签: java android memory-leaks leakcanary

我有以下ConnectivityReceiver类,它扩展了BroadcastReceiver,用于检查互联网连接。 还有另一个活动SplashActivity,它实现了这个类来检查互联网连接。我在OnCreate中注册接收器并在OnDestroy方法中取消注册它。但是,在进行下一个活动后,LeakCanary会在SplashActivity中显示内存泄漏。

我在MyApplication类中实例化了LeakCanary和一些方法。 请在下面找到泄漏的屏幕截图。

有人可以帮助我检测内存泄漏并解决此问题吗?

ConnectivityReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

public class ConnectivityReceiver extends BroadcastReceiver
{
    public static ConnectivityReceiverListener connectivityReceiverListener;
    public ConnectivityReceiver()
    {
        super();
    }

    @Override
    public void onReceive(Context context, Intent arg1)
    {
        if(arg1.getAction() != null && arg1.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION))
        {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if(cm != null)
            {
                NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

                if (connectivityReceiverListener != null)
                    connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
            }
        }
    }
    public static boolean isConnected()
    {
        ConnectivityManager cm = (ConnectivityManager) MyApplication.getInstance().getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if(cm != null)
        {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        }
        return false;
    }
    public interface ConnectivityReceiverListener
    {
        void onNetworkConnectionChanged(boolean isConnected);
    }
}

MyApplication.java

import android.app.Application;
import com.squareup.leakcanary.LeakCanary;

public class MyApplication extends Application
{
    private static MyApplication mInstance;

    @Override
    public void onCreate()
    {
        super.onCreate();
        mInstance = this;

        if(LeakCanary.isInAnalyzerProcess(this))
            return;
        LeakCanary.install(this);
    }
    public static synchronized MyApplication getInstance()
    {
        return mInstance;
    }
    public void setConnectivityListener(ConnectivityReceiver.ConnectivityReceiverListener listener)
    {
        ConnectivityReceiver.connectivityReceiverListener = listener;
    }
}

SplashActivity.java

public class SplashActivity extends AppCompatActivity implements ConnectivityReceiver.ConnectivityReceiverListener
{
    final int REQUEST_CODE_RECOVER_PLAY_SERVICES = 1001, PERMISSION_READ_STORAGE = 0;
    RelativeLayout relativeLayout;
    IntentFilter intentFilter;
    ConnectivityReceiver connectivityReceiver;
    Bitmap thumbnail;

    @Override
    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);
        Fabric.with(this, new Crashlytics());

        setContentView(R.layout.activity_main);

        intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        connectivityReceiver = new ConnectivityReceiver();

        registerReceiver(connectivityReceiver, intentFilter);

        if(checkInternet())
        {
             Intent mainIntent = new Intent(SplashActivity.this, WelcomeActivity.class);
             SplashActivity.this.startActivity(mainIntent);
             SplashActivity.this.finish();
        }
    }

    boolean checkInternet()
    {
        boolean isConnected = ConnectivityReceiver.isConnected();
        showSnack(isConnected);
        return isConnected;
    }
    private void showSnack(boolean isConnected)
    {
        Snackbar snackbar = Snackbar.make(relativeLayout, AppConfig.noInternet, Snackbar.LENGTH_INDEFINITE);
        if(!isConnected)
        {
            snackbar.setAction("GO OFFLINE", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent mainIntent = new Intent(SplashActivity.this, WelcomeActivity.class);
    SplashActivity.this.startActivity(mainIntent);
    SplashActivity.this.finish();
                }
            });
            View sbView = snackbar.getView();
            TextView textView = sbView.findViewById(android.support.design.R.id.snackbar_text);
            textView.setTextColor(Color.WHITE);

            snackbar.setActionTextColor(getResources().getColor(R.color.colorPrimary));
            snackbar.show();
        }
        else
            snackbar.dismiss();
    }
    @Override
    public void onDestroy() {
        unregisterReceiver(connectivityReceiver);
        connectivityReceiver = null;
        super.onDestroy();
    }

    @Override
    public void onPause()
    {
        super.onPause();
    }

    @Override
    public void onResume()
    {
        super.onResume();
        MyApplication.getInstance().setConnectivityListener(this);
    }

    @Override
    public void onNetworkConnectionChanged(boolean isConnected)
    {
        showSnack(isConnected);
    }
}

enter image description here

1 个答案:

答案 0 :(得分:0)

您需要unregisterReceiver(connectivityReceiver);onPause()中的onStop();接收者,因为onDestroy();直到活动堆栈中的活动才会被调用。 onDestroy();将被执行。