แอปรีสตาร์ทแทนที่จะดำเนินการต่อ


195

หวังว่าใครบางคนสามารถช่วยฉันคิดออกถ้าไม่ได้แก้ปัญหาอย่างน้อยคำอธิบายสำหรับพฤติกรรม

ปัญหา:

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

รายละเอียด:

เมื่อคุณกดปุ่ม "ไอคอนเปิด" แอปเริ่มทำงานตามปกติ - นั่นคือผมถือว่าเป็นเจตนาจะเปิดตัวที่มีชื่อของแรกของคุณActivityด้วยการกระทำและหมวดหมู่android.intent.action.MAIN android.intent.category.LAUNCHERอย่างไรก็ตามในกรณีนี้ไม่ได้:

สำหรับอุปกรณ์ส่วนใหญ่หากคุณกดไอคอนตัวเรียกใช้งานหลังจากแอปทำงานอยู่กิจกรรมที่กำลังทำงานอยู่ในกระบวนการนั้นจะกลับมาทำงานต่อ ( ไม่ใช่เริ่มต้นActivity) มันดำเนินการต่อในลักษณะเดียวกับว่าคุณได้เลือกจาก "งานล่าสุด" ในเมนู OS นี่คือพฤติกรรมที่ฉันต้องการในทุกอุปกรณ์

อย่างไรก็ตามในอุปกรณ์อื่นที่เลือกมีพฤติกรรมที่แตกต่างกันเกิดขึ้น:

  • บน Motorola Xoom, เมื่อคุณกดไอคอนตัวที่ App จะเสมอเริ่มเปิดตัวครั้งแรกActivityโดยไม่คำนึงถึงสิ่งที่กำลังทำงาน ฉันคิดว่าไอคอนตัวเรียกใช้เริ่มต้นด้วยเจตนา "เปิดตัว"

  • บน Samsung Tab 2 เมื่อคุณกดไอคอนตัวเรียกใช้งานถ้าคุณเพิ่งติดตั้งแอพมันจะเปิดตัวครั้งแรกเสมอActivity(เหมือน Xoom) - อย่างไรก็ตามหลังจากคุณรีสตาร์ทอุปกรณ์หลังจากติดตั้งไอคอนตัวเรียกใช้จะแทน ดำเนินการแอปต่อ ฉันถือว่าอุปกรณ์เหล่านี้เพิ่ม "แอพที่ติดตั้ง" ลงในตารางการค้นหาเมื่อเริ่มต้นอุปกรณ์ซึ่งอนุญาตให้ไอคอนตัวเรียกใช้งานทำงานต่อได้อย่างถูกต้องหรือไม่

ฉันได้อ่านคำตอบหลายอย่างที่เสียงคล้ายกับปัญหาของฉัน แต่เพียงการเพิ่มandroid:alwaysRetainTaskState="true"หรือใช้launchMode="singleTop"ไปยังActivityไม่ได้คำตอบ

แก้ไข:

หลังจากการเปิดตัวแอพนี้ครั้งล่าสุดเราพบว่าพฤติกรรมนี้เริ่มเกิดขึ้นบนอุปกรณ์ทั้งหมดหลังจากการรีสตาร์ทครั้งแรก ซึ่งดูเหมือนจะบ้าสำหรับฉัน แต่เมื่อมองผ่านกระบวนการรีสตาร์ทฉันไม่พบสิ่งที่ผิดปกติ


1
นี่อาจดูเหมือนคำถามที่ไม่สำคัญที่จะถาม แต่คุณตั้งค่า "อย่าเก็บกิจกรรม" เป็นจริงในตัวเลือกการพัฒนาของคุณสำหรับ Xoom หรือไม่?
Andrew Schuster

Nope (ฉันต้องการ! :)) - ฉันบันทึกวงจรชีวิตของแต่ละกิจกรรมและกิจกรรมในพื้นหลังเท่าที่มีอยู่ (หยุดแล้ว - ไม่ถูกทำลาย) ระบบปฏิบัติการดูเหมือนว่าจะเรียกfinish()พวกเขาในกรณีที่มันเริ่มครั้งแรกActivityอีกครั้งแทนที่จะกลับมาทำงานต่อ
แกรม

