Android 方向改变时是否会泄漏

Android 方向改变时是否会泄漏,android,android-orientation,resource-leak,Android,Android Orientation,Resource Leak,我已经在CustomWebView中注册了收到的短信。我负责在活动的生命周期中注册和注销接收方。在方向改变之前,一切都很好 我曾尝试将注册/注销接收器置于webview的不同状态下,如onAttachedToWindow()/OnAttachedFromWindow(),onPause()/onResume()(从活动的onPause()/onResume())显式调用),onStart()/onStop()。但似乎没有什么能阻止IntentReceiver在方向改变时泄漏 以下是我尝试过的代码

我已经在CustomWebView中注册了收到的短信。我负责在活动的生命周期中注册和注销接收方。在方向改变之前,一切都很好

我曾尝试将注册/注销接收器置于webview的不同状态下,如
onAttachedToWindow()
/
OnAttachedFromWindow()
onPause()
/
onResume()
(从活动的
onPause()
/
onResume()
)显式调用),
onStart()
/
onStop()
。但似乎没有什么能阻止
IntentReceiver
在方向改变时泄漏

以下是我尝试过的代码:

CustomWebView.java

public class CustomWebView extends WebView {

    BroadcastReceiver reciver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                final Bundle bundle = intent.getExtras();
                try {
                    if (bundle != null) {
                        final Object[] pdusObj = (Object[]) bundle.get("pdus");
                        Log.v(tag, "Got PDUS Obj [" + pdusObj + "]");
                        }
                    }

                } catch (Exception e) {
                    Log.e(tag, "Exception smsReceiver" + e);
                }
            }
        };

    --------------------
    --------------------
    some code
    --------------------

    @Override
    public void onResume() {
        try {
            IntentFilter intents = new IntentFilter(
                    "android.provider.Telephony.SMS_RECEIVED");
            getContext().registerReceiver(reciver, intents);
            Log.i(tag, "Webview sms reciever registered");
        } catch (Exception e) {
            e.printStackTrace();
        }

        super.onResume();
    }

    @Override
    public void onPause() {
        try {
            getContext().unregisterReceiver(reciver);
            Log.i(tag, "Webview sms reciever unregistered");
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onPause();
    }



    // Tried this one too
    /* @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.i(tag, "Billdesk onAttach to window called");
        try {
            IntentFilter intents = new IntentFilter(
                    "android.provider.Telephony.SMS_RECEIVED");
            getContext().registerReceiver(reciver, intents);
            Log.i(tag, "Webview sms reciever registered");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.i(tag, "Billdesk onDetach From window to window called");
        try {
            getContext().unregisterReceiver(reciver);
            Log.i(tag, "Webview sms reciever unregistered");
        } catch (Exception e) {
            e.printStackTrace();
        }

    } */

}
public class MainActivity extends FragmentActivity{

-----------
-----------
-----------

@Override
    protected void onPause() {
        if (this.customWebView != null)
            this.customWebView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        if (this.customWebView != null)
            this.customWebView.onResume();
        super.onResume();
    }

}
MainActivity.java

public class CustomWebView extends WebView {

    BroadcastReceiver reciver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                final Bundle bundle = intent.getExtras();
                try {
                    if (bundle != null) {
                        final Object[] pdusObj = (Object[]) bundle.get("pdus");
                        Log.v(tag, "Got PDUS Obj [" + pdusObj + "]");
                        }
                    }

                } catch (Exception e) {
                    Log.e(tag, "Exception smsReceiver" + e);
                }
            }
        };

    --------------------
    --------------------
    some code
    --------------------

    @Override
    public void onResume() {
        try {
            IntentFilter intents = new IntentFilter(
                    "android.provider.Telephony.SMS_RECEIVED");
            getContext().registerReceiver(reciver, intents);
            Log.i(tag, "Webview sms reciever registered");
        } catch (Exception e) {
            e.printStackTrace();
        }

        super.onResume();
    }

    @Override
    public void onPause() {
        try {
            getContext().unregisterReceiver(reciver);
            Log.i(tag, "Webview sms reciever unregistered");
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onPause();
    }



    // Tried this one too
    /* @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.i(tag, "Billdesk onAttach to window called");
        try {
            IntentFilter intents = new IntentFilter(
                    "android.provider.Telephony.SMS_RECEIVED");
            getContext().registerReceiver(reciver, intents);
            Log.i(tag, "Webview sms reciever registered");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.i(tag, "Billdesk onDetach From window to window called");
        try {
            getContext().unregisterReceiver(reciver);
            Log.i(tag, "Webview sms reciever unregistered");
        } catch (Exception e) {
            e.printStackTrace();
        }

    } */

}
public class MainActivity extends FragmentActivity{

-----------
-----------
-----------

@Override
    protected void onPause() {
        if (this.customWebView != null)
            this.customWebView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        if (this.customWebView != null)
            this.customWebView.onResume();
        super.onResume();
    }

}
当方向改变时,我得到以下错误:

Activity com.abcd.xyz.ActivityClass has leaked IntentReceiver com.abcd.xyz.CustomWebView$2@4898758 that was originally registered here. Are you missing a call to unregisterReceiver()?

提前感谢。

此问题是由于设备屏幕旋转造成的

当手机旋转和屏幕改变方向时,Android通常会破坏应用程序的现有活动和片段并重新创建它们。Android这样做是为了让您的应用程序可以基于新配置重新加载资源

您的接收者已在活动的最后一个对象或实例上注册。因此,解决方案是保存接收器对象

您可以通过重写OnRetainOnConfiguration实例()上的公共对象并在onCreate方法中调用GetLastNonConfiguration实例()来保存任何对象

@Override
public Object onRetainNonConfigurationInstance() {
// Save the reciever obj here

return data;
}

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     data = getLastNonConfigurationInstance();
}

希望这对您有所帮助。

在哪一行出现问题?为什么不在CustomWebView中创建registerReceiver/unregisterReceiver之类的方法,然后从父级onResume/onPause调用它。。。CustomWebView也是活动布局或片段布局的一部分吗?@ρцσѕρєK调用getContext()时出现错误。registerReceiver(Receiver,intents);定向后的CustomWebViewchange@Selvin我也试过了。但是问题没有解决。CustomWebView是片段布局的一部分。