android–Activity泄露了最初绑定在这里的ServiceConnection @ 438030a8

android–Activity泄露了最初绑定在这里的ServiceConnection @ 438030a8,第1张

概述我正在开发我的第一款Android应用.我的应用程序中有三个活动,用户来回切换频繁.我还有一个远程服务,它处理一个telnet连接.应用程序需要绑定到此服务才能发送/接收telnet消息.编辑感谢BDLS提供的信息.我已根据您对使用bindService()作为独立函数或在startService()之间的区别的说

我正在开发我的第一款Android应用.我的应用程序中有三个活动,用户来回切换频繁.我还有一个远程服务,它处理一个telnet连接.应用程序需要绑定到此服务才能发送/接收telnet消息.

编辑
感谢BDLS提供的信息.我已根据您对使用bindService()作为独立函数或在startService()之间的区别的说明重新编写了我的代码,现在我只是在使用后退按钮之间循环时间歇性地获取泄漏错误消息活动.

我的连接活动有以下onCreate()和onDestroy():

/** Called when the activity is first created. */@OverrIDepublic voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    /*     * Initialize the ServiceConnection.  Note that this is the only place startService() is run.     * It is also the only time bindService is run without dependency on connectStatus.     */    conn = new TelnetServiceConnection();    //start the service which handles telnet    Intent i = new Intent();    i.setClassname( "com.wingedvictorydesign.lightfactoryRemote", "com.wingedvictorydesign.lightfactoryRemote.TelnetService" );    startService(i);    //bind to the service    bindService(i, conn, 0);    setContentVIEw(R.layout.connect);    setupConnectUI();}//end OnCreate()@OverrIDeprotected voID onDestroy() {    super.onDestroy();    //unbind the service and null it out    if (conn != null) {        unbindService(conn);        conn = null;        }    if(connectStatus == 0) {        //stop the service        Intent i = new Intent();        i.setClassname( "com.wingedvictorydesign.lightfactoryRemote", "com.wingedvictorydesign.lightfactoryRemote.TelnetService" );        stopService(i);        Log.d("lightfactoryRemote", "Connect onDestroy() attempted to stop service");        }    Log.d("lightfactoryRemote", "Connect onDestroy()");    }//end onDestroy()

因此,服务在活动开始时启动,如果没有成功的telnet连接,则在活动被销毁时停止(connectStatus == 0).仅当成功建立连接时,其他活动才绑定到服务(connectStatus == 1,保存到共享首选项).这是他们的onResume()和onDestroy():

@OverrIDeprotected voID onResume() {    super.onResume();    //retrIEve the shared preferences file, and grab the connectionStatus out of it.    SharedPreferences settings = getSharedPreferences(PREFS_name, MODE_WORLD_WRITEABLE);    connectStatus = settings.getInt("connectStatus", 0);    Log.d("lightfactoryRemote", "Focus onResume with " + connectStatus);    //if a telnet connection is active, start the service and bind to it    if (connectStatus == 1) {        conn = new TelnetServiceConnection();        Intent i = new Intent();        i.setClassname("com.wingedvictorydesign.lightfactoryRemote", "com.wingedvictorydesign.lightfactoryRemote.TelnetService");        bindService(i, conn, 0);        //Todo write restore texvIEw code        }//end if    }//end onResume@OverrIDeprotected voID onDestroy() {    super.onDestroy();    //unbind the service and null it out.    if (conn != null) {        Log.d("lightfactoryRemote", "Focus onDestroy() attempted to unbind service");        unbindService(conn);        conn = null;        }    Log.d("lightfactoryRemote", "Focus onDestroy()");    }//end onDestroy()

因此,绑定发生在onResume()中,以便它将从连接活动中获取更改的状态,并且在onDestroy()函数中,如果需要,它将被解除绑定.

结束编辑

但是在切换活动时,我仍然会间歇性地获取内存泄漏错误消息“Activity已经泄漏了最初绑定的ServiceConnection @ 438030a8”.我究竟做错了什么?

提前感谢任何提示或指示!

完整的错误消息(来自修订后的代码):

01-02 22:04:26.642: DEBUG/lightfactoryRemote(2024): Focus onStop()01-02 22:04:26.642: DEBUG/lightfactoryRemote(2024): Focus onDestroy() attempted to unbind service01-02 22:04:26.642: DEBUG/lightfactoryRemote(2024): Focus onDestroy()01-02 22:04:26.672: ERROR/ActivityThread(2024): Activity com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote$TelnetServiceConnection@439e51e8 that was originally bound here01-02 22:04:26.672: ERROR/ActivityThread(2024): androID.app.ServiceConnectionLeaked: Activity com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote$TelnetServiceConnection@439e51e8 that was originally bound here01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread$PackageInfo$Servicedispatcher.<init>(ActivityThread.java:927)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread$PackageInfo.getServicedispatcher(ActivityThread.java:822)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ApplicationContext.bindService(ApplicationContext.java:842)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.content.Contextwrapper.bindService(Contextwrapper.java:319)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote.onResume(lightfactoryRemote.java:102)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.Instrumentation.callActivityOnResume(Instrumentation.java:1225)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.Activity.performResume(Activity.java:3559)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2838)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread.handleResumeActivity(ActivityThread.java:2866)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread.access00(ActivityThread.java:116)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.os.Handler.dispatchMessage(Handler.java:99)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.os.Looper.loop(Looper.java:123)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at androID.app.ActivityThread.main(ActivityThread.java:4203)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at java.lang.reflect.Method.invokeNative(Native Method)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at java.lang.reflect.Method.invoke(Method.java:521)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:549)01-02 22:04:26.672: ERROR/ActivityThread(2024):     at dalvik.system.NativeStart.main(Native Method)01-02 22:04:26.692: WARN/ActivityManager(558): Unbind Failed: Could not find connection for androID.os.BinderProxy@43c509a8

