กิจกรรม <ชื่อแอป> รั่วออกจาก ServiceConnection <ServiceConnection Name> @ 438030a8 ซึ่งเดิมถูกผูกไว้ที่นี่


135

ฉันกำลังทำงานกับแอป Android ตัวแรก ฉันมีกิจกรรมสามอย่างในแอปของฉันและผู้ใช้ก็สลับไปมาค่อนข้างบ่อย ฉันยังมีบริการระยะไกลซึ่งจัดการการเชื่อมต่อ Telnet แอปจำเป็นต้องเชื่อมโยงกับบริการนี้เพื่อส่ง / รับข้อความ Telnet

แก้ไข ขอบคุณ BDLS สำหรับคำตอบที่เป็นประโยชน์ ฉันได้เขียนโค้ดของฉันใหม่ตามคำชี้แจงของคุณเกี่ยวกับความแตกต่างระหว่างการใช้bindService()เป็นฟังก์ชันแบบสแตนด์อะโลนหรือหลังจากstartService()นั้นและตอนนี้ฉันได้รับข้อความแสดงข้อผิดพลาดรั่วไหลเป็นระยะ ๆ เมื่อใช้ปุ่มย้อนกลับเพื่อวนระหว่างกิจกรรม

กิจกรรมการเชื่อมต่อของฉันมีดังต่อไปนี้onCreate()และonDestroy():

/** Called when the activity is first created. */
@Override
public 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()

@Override
protected 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():

@Override
protected 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

