ทำไมไม่ใช้ Android เสมอ: configChanges =“ keyboardHidden | ปฐมนิเทศ”?


178

ฉันสงสัยว่าทำไมไม่ใช้ android:configChanges="keyboardHidden|orientation"ในทุก ๆ กิจกรรม (เกือบทุกอัน)?

สินค้า:

  • ไม่จำเป็นต้องกังวลเกี่ยวกับกิจกรรมของคุณที่ถูกหมุน
  • มันเร็วกว่า

ไม่ค่อยดี:

  • จำเป็นต้องเปลี่ยนเค้าโครงของคุณหากขึ้นอยู่กับขนาดหน้าจอ (เช่นเค้าโครงที่มีสองคอลัมน์หรือมากกว่านั้น)

แย่:

  • ไม่มีวิธีที่ยืดหยุ่นในการมีรูปแบบที่แตกต่างกันในทิศทางที่แตกต่างกัน
  • ไม่ค่อยดีเมื่อใช้แฟรกเมนต์

แต่ถ้าเราไม่ใช้เลย์เอาต์ที่แตกต่างกันทำไมล่ะ?


6
คุณควรอธิบายสิ่งที่คุณคิดว่า keyboardHidden | การวางแนวกำลังทำอยู่
Blundell

มันป้องกันไม่ให้ใช้การจัดการดั้งเดิมของการเปลี่ยนแปลงการกำหนดค่าที่ระบุและการอนุญาตให้แอปพลิเคชันจัดการได้ใช่ไหม
Mikooos

2
นั่นเป็นสาเหตุที่ตัวเลือกนี้อยู่ที่นั่นถ้าคุณรู้ว่าคุณกำลังทำอะไร (ไม่มีการเปลี่ยนแปลงทรัพยากร) ให้ใช้มัน
ตัวชี้ Null

ทำไมจึงเร็วกว่าการใช้ ScreenSize
batmaci

คำตอบ:


334

พื้นหลังด่วน

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

เมื่อคุณกำหนดandroid:configChanges="keyboardHidden|orientation"ใน AndroidManifest ของคุณคุณกำลังบอก Android: "โปรดอย่าทำการรีเซ็ตเริ่มต้นเมื่อดึงคีย์บอร์ดออกหรือหมุนโทรศัพท์ฉันต้องการจัดการกับตัวเองใช่ฉันรู้ว่าฉันกำลังทำอะไรอยู่ "

นี่เป็นสิ่งที่ดีหรือไม่? เราจะได้เห็น ...

ไม่ต้องห่วง?

หนึ่งในข้อดีที่คุณเริ่มต้นคือมี:

ไม่จำเป็นต้องกังวลเกี่ยวกับกิจกรรมของคุณที่ถูกหมุน

ในหลายกรณีคนเข้าใจผิดเชื่อว่าเมื่อพวกเขามีข้อผิดพลาดที่จะถูกสร้างขึ้นโดยการเปลี่ยนแปลงการปฐมนิเทศ ( "หมุน") android:configChanges="keyboardHidden|orientation"แล้วพวกเขาก็สามารถแก้ไขได้โดยการวางใน

อย่างไรก็ตาม android: configChanges = "keyboardHidden | ปฐมนิเทศ" ไม่มีอะไรมากไปกว่า bandaid ความจริงมีหลายวิธีที่การเปลี่ยนแปลงการกำหนดค่าสามารถถูกเรียกใช้ ตัวอย่างเช่นหากผู้ใช้เลือกภาษาใหม่ (เช่นสถานที่มีการเปลี่ยนแปลง) กิจกรรมของคุณจะเริ่มต้นใหม่ในลักษณะเดียวกับที่มันทำโดยการเปลี่ยนทิศทาง หากคุณต้องการคุณสามารถดูรายการการเปลี่ยนแปลงการกำหนดค่าได้ทุกประเภท