1
หากคุณกดปุ่มโฮมแล้วคลิกที่ไอคอนตัวเรียกใช้งานประวัติการทำงานนั้นเป็นค่าเริ่มต้นสำหรับ Android เนื่องจากคุณอาจทราบ อย่างไรก็ตามหากคุณกดปุ่มย้อนกลับเพื่อกลับไปที่หน้าจอหลักโทรศัพท์ส่วนใหญ่จะเสร็จสิ้น () แอป เป็นไปได้หรือไม่ว่าวิธีการที่คุณใช้เพื่อออกจากแอพนั้นแตกต่างกันไปตามอุปกรณ์ต่าง ๆ หรือไม่? คุณสามารถออกจากระบบ onKeyUpEvent เพื่อตรวจสอบว่ามีบางคนไม่จัดการ tkeys ยาก / นุ่มอย่างแปลก ๆ ?
Nick Cardoso

2
Nope - ฉันแน่ใจว่าปัญหาดังกล่าวข้างต้น การใช้งานที่บ้านเพื่อทำให้แอปอยู่ในพื้นหลัง (ไม่ใช่กลับมาซึ่งคุณคิดว่าถูกต้องจะเสร็จสิ้น) กิจกรรม) เป็นไปได้ที่ Xoom จะกลับมาใช้งานแอปจากรายการงาน (ไม่ใช่จากตัวเรียกใช้) เพื่อให้แบ็คสแต็คไม่ถูกฆ่าตายอย่างแน่นอน
แกรม

1
คำตอบด้วยเงินรางวัลเป็นวิธีการแก้ไขปัญหาที่อธิบายไว้ในคำถาม ทำเครื่องหมายคำตอบของฉันเองว่า "ถูกต้อง" เพราะแม้ว่าบางครั้งปัญหาเกิดจากข้อบกพร่องของแอปในตัวเรียกใช้งาน (ตามที่ระบุไว้ในคำตอบของเขา) ปัญหาเฉพาะของฉันเกิดจากการสลับงาน การแก้ไขปัญหาทั้งสองแบบได้รับการแก้ไขโดยวิธีแก้ไขของเขา
แกรม

คำตอบ:


238

พฤติกรรมที่คุณกำลังประสบมีสาเหตุมาจากปัญหาที่มีอยู่ในตัวเรียกใช้ Android บางตัวตั้งแต่ API 1 คุณสามารถดูรายละเอียดเกี่ยวกับข้อบกพร่องรวมถึงวิธีแก้ปัญหาที่เป็นไปได้ที่นี่: https://code.google.com/p/android/issues/ รายละเอียด?

เป็นปัญหาที่พบได้บ่อยในอุปกรณ์ Samsung เช่นเดียวกับผู้ผลิตรายอื่นที่ใช้ตัวเรียกใช้งาน / สกินแบบกำหนดเอง ฉันไม่เห็นปัญหาเกิดขึ้นในตัวเรียกใช้งานหุ้น Android

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

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

นี่คือสิ่งที่ฉันทำใน onCreate () ของกิจกรรมเริ่มต้น / เรียกใช้:

    if (!isTaskRoot()
            && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
            && getIntent().getAction() != null
            && getIntent().getAction().equals(Intent.ACTION_MAIN)) {

        finish();
        return;
    }

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

3
ฉันคิดว่านี่เป็นวิธีที่เหมาะสมในการจัดการกับข้อผิดพลาดนี้ ได้ผลสำหรับฉัน
Sokolov

3
ทำงานให้ฉันได้ตรวจสอบกับอุปกรณ์ที่แตกต่างกันประมาณ 8 ชิ้น ขอบคุณมาก ๆ!
shaya ajzner