编辑第二个
再次感谢bdls提出您的建议.我按照你的建议做了,并为服务添加了一个onUnBind()覆盖. onUnBind()实际上只在所有客户端与服务断开连接时触发,但当我点击主页按钮时,它会执行,然后d出错误消息!这对我来说没有意义,因为所有客户端都已从服务中解除绑定,那么如何破坏serviceConnection?看看这个:

01-03 19:38:30.837: DEBUG/lightfactoryRemote(1118): Focus onPause()101-03 19:38:31.577: WARN/IinputConnectionWrapper(1118): showStatusIcon on inactive inputConnection01-03 19:38:31.587: DEBUG/lightfactoryRemote(1118): Focus onStop()01-03 19:38:31.600: DEBUG/lightfactoryRemote(1118): Focus onDestroy() attempted to unbind service01-03 19:38:31.607: DEBUG/lightfactoryRemote(1118): Focus onDestroy()01-03 19:38:31.677: DEBUG/lightfactoryRemote(1125): TelnetService onUnBind()01-03 19:38:31.727: ERROR/ActivityThread(1118): Activity com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote$TelnetServiceConnection@435baeb0 that was originally bound here01-03 19:38:31.727: ERROR/ActivityThread(1118): androID.app.ServiceConnectionLeaked: Activity com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote$TelnetServiceConnection@435baeb0 that was originally bound here01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread$PackageInfo$Servicedispatcher.<init>(ActivityThread.java:886)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread$PackageInfo.getServicedispatcher(ActivityThread.java:781)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ApplicationContext.bindService(ApplicationContext.java:820)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.content.Contextwrapper.bindService(Contextwrapper.java:307)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at com.wingedvictorydesign.lightfactoryRemote.lightfactoryRemote.onResume(lightfactoryRemote.java:102)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.Instrumentation.callActivityOnResume(Instrumentation.java:1225)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.Activity.performResume(Activity.java:3530)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread.performResumeActivity(ActivityThread.java:2619)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread.handleResumeActivity(ActivityThread.java:2647)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2287)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread.access00(ActivityThread.java:112)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.os.Handler.dispatchMessage(Handler.java:99)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.os.Looper.loop(Looper.java:123)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at androID.app.ActivityThread.main(ActivityThread.java:3948)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at java.lang.reflect.Method.invokeNative(Native Method)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at java.lang.reflect.Method.invoke(Method.java:521)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:540)01-03 19:38:31.727: ERROR/ActivityThread(1118):     at dalvik.system.NativeStart.main(Native Method)01-03 19:38:31.777: WARN/ActivityManager(564): Unbind Failed: Could not find connection for androID.os.BinderProxy@4370f8a8

我认为它可能就像你说的那样,当调用unbindService()时,对服务的绑定不完整,但是我尝试在服务上调用一个方法,因为我支持每个活动以验证绑定是否完整,并且他们都很好.

一般来说,这种行为似乎与我在每项活动中停留的时间无关.然而,一旦第一个活动泄漏了它的serviceConnection,它们都会在我之后重新执行它们.

另外一件事,如果我在Dev Tools中打开“立即销毁活动”,它会阻止此错误.

有任何想法吗?

解决方法:

你没有提供lightFactoryRemote的任何代码,所以这只是一个假设,但如果你自己使用bindService方法,它看起来就像你会遇到的那种问题.

为了确保服务保持运行,即使在启动它的活动调用了onDestroy方法之后,您也应该首先使用startService.

androID文档为startService状态:

Using startService() overrIDes the default service lifetime that is managed by bindService(Intent, ServiceConnection, int): it requires the service to remain running until stopService(Intent) is called, regardless of whether any clIEnts are connected to it.

鉴于bindService:

The service will be consIDered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed.

所以发生的事情是绑定(并因此启动)服务的活动已经停止,因此系统认为不再需要服务并导致该错误(然后可能会停止服务).

在此示例中,无论调用活动是否正在运行,服务都应保持运行.

Componentname myService = startService(new Intent(this, myClass.class));bindService(new Intent(this, myClass.class), myServiceConn, BIND_auto_CREATE);

第一行启动服务,第二行将其绑定到活动.

总结

以上是内存溢出为你收集整理的android – Activity泄露了最初绑定在这里的ServiceConnection @ 438030a8全部内容,希望文章能够帮你解决android – Activity泄露了最初绑定在这里的ServiceConnection @ 438030a8所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1101621.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存