แก้ไข : ที่สำคัญกว่านั้นเมื่อแฮ็คโบดชี้ให้เห็นในความคิดเห็นกิจกรรมของคุณจะเริ่มต้นใหม่เมื่อแอปของคุณอยู่ในพื้นหลังและ Android ตัดสินใจที่จะเพิ่มหน่วยความจำบางส่วนด้วยการฆ่ามัน เมื่อผู้ใช้กลับมาที่แอปของคุณ Android จะพยายามเริ่มกิจกรรมใหม่ในลักษณะเดียวกับที่ทำถ้ามีการเปลี่ยนแปลงการกำหนดค่าอื่น ๆ หากคุณไม่สามารถจัดการได้ - ผู้ใช้จะไม่มีความสุข ...

กล่าวอีกนัยหนึ่งการใช้android:configChanges="keyboardHidden|orientation"ไม่ใช่ทางออกสำหรับ "ความกังวล" ของคุณ วิธีที่ถูกต้องคือการกำหนดรหัสกิจกรรมของคุณเพื่อให้พวกเขามีความสุขกับการรีสตาร์ท Android ทุกครั้ง นี่เป็นวิธีปฏิบัติที่ดีที่จะช่วยคุณให้คุ้นเคยกับถนน

ดังนั้นเมื่อไรฉันจึงควรใช้

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

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

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

สรุปด่วน

โดยทั้งหมดหากandroid:configChanges="keyboardHidden|orientation"เหมาะสมกับคุณแล้วให้ใช้ แต่โปรดแน่ใจว่าได้ทดสอบสิ่งที่เกิดขึ้นเมื่อมีการเปลี่ยนแปลงบางอย่างเนื่องจากการเปลี่ยนแปลงการวางแนวไม่ใช่วิธีเดียวที่การเรียกใช้การรีสตาร์ทแบบเต็มกิจกรรม


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

14
จาก Android 3.x บนอย่าพลาดที่จะเพิ่ม "screenSize" ---------- android: configChanges = ["mcc", "mnc", "locale", "touchscreen", "keyboard", "keyboardHidden", "การนำทาง", "screenLayout", "fontScale", "uiMode", "ปฐมนิเทศ", "screenSize", "smallScreenSize"]
Michael Biermann

1
ฉันสังเกตเห็นว่าเมื่อคุณใช้แอตทริบิวต์ configChanges แอปของคุณจะไม่สนใจคุณสมบัติการวางแนวล็อค คุณจะแก้ปัญหานี้อย่างไร ถ้าคุณรู้คำตอบโปรดเขียนมันที่นี่: stackoverflow.com/questions/24000361/ …
นักพัฒนา Android

4
Please don't do the default reset when the keyboard is pulled outฉันไม่เคยเห็นกิจกรรมรีสตาร์ทสำหรับคีย์บอร์ดดึงออกมา !
มูฮัมหมัดบาบา

เริ่มใหม่ดีเป็นครั้งคราวตกลงในความคิดของฉัน ... configChanges จัดการกรณีส่วนใหญ่สำหรับฉัน ... ดีอาจจะอยู่ในประเภทอื่น ๆ ในการใช้งานนี้อาจมีปัญหา แต่มันขึ้นอยู่กับมันจริงๆ ....
Renetik

2

จากมุมมองของฉัน: หากเค้าโครงเหมือนกันทั้งในแนวนอนและแนวตั้งคุณอาจปิดการใช้งานหนึ่งในสองรูปแบบในแอปของคุณ

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

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


4
ใช่เราไปกับมันในเวอร์ชัน 1.0 ของแอพของเราเพื่อให้ตรงกับรุ่นของ Apple มันถูกนำเสนอเฉพาะในแนวตั้ง สิ่งที่ดูดีสำหรับ Droid X ของฉันเราจับคู่กับพฤติกรรมของแป้นพิมพ์ป๊อปอัปของรุ่น IOS อย่างแน่นอน จากนั้น CFO ได้ติดตั้งแอพลงบน Droid ของเขาแล้วหันไปทางด้านข้างแล้วเปิดคีย์บอร์ด อุ่ย สิ่งที่เกี่ยวกับ Android คือมันเป็นแพลตฟอร์มเปิดและคุณไม่สามารถคาดการณ์การกำหนดค่าฮาร์ดแวร์ได้หรือสิ่งที่ผู้ใช้ต้องการทำกับมันดังนั้นคุณควรสนับสนุนการหมุนทั้งสองแบบ (ทั้งหมด) ในกรณีนี้
Tevo D