3
WOOOOOW แก้ไขปัญหาของฉันแล้วฉันกำลังมองหาวิธีแก้ไขในช่วง 2 ชั่วโมงที่ผ่านมา
Jean Raymond Daher

2
ขอบคุณ @ starkej2 ทำงานเหมือนจับใจ
Rajeev Sahu

55

คำถามนี้ยังมีความเกี่ยวข้องในปี 2559 วันนี้ผู้ทดสอบ QA รายงานว่าแอปของฉันเริ่มต้นใหม่แทนที่จะกลับมาทำงานต่อจากตัวเปิดใช้งานสต็อกใน Android M

ในความเป็นจริงระบบกำลังเพิ่มกิจกรรมที่เรียกใช้ไปยังtask-stackปัจจุบัน แต่ปรากฏแก่ผู้ใช้ราวกับว่าการรีสตาร์ทเกิดขึ้นและพวกเขาจะสูญเสียงานของพวกเขา ลำดับคือ:

  1. ดาวน์โหลดจาก play store (หรือ sideload apk)
  2. เปิดแอพจากกล่องโต้ตอบ play store: activity A ปรากฏขึ้น[task stack: A]
  3. นำทางไปยังกิจกรรม B [task stack: A -> B]
  4. กดปุ่ม 'หน้าแรก'
  5. เปิดแอปจากลิ้นชักแอป: กิจกรรม A ปรากฏขึ้น! [ภาระงาน: A -> B -> A] (ผู้ใช้สามารถกดปุ่ม 'ย้อนกลับ' เพื่อไปที่กิจกรรม 'B' จากที่นี่)

หมายเหตุ: ปัญหานี้ไม่ปรากฏสำหรับการดีบัก APK ที่ปรับใช้ผ่าน ADB เฉพาะใน APK ที่ดาวน์โหลดจาก Play Store หรือโหลดด้านข้าง ในกรณีหลังเจตนาการเรียกใช้จากขั้นตอนที่ 5 มีการตั้งค่าสถานะIntent.FLAG_ACTIVITY_BROUGHT_TO_FRONTแต่ไม่ได้อยู่ในกรณีการดีบัก ปัญหาจะหายไปเมื่อแอปเริ่มเย็นจากตัวเรียกใช้ ความสงสัยของฉันคืองานมีเจตนาที่ไม่ถูกต้อง (ถูกต้องมากขึ้นและไม่ได้มาตรฐาน) ที่ป้องกันพฤติกรรมการเปิดตัวที่ถูกต้องจนกว่างานจะถูกล้างออกทั้งหมด

ฉันลองใช้โหมดเรียกใช้กิจกรรมต่างแต่การตั้งค่าเหล่านั้นเบี่ยงเบนจากพฤติกรรมมาตรฐานที่ผู้ใช้คาดหวัง: กลับมาทำงานที่กิจกรรม B ดูคำจำกัดความของพฤติกรรมที่คาดหวังต่อไปนี้ในคำแนะนำเกี่ยวกับ Tasks และ Back Stackที่ด้านล่างของหน้า ใต้ 'การเริ่มภารกิจ':

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

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

                    /**
     * Ensure the application resumes whatever task the user was performing the last time
     * they opened the app from the launcher. It would be preferable to configure this
     * behavior in  AndroidMananifest.xml activity settings, but those settings cause drastic
     * undesirable changes to the way the app opens: singleTask closes ALL other activities
     * in the task every time and alwaysRetainTaskState doesn't cover this case, incredibly.
     *
     * The problem happens when the user first installs and opens the app from
     * the play store or sideloaded apk (not via ADB). On this first run, if the user opens
     * activity B from activity A, presses 'home' and then navigates back to the app via the
     * launcher, they'd expect to see activity B. Instead they're shown activity A.
     *
     * The best solution is to close this activity if it isn't the task root.
     *
     */

    if (!isTaskRoot()) {
        finish();
        return;
    }

