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

标签 java android memory-leaks leakcanary

我有下面的 ConnectivityReceiver 类,它扩展了 BroadcastReceiver,用于检查互联网连接。 还有另一个 Activity SplashActivity,它实现此类来检查互联网连接。我在 OnCreate 中注册接收器并在 OnDestroy 方法中注销它。但是,在进入下一个 Activity 后,LeakCanary 在 SplashActivity 中显示内存泄漏。

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

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

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

最佳答案

您需要在onPause()onStop();unregisterReceiver(connectivityReceiver);接收器,因为onDestroy();直到 Activity 堆栈中的 Activity 才会被调用。 onDestroy(); 将在您完成 Activity 时调用,并且 unregisterReceiver(connectivityReceiver); 将被执行。

关于java - 发生内存泄漏。无法检测泄漏并进行清洁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49849315/

相关文章:

java - 如何将字符数组中的字符添加到Java中的字符串中

android - mediarecorder.setVideoSize() 以最大分辨率失败

android - 如何从多任务 Pane 中删除安装/卸载接收器以杀死应用程序/强制关闭应用程序?

Android:TextView 中的文本不会填满所有可用空间

ios - skpaymentqueue canmakepayments 内存泄漏检查

c++ - 关于调试核心文件C++/linux的一些基本问题?

java - 基于可变属性的TreeSet比较器

java - CXF异步调用异常延迟

macos - PresentedViewControllers 内存泄漏

java - 如何为 vscode 终端定义命令/变量?