【问题标题】:Google Play Services error dialog potential memory leak?Google Play 服务错误对话框可能存在内存泄漏?
【发布时间】:2014-09-11 04:36:37
【问题描述】:

我正在看这个例子 https://developer.android.com/training/location/retrieve-current.html#CheckServices

这里是有问题的代码:

public class MainActivity extends FragmentActivity {
    ...
    private boolean servicesConnected() {
        ...
        if (ConnectionResult.SUCCESS == resultCode) {
            ...
            // Google Play services was not available for some reason.
            // resultCode holds the error code.
        } else {
            // Get the error dialog from Google Play services
            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                resultCode,
                this,
                CONNECTION_FAILURE_RESOLUTION_REQUEST);
            ...
        }
    }
}

如果我们查看GooglePlayServicesUtil.getErrorDialog(..),我们传递的是对this 的引用,它恰好是Activity

问题是: 这会在配置更改期间导致内存泄漏吗?

我想答案取决于GooglePlayServicesUtil.getErrorDialog(..) 如何/是否在内部保留对Activity 的引用。

【问题讨论】:

    标签: android google-play-services


    【解决方案1】:

    是的,我的应用程序曾经泄漏过

    如果您打开 Google Play 服务错误对话框然后再次旋转它会泄漏

    这是我为解决泄漏而采取的解决方案,但这假设您的 Google Play 服务检查在 onResume 中

    public class MainActivity extends Activity
    {
    private Dialog googlePlayErrorDialog;
    
    @Override
        protected void onResume()
        {
            // TODO Auto-generated method stub
            super.onResume();
            int isAvaiable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
            if(isAvaiable == ConnectionResult.SUCCESS)
            {
                Log.d("TEST", "GPS IS OK");
            }
            else if(isAvaiable == ConnectionResult.SERVICE_MISSING || 
                    isAvaiable == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED || 
                    isAvaiable == ConnectionResult.SERVICE_DISABLED)
            {
                googlePlayErrorDialog = GooglePlayServicesUtil.getErrorDialog(isAvaiable, this, 10);
                googlePlayErrorDialog.show();
    
            }
    
        }
    
        @Override
        protected void onPause()
        {
            // TODO Auto-generated method stub
            super.onPause();
            if(googlePlayErrorDialog != null)
            {
                googlePlayErrorDialog.dismiss();
            }
    
        }
    

    所以这里的交易是我将 getErrorDialog 设置为我自己的对话框变量,然后在 onPause 中进行简单的空检查(以避免可怕的空指针异常!)并调用解除。

    如果您想了解更多信息,我从阅读本文中得到了灵感

    http://publicstaticdroidmain.com/2012/01/avoiding-android-memory-leaks-part-1/

    【讨论】:

    • 这解决了内存泄漏,但它是一个糟糕的用户体验。通过配置更改更改屏幕上的内容是糟糕的用户体验。
    • 如果对话框的显示与配置更改之前不完全一样,那就太糟糕了。这就是 onResume 的用武之地。在这个例子中,它很好,因为 GPS 对话框无论如何都会再次出现。对于其他对话框,如果显示对话框,只需设置一个布尔值,然后通过 on Resume 再次显示它并通过 onSavedInstanceState 恢复用户在对话框中更改的变量。这就是为什么我更喜欢在这种自己的私有方法中使用对话代码使事情变得更容易和有条理
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 2011-02-18
    相关资源
    最近更新 更多