อัปเดต: ย้ายโซลูชันนี้ออกจากการแยกการตั้งค่าสถานะความตั้งใจเพื่อสอบถามว่ากิจกรรมอยู่ที่รากของงานโดยตรง การตั้งค่าสถานะเป็นเรื่องยากที่จะคาดการณ์และทดสอบด้วยวิธีต่าง ๆ ทั้งหมดที่มีเพื่อเปิดกิจกรรมหลัก (เปิดตัวจากที่บ้านเปิดตัวจากปุ่ม 'up' เปิดตัวจาก Play Store ฯลฯ )


4
"ปัญหาจะหายไปเมื่อแอปเริ่มเย็นจากตัวเรียกใช้" นี่เป็นส่วนที่แปลกประหลาดที่สุดและฉันก็สังเกตเห็นเช่นกัน - ฆ่าแอพหลังจากเปิดตัวครั้งแรกมันเริ่มทำงานได้ตามปกติอีกครั้ง ช่างเป็นบั๊กที่แปลก ขอบคุณสำหรับการวิเคราะห์อย่างละเอียดถี่ถ้วนและสำหรับการแก้ปัญหา
Oded

11
หมายเหตุ: คุณจะได้รับปัญหาในการทำซ้ำอีกครั้งแรกหลังจากล้าง (โดย "เย็นเริ่มต้น" ในขณะที่คุณอธิบายว่ามัน) โดยใช้ "เปิด" จากหน้าของ Google Play ของแอปแม้ว่าคุณจะติดตั้งเอพีเคมันผ่าน Android สตูดิโอ ฉันพบสิ่งนี้มีประโยชน์มากสำหรับการตรวจสอบการแก้ไขการทำงาน
Oded

คำอธิบายที่ดี!
karanatwal.github.io

ขอบคุณสำหรับคำอธิบายนี้ :)
AndroidEnthusiast

2
สิ่งนี้เกิดขึ้นกับแอพมากมาย Google Photos เป็นส่วนสำคัญที่ฉันทดสอบ
Raghubansh Mani

19

Aha! (tldr; ดูข้อความที่เป็นตัวหนาที่ด้านล่าง)

ฉันพบปัญหา ... ฉันคิดว่า

ดังนั้นฉันจะเริ่มต้นด้วยการคาดคะเน เมื่อคุณกดตัวเรียกใช้ก็จะเริ่มต้นเป็นค่าเริ่มต้นActivityหรือหากTaskเริ่มต้นด้วยการเปิดตัวก่อนหน้านี้ก็จะเปิดขึ้นมาด้านหน้า ใส่อีกวิธีหนึ่ง - หากคุณอยู่ในขั้นตอนใด ๆ ในการนำทางของคุณคุณจะสร้างใหม่Taskและfinishเก่าแล้วตัวเรียกใช้งานจะไม่ดำเนินการกับแอป

หากการคาดคะเนนั้นเป็นจริงฉันค่อนข้างแน่ใจว่าควรจะเป็นข้อผิดพลาดเนื่องจากแต่ละคนTaskอยู่ในกระบวนการเดียวกัน

ปัญหาของฉันถูกแก้ไขโดยการลบค่าสถานะเหล่านี้ออกจากสองIntents:

i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );

ในขณะที่มันค่อนข้างชัดเจนว่าFLAG_ACTIVITY_NEW_TASKสร้างใหม่Taskฉันไม่ได้ชื่นชมว่าการคาดคะเนดังกล่าวข้างต้นมีผลบังคับใช้ ฉันคิดว่านี่เป็นผู้ร้ายและลบออกเพื่อทดสอบและฉันยังคงมีปัญหาดังนั้นฉันจึงยกเลิก อย่างไรก็ตามฉันยังคงมีเงื่อนไขด้านล่าง:

i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

หน้าจอเริ่มต้นของฉันเริ่มต้น "หลัก" Activityในแอปของฉันโดยใช้ธงด้านบน หลังจากนั้นหากฉันมี "รีสตาร์ท" แอปของฉันและแอปActivityนั้นยังทำงานอยู่ฉันจะเก็บข้อมูลสถานะไว้เป็นอย่างดี