@Override
protected 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 has leaked 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 service
01-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 here
01-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 here
01-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.access$2100(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

แก้ไขครั้งที่ 2
ขอบคุณอีกครั้ง bdls สำหรับคำแนะนำของคุณ ฉันทำตามที่คุณแนะนำและเพิ่มการonUnBind()ลบล้างบริการ onUnBind()จะถูกทริกเกอร์ก็ต่อเมื่อไคลเอนต์ทั้งหมดตัดการเชื่อมต่อกับบริการ แต่เมื่อฉันกดปุ่มโฮมมันจะดำเนินการจากนั้นข้อความแสดงข้อผิดพลาดก็โผล่ขึ้นมา! สิ่งนี้ไม่สมเหตุสมผลสำหรับฉันเนื่องจากลูกค้าทั้งหมดถูกปลดออกจากบริการแล้วลูกค้าจะทำลาย serviceConnection รั่วไหลได้อย่างไร ลองดูสิ:

01-03 19:38:30.837: DEBUG/LightfactoryRemote(1118): Focus onPause()1
01-03 19:38:31.577: WARN/IInputConnectionWrapper(1118): showStatusIcon on inactive InputConnection
01-03 19:38:31.587: DEBUG/LightfactoryRemote(1118): Focus onStop()
01-03 19:38:31.600: DEBUG/LightfactoryRemote(1118): Focus onDestroy() attempted to unbind service
01-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 here
01-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 here
01-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.access$1800(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.onCreate () ได้หรือไม่? (com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote.onCreate (LightfactoryRemote.java:97))
tbruyelle

คำตอบ:


57

คุณยังไม่ได้ระบุรหัสใด ๆ ของคุณLightFactoryRemoteดังนั้นนี่เป็นเพียงข้อสันนิษฐาน แต่ดูเหมือนว่าคุณจะพบปัญหาหากคุณใช้bindServiceวิธีนี้ด้วยตัวเอง

เพื่อให้แน่ใจว่าบริการยังคงทำงานต่อไปแม้ว่ากิจกรรมที่เริ่มต้นจะมีonDestroyวิธีการที่เรียกว่าคุณควรใช้startServiceก่อน

เอกสาร Android สำหรับสถานะstartService :

การใช้ startService () จะแทนที่อายุการใช้งานของบริการเริ่มต้นที่จัดการโดย bindService (Intent, ServiceConnection, int): ต้องการให้บริการยังคงทำงานอยู่จนกว่าจะมีการเรียกใช้ stopService (Intent) ไม่ว่าไคลเอ็นต์ใด ๆ จะเชื่อมต่ออยู่ก็ตาม

ในขณะที่bindService :

ระบบจะพิจารณาว่าจำเป็นต้องใช้บริการตราบเท่าที่มีบริบทการโทร ตัวอย่างเช่นหากบริบทนี้เป็นกิจกรรมที่หยุดบริการจะไม่จำเป็นต้องทำงานต่อไปจนกว่ากิจกรรมจะกลับมาทำงานอีกครั้ง


ดังนั้นสิ่งที่เกิดขึ้นคือกิจกรรมที่ผูกมัด (และเริ่มต้น) บริการได้หยุดลงดังนั้นระบบจึงคิดว่าบริการไม่จำเป็นอีกต่อไปและทำให้เกิดข้อผิดพลาดนั้น (จากนั้นอาจหยุดให้บริการ)


ตัวอย่าง

ในตัวอย่างนี้บริการควรทำงานต่อไปไม่ว่ากิจกรรมการโทรจะทำงานอยู่หรือไม่

ComponentName myService = startService(new Intent(this, myClass.class));
bindService(new Intent(this, myClass.class), myServiceConn, BIND_AUTO_CREATE);

บรรทัดแรกเริ่มต้นบริการและบรรทัดที่สองผูกเข้ากับกิจกรรม


ฉันเริ่มบริการโดยใช้ START_STICKY และเริ่มต้นด้วยความตั้งใจในการบูตด้วย ถ้าฉันเรียก StartService มันจะสร้างอินสแตนซ์ของบริการอื่นขึ้นมาและฉันไม่ต้องการให้ 2 บริการทำงานพร้อมกัน ฉันจะแก้ไขข้อผิดพลาดในกรณีนี้ได้อย่างไร?
opc0de

17
@ opc0de ไม่คุณไม่ได้สร้างบริการอื่นเมื่อคุณเรียก startService () สองครั้ง บริการเป็นสิ่งที่มีเหตุผลตามธรรมชาติ ไม่ว่าคุณจะเริ่มกี่ครั้งบริการเดียวก็จะทำงาน
mahkie

2
วิธีแก้ปัญหาสำหรับการให้บริการต่อในพื้นหลังสำหรับเครื่องเล่นเพลงคืออะไร?
Anand Savjani

46

คุณสามารถใช้ได้:

@Override
public void onDestroy() {
    super.onDestroy();

    if (mServiceConn != null) {
        unbindService(mServiceConn);
    }
}

ยอดเยี่ยม. นั่นคือสิ่งที่มันเป็น
Seltsam

31

คุณผูกในแต่ยกเลิกการเชื่อมโยงในonResume onDestroyคุณควรทำการคลายการonPauseผูกแทนเพื่อให้มีคู่สายผูก / เลิกผูกที่ตรงกันเสมอ ข้อผิดพลาดที่ไม่ต่อเนื่องของคุณคือการที่กิจกรรมของคุณหยุดชั่วคราว แต่ไม่ถูกทำลายจากนั้นจึงกลับมาดำเนินการต่ออีกครั้ง


13

คุณควรจะต้องเลิกผูกบริการในonDestroy()เท่านั้น จากนั้นคำเตือนจะไป

ดูที่นี่ .

ตามที่เอกสารกิจกรรมพยายามอธิบายมีกลุ่มการผูก / เลิกผูกหลักสามกลุ่มที่คุณจะใช้: onCreate () และ onDestroy (), onStart () และ onStop () และ onResume () และ onPause ()


7
อย่างที่คุณอาจเคยมีประสบการณ์เกี่ยวกับ Destroy นั้นค่อนข้างไม่เคยถูกเรียกจากระบบปฏิบัติการ
martyglaubitz

ดูลิงก์ส่งต่อไปยังเนื้อหาต้องห้ามที่นี่ -> คำเตือนเนื้อหาต้องห้าม ทุกคนสามารถเข้าถึงได้หรือไม่? ปุ่ม "ดำเนินการต่อในกลุ่ม" เพียงแค่รีเฟรชหน้าเว็บและแสดงคำเตือนเดียวกันนี้ให้ฉัน
Blaze Gawlik

11

คุณพูดถึงผู้ใช้ที่สลับระหว่างกิจกรรมค่อนข้างเร็ว เป็นไปได้ไหมว่าคุณโทรunbindServiceมาก่อนที่จะมีการเชื่อมต่อบริการ ซึ่งอาจมีผลจากการไม่สามารถคลายการผูกมัดจากนั้นจึงทำให้การผูกรั่ว

ไม่แน่ใจว่าคุณจะจัดการกับเรื่องนี้ได้อย่างไร ... บางทีเมื่อไหร่ที่onServiceConnectedคุณสามารถโทรได้unbindServiceหากonDestroyถูกเรียกไปแล้ว ไม่แน่ใจว่าจะใช้ได้หรือไม่


หากคุณยังไม่ได้ทำคุณสามารถเพิ่มเมธอด onUnbind ในบริการของคุณได้ ด้วยวิธีนี้คุณจะเห็นได้ชัดเจนว่าเมื่อใดที่ชั้นเรียนของคุณเลิกผูกมัดและอาจช่วยในการแก้ไข

@Override
public boolean onUnbind(Intent intent) {
    Log.d(this.getClass().getName(), "UNBIND");
    return true;
}

2

ลองใช้ unbindService () ใน OnUserLeaveHint () ป้องกันไม่ให้ ServiceConnection รั่วไหลออกมาและข้อยกเว้นอื่น ๆ
ฉันใช้มันในรหัสของฉันและใช้งานได้ดี


2

ข้อผิดพลาดนี้เกิดขึ้นเมื่อคุณจะผูกบริการที่มีขอบเขต ดังนั้นโซลควรเป็น: -

  1. ในการเชื่อมต่อบริการเพิ่ม serviceBound ดังต่อไปนี้:

    private final ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // your work here.
    
        serviceBound = true;
    
    }
    
    @Override
    public void onServiceDisconnected(ComponentName name) {
    
        serviceBound = false;
    }
    

    };

  2. เลิกผูกบริการ onDestroy

        if (serviceBound) {
            unbindService(serviceConnection);
        }
    