1
ซึ่งบังเอิญไปแทนที่การตั้งค่าแบบแนวตั้งเท่านั้นเนื่องจากโดยทั่วไปแล้วในฮาร์ดแวร์ที่แนวนอนนั้นเป็นแนวปกติไม่ใช่แนวอื่น ซึ่งจริงๆแล้ว messed up เค้าโครงของเรา :( และก็น่าอายสวยมีข้อบกพร่องที่สำคัญภายในไม่กี่วินาทีของเขาติดตั้งแอป
Tevo D

1
ทำไมคุณถึงพยายามทำให้มันเหมือน iOS? :(
FunkTheMonk

7
@FunkTheMonk น่าเสียดายที่เราอยู่ในโลกที่นักธุรกิจตัดสินใจทางเทคนิค แม้ว่าคุณจะโต้แย้งกับมันก็ตามครึ่งเวลาที่พวกเขาคิดว่าถูกต้อง และพวกเขาควบคุมเงินเดือนของคุณ
StackOverflow

2
การใช้เลย์เอาต์เดียวเท่านั้นไม่ได้หมายความว่าหน้าจอจะดูเหมือนกันเมื่อหมุน เค้าโครง XML ที่มีโครงสร้างที่ดีจะทำให้สิ่งต่าง ๆ เลื่อนไปมาโดยอัตโนมัติด้วยขนาดที่เหมาะสมและผู้ใช้จะพึงพอใจ
Melinda Green

-1

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

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

ดังนั้นฆ่าฉัน แต่ฉันใช้สิ่งนี้ข้ามแอปพลิเคชันค่อนข้างประสบความสำเร็จ ... android: configChanges = "locale | keyboard | keyboardHidden | ปฐมนิเทศ | screenLayout | uiMode | screenSize | smallScreenSize" แต่ฉันเข้าใจว่าสำหรับบางแอปพลิเคชันพิเศษ เป็นวิธีที่ดี แต่แอพส่วนใหญ่สามารถอยู่กับสิ่งนี้ได้เพียงแค่ตกลง


สวัสดีใครบางคนสามารถมีความรู้ในหัวข้อนี้โปรดดูที่หัวข้อของฉัน: stackoverflow.com/questions/35941585/…? ต้องการความช่วยเหลืออย่างยิ่ง
ลุคอัลลิสัน

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

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

การเพิกเฉยที่จะปฏิบัติตามสัญญากิจกรรม (สถานะการออม / การกู้คืน) เป็นการปฏิบัติที่ไม่ดีและนี่เป็นคำแนะนำที่แย่มาก ลองทดสอบการเสียชีวิตของกระบวนการและดูว่าแอปของคุณให้คุณไปที่ใดและพฤติกรรมนี้เป็น "สถานการณ์ปกติ" โดยสมบูรณ์หากผู้ใช้ของคุณใช้แอปอย่างน้อย 2-3 แอพในโทรศัพท์และสลับไปมาระหว่างพวกเขา
EpicPandaForce

-3

ใช่ฉันคิดว่าการหยุดชั่วคราวจะทำให้เร็วกว่าการปล่อยผู้เล่นออก ยังคงมีการหยุดแม้ว่า

พบวิธีแก้ปัญหาที่จะไม่หยุดเพลงชั่วคราว

ระบุในรายการที่คุณจะจัดการกับการเปลี่ยนแปลงการกำหนดค่าสำหรับการวางแนวหน้าจอจากนั้นใช้เมธอด onConfigurationChanged เพื่อโหลดไฟล์โครงร่าง เมื่อทำสิ่งนี้ใน logCat ฉันสามารถเห็น onPause, onCreate & onResume ไม่ได้ถูกเรียกและเพลงจึงไม่หยุดชั่วคราว

  1. อัปเดตรายการเพื่อจัดการการวางแนว

    android:configChanges="orientation|screenSize"
  2. เพิ่มรหัสนี้

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub      
        super.onConfigurationChanged(newConfig);        
        setContentView(R.layout.activity_main);
    }

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