คุณจะสังเกตเห็นในเอกสารมันไม่ได้กล่าวถึงการเริ่มต้นใหม่Task:

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

ตัวอย่างเช่นพิจารณางานที่ประกอบด้วยกิจกรรม: A, B, C, D ถ้า D เรียก startActivity () ด้วย Intent ที่แก้ไขส่วนประกอบของกิจกรรม B แล้ว C และ D จะเสร็จสิ้นและ B ได้รับ Intent ที่กำหนด ส่งผลให้สแต็กตอนนี้เป็น: A, B

อินสแตนซ์ที่ทำงานอยู่ในปัจจุบันของกิจกรรม B ในตัวอย่างด้านบนจะได้รับความตั้งใจใหม่ที่คุณกำลังเริ่มต้นที่นี่ในเมธอด onNewIntent () หรือทำเสร็จแล้วและเริ่มต้นใหม่ด้วยความตั้งใจใหม่ หากได้ประกาศโหมดเรียกใช้เป็น "หลาย" (ค่าเริ่มต้น) และคุณยังไม่ได้ตั้งค่า FLAG_ACTIVITY_SINGLE_TOP ในเจตนาเดียวกันมันจะเสร็จสิ้นและสร้างขึ้นใหม่ สำหรับโหมดการเรียกใช้อื่น ๆ ทั้งหมดหรือหากตั้งค่า FLAG_ACTIVITY_SINGLE_TOP แล้ว Intent นี้จะถูกส่งไปยังอินสแตนซ์ปัจจุบันของ onNewIntent ()

โหมดการเรียกใช้นี้ยังสามารถใช้เพื่อให้เกิดผลดีร่วมกับ FLAG_ACTIVITY_NEW_TASK: หากใช้เพื่อเริ่มกิจกรรมรูทของภารกิจมันจะนำอินสแตนซ์ที่กำลังทำงานของภารกิจนั้นไปยังส่วนหน้า สิ่งนี้มีประโยชน์เป็นพิเศษตัวอย่างเช่นเมื่อเริ่มต้นกิจกรรมจากตัวจัดการการแจ้งเตือน

ดังนั้นฉันมีสถานการณ์ตามที่อธิบายไว้ด้านล่าง:

  • AเปิดตัวBกับFLAG_ACTIVITY_CLEAR_TOP, Aเสร็จสิ้น
  • Bมีความประสงค์ที่จะเริ่มบริการใหม่เพื่อส่งผู้ใช้Aที่มีตรรกะการเริ่มบริการและ UI (ไม่มีแฟล็ก)
  • AเปิดตัวBด้วย FLAG_ACTIVITY_CLEAR_TOP Aเสร็จสิ้น

ในขั้นตอนนี้การFLAG_ACTIVITY_CLEAR_TOPตั้งค่าสถานะที่สองกำลังเริ่มต้นใหม่Bซึ่งอยู่ในกองซ้อนของงาน ฉันคิดว่าสิ่งนี้จะต้องทำลายTaskและเริ่มต้นใหม่ทำให้เกิดปัญหาของฉันซึ่งเป็นสถานการณ์ที่ยากมากที่จะสังเกตเห็นถ้าคุณถามฉัน!

ดังนั้นหากการคาดคะเนทั้งหมดของฉันถูกต้อง:

  • Launcherดำเนินการต่อเพียงสร้างขึ้นครั้งแรกงาน
  • FLAG_ACTIVITY_CLEAR_TOPจะถ้ามันเริ่มต้นสิ่งที่เหลืออยู่เพียงอย่างเดียวActivityก็สร้างใหม่Task

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

2
ฉันรู้ว่ามันไม่ได้หมายถึง - แต่ผ่านการทดลองและข้อผิดพลาดสิ่งนี้เกิดขึ้นในกรณีของฉัน การลบการตั้งค่าสถานะเหล่านี้แก้ไขปัญหาได้
แกรม

สิ่งนี้ไม่ได้สร้างประวัติย่อที่สมบูรณ์แบบในทุกอุปกรณ์ภายใต้เงื่อนไข
danny117