1

คุณสามารถควบคุมมันได้ด้วยบูลีนดังนั้นคุณจะเรียกเลิกผูกก็ต่อเมื่อมีการผูก

public void doBindService()
{
    if (!mIsBound)
    {
        bindService(new Intent(this, DMusic.class), Scon, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }
}

public void doUnbindService()
{
    if (mIsBound)
    {
        unbindService(Scon);
        mIsBound = false;
    }
}

หากคุณต้องการคลายการเชื่อมต่อหากมีการเชื่อมต่อเท่านั้น

public ServiceConnection Scon = new ServiceConnection() {

    public void onServiceConnected(ComponentName name, IBinder binder)
    {
        mServ = ((DMusic.ServiceBinder) binder).getService();
        mIsBound = true;
    }

    public void onServiceDisconnected(ComponentName name)
    {
        mServ = null;
    }
};

0

ทุกบริการที่ผูกพันในกิจกรรมจะต้องเลิกผูกเมื่อปิดแอป

ดังนั้นลองใช้

 onPause(){
   unbindService(YOUR_SERVICE);
   super.onPause();
 }

0

เมื่อเร็ว ๆ นี้ฉันได้อ่านเกี่ยวกับบริการ Android และมีโอกาสได้เจาะลึกเกี่ยวกับบริการนี้ ฉันพบการรั่วไหลของบริการสำหรับสถานการณ์ของฉันมันเกิดขึ้นเนื่องจากฉันมีบริการที่ไม่ถูกผูกไว้ซึ่งกำลังเริ่มบริการที่ถูกผูกไว้แต่ในสิ่งนี้บริการที่ไม่ถูกผูกไว้ของฉันจะถูกแทนที่ด้วยกิจกรรมกิจกรรม

ดังนั้นเมื่อฉันหยุดบริการที่ไม่ถูกผูกไว้โดยใช้stopSelf ()เกิดการรั่วไหลขึ้นเหตุผลก็คือฉันหยุดบริการแม่โดยไม่ผูกมัดบริการที่ผูกไว้ ขณะนี้บริการที่ผูกไว้กำลังทำงานอยู่และไม่รู้ว่าเป็นของใคร

การแก้ไขที่ง่ายและตรงไปตรงมาคือคุณควรเรียกใช้unbindService (YOUR_SERVICE) ใน ฟังก์ชัน onDestroy ()ของกิจกรรม / บริการหลักของคุณ วงจรชีวิตด้วยวิธีนี้จะช่วยให้มั่นใจได้ว่าบริการที่ผูกไว้ของคุณหยุดทำงานหรือล้างข้อมูลก่อนที่กิจกรรม / บริการหลักของคุณจะหยุดทำงาน

มีอีกหนึ่งรูปแบบของปัญหานี้ บางครั้งในบริการที่ผูกไว้ของคุณคุณต้องการให้ฟังก์ชันบางอย่างทำงานเฉพาะในกรณีที่บริการถูกผูกไว้ดังนั้นเราจึงวางธงที่ถูกผูกไว้ในonServiceConnectedเช่น:

public void onServiceConnected(ComponentName name, IBinder service) {
            bounded = true;
            // code here
        }

สิ่งนี้ใช้งานได้ดีจนถึงที่นี่ แต่ปัญหาจะเกิดขึ้นเมื่อเราถือว่าฟังก์ชันonServiceDisconnectedเป็นการเรียกกลับสำหรับการเรียกใช้ฟังก์ชันunbindServiceสิ่งนี้ตามเอกสารจะถูกเรียกเมื่อบริการถูกฆ่าหรือล้มเหลวเท่านั้น และคุณจะไม่เคยได้รับการติดต่อกลับนี้ในหัวข้อเดียวกัน ดังนั้นเราจะทำสิ่งที่ชอบ:

public void onServiceDisconnected(ComponentName name) {
            bounded = false;
        }

ซึ่งสร้างข้อผิดพลาดที่สำคัญในรหัสเนื่องจากค่าสถานะที่ถูกผูกไว้ของเราไม่เคยถูกรีเซ็ตเป็นเท็จและเมื่อบริการนี้เชื่อมต่อกลับมาอีกครั้งเกือบtrueทั้งหมด ดังนั้นเพื่อที่จะหลีกเลี่ยงสถานการณ์นี้คุณควรตั้งค่าเป็นเท็จในขณะที่คุณกำลังเรียกร้องboundunbindService

นี่คือปกในรายละเอียดในเอริคบล็อก

หวังว่าใครเคยมาที่นี่จะพอใจกับความอยากรู้อยากเห็นของเขา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.