การลบค่าสถานะแก้ไขปัญหาให้ฉัน ขอบคุณ
Sealer_05

ฉันมีสถานการณ์หน้าจอสแปลช / หน้าจอหลัก แต่ฉันไม่ได้ใช้แฟล็กใด ๆ เพื่อเปลี่ยนจากสาดเป็นหลักยังคงเป็นปัญหาที่ทำซ้ำได้สำหรับฉัน - วิธีนี้ไม่ได้ผลสำหรับฉัน
รอ

12

ฉันมีปัญหาเดียวกันกับอุปกรณ์ Samsung หลังจากค้นหามากคำตอบเหล่านี้ก็ไม่เหมาะกับฉัน ฉันพบว่าในไฟล์AndroidManifest.xmllaunchModeตั้งเป็นsingleInstance( android:launchMode="singleInstance") การลบlaunchModeแอตทริบิวต์นี้แก้ไขปัญหาของฉัน


อันที่จริงนี่ก็เป็นกลอุบายของฉันเช่นกัน ผมพบว่าคำตอบนี้จากคำถาม SO อื่นที่จะเป็นประโยชน์: stackoverflow.com/a/21622266/293280 และสิ่งนี้เขียนถึงlaunchModeคุณค่าประเภทต่าง ๆ: inthecheesefactory.com/blog/…
Joshua Pinter

การแก้ไขนี้ใช้งานได้สำหรับฉัน! เพิ่มสิ่งนี้ไม่ได้อยู่ในรายการ แต่ในแอ็ตทริบิวต์กิจกรรมเหนือคลาสกิจกรรมหลัก
Calin Vlasin

@CalinVlasin คุณช่วยแสดงให้ฉันเห็นว่าคุณใช้ launchMode ได้อย่างไร คุณวางไว้ที่ไหน ขณะนี้ฉันมีมันเช่นนี้ แต่มันก่อให้เกิดปัญหา: <กิจกรรม android: ชื่อ = ". UI.landing.MyActivity" android: configChanges = "สถานที่เกิดเหตุ | เค้าโครงDirection" android: launchMode = "singleTop" android: windowSoftInputMode = "stateAlwaysHidden | AdjustResize ">
j2emanue

นี่คือปัญหาของฉันด้วย ฉันคิดว่าสิ่งนี้ควรใช้ร่วมกับคำตอบที่ยอมรับ (! isTaskRoot ...
behelit

1

ใน Cat s60 ของฉันฉันได้เปิดใช้งาน "ไม่เก็บกิจกรรม" ในตัวเลือกนักพัฒนาการปิดใช้งานสิ่งนี้ทำให้ฉันสามารถสลับแอปได้โดยไม่สูญเสียสถานะของแอพ ...


ไม่ทราบวิธี แต่นี่เป็นอุปกรณ์ของฉัน
realPro

0

วิธีนี้ใช้ได้ผลสำหรับฉัน:

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Intent startMain = new Intent(Intent.ACTION_MAIN);
            startMain.addCategory(Intent.CATEGORY_HOME);
            startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(startMain);
            return false;
        }
        else
            return super.onKeyUp(keyCode, event);
    }

เครดิต: ฉันต้องลดแอปพลิเคชัน Android ให้น้อยที่สุดเมื่อคลิกปุ่มย้อนกลับ

อาจใช้งานไม่ได้กับอุปกรณ์ทั้งหมด แต่สร้างพฤติกรรมการใช้ปุ่ม Home ได้สำเร็จเมื่อกดปุ่มย้อนกลับจึงหยุดกิจกรรมแทนที่จะทำให้เสร็จสิ้น


เคล็ดลับที่น่าสนใจ แต่ไม่ได้แก้ปัญหาตามที่ระบุไว้ มีประโยชน์มากสำหรับปัญหา / คำถามอื่น ๆ
แกรม

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

-1

ฉันมีปัญหาเดียวกันสาเหตุคือ:

(รหัส Kotlin เป็น MainActivity)

override fun onBackPressed() {
    finish()
}

ดังนั้นเมื่อไปที่ MainActivity ของฉันจาก LoginActivity ของฉันฉันจะใช้สิ่งนี้:

    val intent = Intent(this, MainActivity::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    startActivity(intent)

เมื่อใช้การตั้งค่าสถานะเหล่านี้ฉันไม่จำเป็นต้องมีonBackPressed ()ใน MainActivity ของฉันมันจะออกจากแอปตามธรรมชาติเมื่อคลิกย้อนกลับ และเมื่อกดปุ่มโฮมและย้อนกลับไปที่แอปมันจะไม่รีสตาร์ท


-2

วิธีแก้ปัญหาสำหรับผู้ที่ไม่มีความคิดเกี่ยวกับการเขียนโปรแกรมและพบปัญหานี้ในโทรศัพท์ Android ของพวกเขา สิ่งนี้เกิดขึ้นส่วนใหญ่เกิดจากการอัพเกรดเวอร์ชั่น android (เฉพาะข้อสันนิษฐานของฉัน) หลังจากอัปเกรดแอปทั้งหมดของคุณจะได้รับการปรับแต่งให้ใช้แบตเตอรี่น้อยลง แต่สิ่งนี้จะทำให้อุปกรณ์ของคุณช้าลง

วิธีแก้

ไปที่การตั้งค่า >> แอพ >> การตั้งค่าแอพ (มองหาการตั้งค่าลงชื่อที่ใดก็ได้บนหน้าจอ - มันแตกต่างกันไปตามอุปกรณ์ต่าง ๆ ) >> การเพิ่มประสิทธิภาพแบตเตอรี่ (หรือ opti ที่คล้ายกัน [ป้อนคำอธิบายภาพที่นี่] [1] เปิด) >> ย้ายทั้งหมด แอปที่ 'ไม่ปรับสถานะ' (ต้องทำ 1 ต่อ 1 ด้วยตนเอง - อาจอนุญาต / ไม่อนุญาตในโทรศัพท์บางรุ่น) แอปตัวเรียกใช้งานของคุณต้องไม่ 'ปรับให้เหมาะสม' (ตัวเรียกใช้งาน Zen UI ในกรณีของฉัน - นี่คือผู้ร้ายที่ฉันเดา - คุณสามารถลองปรับให้เหมาะสม / ไม่ปรับให้เหมาะสมและรีสตาร์ทแอพอื่นถ้าคุณมีเวลา)ตอนนี้รีสตาร์ทโทรศัพท์ของคุณ (ไม่จำเป็นต้องรีเซ็ตข้อมูล / เซฟโหมดหรือปัญหาใด ๆ )

ลองใช้มัลติทาสก์ทันที :) การกดไอคอนตัวเรียกใช้งานจะส่งผลให้งานปัจจุบันกลับมาทำงานอีกครั้ง :) อุปกรณ์ของคุณจะกลายเป็นไม่ต้องกังวลกับแบตเตอรี่มันจะระบายออกไป


-8

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

ดูเหมือนว่าจะกลับมาทำงานต่อผู้ใช้ แต่จริงๆแล้วเป็นการเริ่มต้นเต็มเป่า

พื้นหลัง: หน่วยความจำที่ใช้โดยแอพที่อยู่ในกิจกรรมหลักที่ยังไม่ได้เริ่มงานนั้นสามารถเรียกคืนได้ง่าย ระบบปฏิบัติการสามารถรีสตาร์ทแอพพลิเคชั่นโดยใช้ชุดบันเดิลดั้งเดิมที่ส่งไปยัง onCreate อย่างไรก็ตามคุณสามารถเพิ่มลงในบันเดิลดั้งเดิมได้ดังนั้นวิธีนี้บันเดิลดั้งเดิมจะมีวัสดุและข้อมูลทั้งหมดที่จำเป็นในการสร้างแอปดังนั้นจึงดูเหมือนว่าจะดำเนินการต่อแล้วonSaveInstanceStateดังนั้นเมื่อแอปของคุณเริ่มต้นใหม่โดยระบบปฏิบัติการคุณสามารถกู้คืนสถานะอินสแตนซ์และไม่มีใครฉลาดในว่าแอปเริ่มต้นใหม่หรือทำงานต่อ ยกตัวอย่างโปรแกรมแผนที่แบบคลาสสิก ผู้ใช้ย้ายไปยังตำแหน่งบนแผนที่แล้วกดปุ่มโฮม สองสัปดาห์ต่อมาแอพการทำแผนที่นี้ยังอยู่ในรายการแอพล่าสุดพร้อมกับ Facebook, pandora และ candy crush ระบบปฏิบัติการไม่เพียง แต่บันทึกชื่อแอพสำหรับแอพที่เพิ่งใช้งาน แต่ยังบันทึกบันเดิลดั้งเดิมที่ใช้ในการเริ่มแอพ อย่างไรก็ตามโปรแกรมเมอร์ได้เขียนรหัสonSaveInstanceState

ตัวอย่าง: บันทึกตำแหน่งกล้องปัจจุบันใน onSaveInstanceState เพียงแค่ใส่แอปลงในแอพและจะต้องเริ่มต้นใหม่ในสัปดาห์ต่อมาจากรายการแอพล่าสุด

@Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        // save the current camera position;
        if (mMap != null) {
            savedInstanceState.putParcelable(CAMERA_POSITION,
                    mMap.getCameraPosition());
        }
    }



@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // get the exact camera position if the app was unloaded.
        if (savedInstanceState != null) {
            // get the current camera position;
            currentCameraPosition = savedInstanceState
                    .getParcelable(CAMERA_POSITION);
        }

หมายเหตุ:คุณยังสามารถใช้onRestoreInstanceStateวิธีการ onCreateแต่ผมพบว่ามันง่ายที่จะเรียกคืนเช่นใน

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

โชคดี


สิ่งนี้ไม่ได้เกิดจากปัญหาหน่วยความจำทั่วไปหรือเงื่อนไข "สถานะหยุดชั่วคราว" เริ่มต้น ฉันลองใช้แอพของฉันในอุปกรณ์หลายตัว (บางตัวมีหน่วยความจำขนาดใหญ่บางตัวมีหน่วยความจำต่ำกว่า)
แกรม

นี่คือเหตุผลที่คุณบันทึกข้อมูลถาวรใน onPauseI ได้ลองใช้แอปของฉันเพื่อกลับมาใช้งานต่ออีกสองสัปดาห์บนโทรศัพท์ที่ฉันใช้ทุกวันและให้ฉันบอกคุณหลังจากผ่านไปสองสัปดาห์วิธี onCreate จะถูกเรียกใช้ onSaveSessionState และฉันใช้ข้อมูลในบันเดิลเพื่อให้กิจกรรมของฉันปรากฏอย่างแน่นอนเมื่อฉันทิ้งไว้ ดังนั้นจึงเป็นเพียงสามวันตั้งแต่คำตอบของฉันดังนั้นจึงไม่มีวิธีที่คุณจะสามารถทำแบบทดสอบสองสัปดาห์ได้ สรุป: แอปสามารถปิดได้ทุกเวลาที่อยู่ในพื้นหลัง
danny117

@ danny117 ฉันไม่คิดว่าคุณมีความเข้าใจที่ถูกต้องปัญหาที่ Graeme กำลังประสบอยู่
starkej2

ฉันเข้าใจปัญหาของแกรม ในอุปกรณ์บางเครื่องกลับมาทำงานต่อแอปที่เรียกใช้สร้าง เสียงเหมือน HTC EVO ของฉัน (Gingerbread) ซึ่งจะฆ่าแอปเพื่อหมุนหน้าจอ ดูเอกสารที่มีข้อความว่าเพื่อให้แอปสามารถเรียกคืนได้ใน onCreate developer.android.com/reference/android/app/
......

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