คำแนะนำที่ละเอียดเกินไปสำหรับไลบรารี Android ที่ใช้งานไม่ได้

เผยแพร่แล้ว: 2022-03-11

นักพัฒนาที่มีประสบการณ์จะบอกคุณว่าโค้ดที่ดีที่สุดไม่ใช่โค้ดที่พวกเขาเขียน เป็นรหัสที่เอามาจากงานของคนอื่น

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

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

แต่ในกรณีที่ SDK ใช้งานไม่ได้ ชุมชน Android ได้สร้างไลบรารีระดับแนวหน้าขึ้นมาบางส่วน ซึ่งสามารถช่วยคุณประหยัดงานเขียนโค้ดได้มากมาย แทนที่ด้วยการใช้งานที่ได้รับการปรับแต่ง ตรวจสอบ และทดสอบอย่างเข้มงวด ฉันไม่ได้หมายถึงไลบรารี่ที่ชัดเจน—ไลบรารีสนับสนุน Android, ไลบรารีสนับสนุนการออกแบบ Android, Gson ฉันหมายถึงเครื่องมือที่คุณอาจไม่รู้ และถึงแม้ว่าคุณจะยังไม่ได้ใช้งานก็ตาม

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

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

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

การเลือกห้องสมุด Android ที่เหมาะสม

เมื่อเลือกห้องสมุด ฉันมองหาคุณสมบัติหลักสี่ประการ:

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

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

Android Libraries

ห้องสมุดที่ฉันกล่าวถึงด้านล่างผ่านการทดสอบทั้งสี่แบบ พวกเขายังแก้ปัญหาด้านการพัฒนามือถือที่ท้าทายที่สุดบางส่วน

  • ไลบรารีสองไลบรารีสำหรับการฉีดขึ้นต่อกัน การโยงเลย์เอาต์กับ Java วัตถุจำลอง
  • รูปแบบข้อความผับ/ย่อยในแอป
  • เลเยอร์การสื่อสาร HTTP ที่ปลอดภัย มีประสิทธิภาพ และกู้คืนได้เอง
  • การจัดการรูปภาพ: ดาวน์โหลด แคช ปรับขนาด และโหลดลงใน RAM
  • การสตรีมวิดีโอแบบเรียลไทม์
  • การตรวจจับการรั่วไหลของหน่วยความจำ

ButterKnife: เครื่องมือฉีดพึ่งพาขั้นสูงสุด

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

บางคนอาจโต้แย้งว่า ButterKnife คือสิ่งที่เลย์เอาต์ของ Android ในการทำแผนที่ Java ควรจะเป็นตั้งแต่แรก

Android Butterknife การพึ่งพาการฉีด

ไม่จำเป็นต้องผูกแต่ละมุมมองของคุณโดยตรงผ่านการเรียก findViewById() ; แต่มีมุมมองที่มีคำอธิบายประกอบซึ่งช่วยให้คุณเข้าถึงโค้ดได้โดยตรง ButterKnife ยังช่วยลดความจำเป็นในเหตุการณ์ UI ของสำเร็จรูป เช่น onClick , onTouch และอื่นๆ และแทนที่ด้วยโค้ดที่ฉีดอัตโนมัติ

แต่พอคุยเล่นๆมาดูโค้ดกัน

ดูการผูกฟิลด์:

 class MyButterKnifeActivity extends Activity { @BindView(R.id.name) TextView name; @BindView(R.id.address) TextView address; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // MUST BE CALLED BEFORE ACCESSING UI FIELDS name.setText(“etc etc”); } }

การเชื่อมโยงทรัพยากร:

 class ExampleActivity extends Activity { @BindString(R.string.username) String username; @BindDrawable(R.drawable.graphic) Drawable graphic; @BindColor(R.color.bg_color) int bgColor; @BindDimen(R.dimen.lower_padding) Float lowerPadding; // and no need for getResources().getString()/getDrawable/getColor() }

การเชื่อมโยงเหตุการณ์ UI:

 @OnClick(R.id.my_button) public void clickHandler(View view) { // onClick logic goes here }

AndroidAnnotations: การพึ่งพาการฉีดไปสู่ระดับถัดไป

เป็นวินาทีที่ใกล้เคียงกับ ButterKnife เมื่อพูดถึงการพึ่งพาการฉีด AndroidAnnotations ใช้แนวทางที่แตกต่างออกไปเล็กน้อย: คลาสที่สร้างโดยอัตโนมัติซึ่งเมื่อคุณเข้าใจแล้วจะง่ายมาก มีประโยชน์มากกว่านั้นคือมันช่วยให้คุณฉีดการพึ่งพา "ตามชื่อ" ได้ ตัวอย่างเช่น @ViewById ListView myUserList; สั่งให้ไลบรารีกำหนดฟิลด์นี้ด้วย layoutListView โดยใช้ชื่อเดียวกัน

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

แต่ความสามารถในการฉีดของ AndroidAnnotations ทำได้มากกว่านั้น คุณสามารถใส่ทั้งสถานะและเลย์เอาต์ลงในกิจกรรมได้

การใช้งาน AndroidAnnotations:

 @NoTitle @Fullscreen @EActivity(R.layout.my_layout) public class MyActivity extends Activity { @ViewById ListView customerList; // auto-binded to R.id.customerList @App MyApplication app; // auto-binded to app object @AminationRes Animation fadeoutAnimation; @UiThread void updateUI() { // main thread action } }

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

 new Handler(Looper.getMainLooper()).post(new Runnable() { logic goes here } ); // NO ANNOTATIONS

ใน AndroidAnnotations สิ่งที่คุณต้องทำคือใส่คำอธิบายประกอบให้กับฟังก์ชันของคุณด้วย @UiThread และตอนนี้ก็รับประกันว่าจะดำเนินการทุกครั้ง:

 @UiThread void updateUI() {..} // WITH ANNOTATIONS

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

ที่นี่ AndroidAnnotations มาพร้อมกับแนวคิดใหม่ที่มาจาก EBean สิ่งที่คุณต้องทำคือทำเครื่องหมายชั้นเรียนของคุณโดยใช้ @EBean และคุณพร้อมแล้ว:

 @EBean public class MyNonComponentClass { @SystemService NotificationManager notifManager; @Bean MyOtherClass dependency; @UiThread void updateUI() { // main thread work goes here } }

EventBus: การสื่อสารข้ามส่วนประกอบทำได้ง่าย

ห้องสมุด EventBus เปลี่ยนปัญหาที่หลอกหลอนนักพัฒนา Android มานานหลายปีให้กลายเป็นการเดินเล่นในสวนสาธารณะ การสื่อสารข้ามองค์ประกอบไม่เคยง่ายอย่างนี้มาก่อน—ใช้โมเดล pub/sub ที่เรียบง่ายเพื่อสื่อสารระหว่างสองส่วนใดๆ ของระบบของคุณ

แอนิเมชั่น EventBus

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

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

การใช้งาน EventBus นั้นตรงไปตรงมา

ก. สร้างคลาสเหตุการณ์ การทำงานกับ POJO ที่นี่ดีที่สุด:

 class NewUserEvent { String fullname; String address; String role; // add getters and setters }

ข. สร้างวิธีจัดการเหตุการณ์ในชั้นเรียน—ชั้นเรียนใดๆ ที่คุณต้องการสมัครเข้าร่วมกิจกรรมเหล่านี้:

 class MySubscriber { @Subscribe public void newUserHandler(NewUserEvent event) { // handle NewUserEvent } @Subscribe public void newUserHandler(AnotherEvent event) { // handle AnotherEvent } }

แต่เดี๋ยวก่อน นักพัฒนา Android ที่มีประสบการณ์ครึ่งหนึ่งจะหยุดและถาม ณ จุดนี้: ตัวจัดการเธรดรุ่นใด และฉันสามารถบังคับตัวจัดการให้ปิดเธรดหลักได้หรือไม่ ถ้าพูด เกี่ยวข้องกับการเข้าถึงองค์ประกอบ UI คำถามที่ดี…

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

 @Subscribe(threadMode = ThreadMode.MAIN) public void runOnMainThreadHandler(AnotherEvent event) { … }

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

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

 class MySubscriberActivity extends Activity { @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); // START RECEIVING EVENTS HERE } @Override public void onStop() { EventBus.getDefault().unregister(this); // NO MORE EVENTS super.onStop(); } }

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

ง. และสุดท้าย เริ่มเหตุการณ์จริง:

 EventBus.getDefault().post(new MyEvent(“I'm here”));

มีอะไรอีกมากมายให้รู้เกี่ยวกับการใช้ EventBus: เหตุการณ์มัลติคาสต์ (พฤติกรรมเริ่มต้น) การใช้เหตุการณ์เหนียว เธรดการนำส่ง ลำดับความสำคัญ และอื่นๆ แต่ข้างต้นก็เพียงพอแล้วสำหรับคุณในการเริ่มต้นใช้เทคโนโลยีที่เรียบง่ายแต่ทรงพลังนี้

OkHttp: HttpClient ของ Android บนเตียรอยด์

นี่คือวิธีเขียน HttpClient ของ Android ง่ายมากฉลาดมาก ไลบรารี OkHttp ภายในดูแลลูปการลองใหม่ การบีบอัด payload อัตโนมัติ การสนับสนุน Http/2 การรวมการเชื่อมต่อ และการแคชการตอบสนอง คุณจึงหลีกเลี่ยงการเข้าถึงเครือข่ายที่ไม่จำเป็นได้

แอนิเมชั่นห้องสมุด OkHttp

การใช้ OkHttp เป็นเรื่องง่าย

Http โพสต์:

 OkHttpClient client = new OkHttpClient(); MediaType JSON = MediaType.parse("application/json; charset=utf-8"); RequestBody body = RequestBody.create(JSON, json_str); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); return response.body().string();

Http รับ:

 OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(urls[0]) .build(); Response responses = client.newCall(request).execute(); String jsonData = responses.body().string();

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

ฉันชอบความแข็งแกร่งของมัน—มันเพิ่มไปยังเลเยอร์เครือข่ายของคุณทันที

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

Picasso: มีเหตุผลที่ดีที่ Google ก็ใช้มันเช่นกัน!

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

คำสั่งนี้:

 Picasso.with(context).load(url).resize(50,50).centerCrop().into(imageView)

จะทำสิ่งนี้ให้คุณ:

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

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

แอนิเมชั่นไลบรารี่ของ Picasso Android

บนอุปกรณ์ Android โดยเฉลี่ย แอปจะได้รับ RAM ไม่เกิน 50 ถึง 60 เมกะไบต์ และปัจจัยพิกเซลต่อไบต์สำหรับอุปกรณ์ Android ส่วนใหญ่คือ 4 ซึ่งหมายความว่าพยายามโหลดภาพขนาด 13 เมกะพิกเซลจากการ์ด SD ต้องการ RAM 52 เมกะไบต์ กล่าวคือ แอปของคุณจะหยุดทำงานทันที

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

หนึ่งในข้อพิสูจน์ที่แข็งแกร่งที่สุดเกี่ยวกับพลังของห้องสมุดนี้: ตัวอย่างโค้ด Android จำนวนมากของ Google ในช่วงสองปีที่ผ่านมาใช้ Picasso ในการโหลดรูปภาพ

ActiveAndroid: โอเวอร์เฮดประสิทธิภาพ ORM Sans

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

ใช้งานAndroid ORM

มันมีประโยชน์หรือไม่? อย่างมาก เนื่องจากช่วยให้คุณสามารถเขียนแอปส่วนใหญ่ได้โดยไม่ต้องเข้ารหัสคำสั่ง SQL

มันยังมีประสิทธิภาพมาก ในสมัยก่อน แพลตฟอร์ม ORM อาศัยการไตร่ตรองอย่างหนาแน่นและขึ้นชื่อว่าทำงานช้า แพลตฟอร์มสมัยใหม่ ซึ่งรวมถึง ActiveAndroid นั้นเร็วกว่ามากและสำหรับความต้องการในทางปฏิบัติส่วนใหญ่ จะไม่ได้รับผลกระทบจากโอเวอร์เฮดของประสิทธิภาพเหนือการเข้ารหัส SQL แบบดิบ

ไม่มีคำสั่ง SQL ที่เขียนด้วยมือ ไม่มีค่าใช้จ่ายด้านประสิทธิภาพ!

การใช้งาน:

ก. เริ่มต้นในวัตถุแอปพลิเคชันโดยขยายคลาสแอปพลิเคชันที่กำหนดเอง:

 public class MyApplication extends extends com.activeandroid.app.Application { … }

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

 @Table(name = "Categories") public class UserDetails extends Model { @Column(name = "Name") public String name; @Column(name = "Address") public String address; @Column(name = "Age") public int age; }

หากคุณต้องการตั้งค่าดัชนีสำหรับสมาชิก ให้ใช้คำอธิบายประกอบต่อไปนี้:

 @Column(name = "ID", index = true) public String userID;

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

 <meta-data android:name="AA_MODELS" android:value=“com.myapp.MyModelA, com.myapp.MyModelB" />

หมายเหตุ: ActiveAndroid ไม่รู้จักคลาสโมเดลที่ไม่ปรากฏในรายการนี้

ง. เขียนไปยังฐานข้อมูล:

 UserDetails usr = new UserDetails(); usr.save(); // RUNS ON A BACKGROUND THREAD

หากจำเป็นต้องเขียนหลายรายการ วิธีที่มีประสิทธิภาพมากขึ้นคือการจัดชุดงานในธุรกรรมเดียว:

 ActiveAndroid.beginTransaction(); try { for (UserDetails u: userList) item.save(); ActiveAndroid.setTransactionSuccessful(); } finally { ActiveAndroid.endTransaction(); }

อี อ่าน POJO จากฐานข้อมูล:

 new Select() .from(UserDetails.class) .where("name = ?", usr.getName()) .orderBy("Age") .executeSingle();

ORM เป็นเครื่องมือที่ต้องมีในสมัยของฉันในฐานะนักพัฒนาฝั่งเซิร์ฟเวอร์ มีการเข้าสู่โดเมน Android ค่อนข้างช้า แต่สุดท้ายนี้ก็คือ การเขียนโปรแกรมฐานข้อมูลแบบง่ายๆ สนุกกับมัน.

LibStreaming: การสตรีมวิดีโอที่ไม่เจ็บปวด

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

ภาพเคลื่อนไหวไลบรารี libStreaming

โชคดีที่ libStreaming ได้เปลี่ยนแปลงทั้งหมดนี้โดยการห่อหุ้มความซับซ้อนของการสตรีมส่วนใหญ่ และเปิดเผย API ที่เรียบง่ายและเป็นมิตร ซึ่งช่วยให้คุณเขียนแอปสตรีมมิ่งพื้นฐานได้ภายในเวลาไม่กี่ชั่วโมง

โดยสรุป มันทำให้การสตรีมวิดีโอคล่องตัว

ในการใช้งานกับ H.264 และ AAC คุณต้องทำสิ่งต่อไปนี้:

ก. เริ่มต้นวัตถุเซสชันที่วิธีการ onCreate ของกิจกรรมหลักของคุณ ออบเจ็กต์เซสชันแสดงถึงการสตรีมสื่อไปยังเพียร์:

 protected void onCreate(Bundle savedInstanceState) { mSession = SessionBuilder.getInstance() .setCallback(this) .setSurfaceView(mSurfaceView) .setPreviewOrientation(90) .setContext(getApplicationContext()) .setAudioEncoder(SessionBuilder.AUDIO_NONE) .setAudioQuality(new AudioQuality(16000, 32000)) .setVideoEncoder(SessionBuilder.VIDEO_H264) .setVideoQuality(new VideoQuality(320,240,20,500000)) .build(); mSurfaceView.getHolder().addCallback(this); }

ข. เริ่มเซสชันจริง:

 mSession.setDestination(destination_server_url); mSession.start();

ค. หยุดเซสชันเมื่อเสร็จสิ้น:

 mSession.stop();

ตอนนี้โปรดอย่าเข้าใจผิด การสตรีมแบบเรียลไทม์นั้นยุ่งเหยิงโดยธรรมชาติ และ libStreaming ก็ไม่ได้ขจัดความซับซ้อนนี้ออกไป อย่างไรก็ตาม การซ่อนมันจากคุณเกือบตลอดเวลานั้นทำได้ดีมาก ในบางกรณี คุณจะต้องจัดการกับความซับซ้อน เช่น เมื่อเลือกนโยบายการส่งสัญญาณจากเพื่อน เลือกการเข้ารหัสกล้อง (โดยปกติคุณต้องการใช้ MediaCodec/surface-to-buffer) หรือการจัดการกับแพ็กเก็ต

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

LibStreaming รองรับตัวเข้ารหัสส่วนใหญ่ที่ใช้โดยแอพ Android รวมถึง H.264, H.263, AAC และ AMR

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

LeakCanary: ตรวจจับการรั่วไหลของหน่วยความจำในบรรทัดของรหัส

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

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

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

แน่นอนว่าการรั่วไหลไม่ได้เกิดขึ้นเฉพาะกับ Android แต่เนื่องจากระบบมือถือที่มีทรัพยากรหน่วยความจำจำกัด ผลกระทบจึงเกิดขึ้นทันที

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

ห้องสมุด LeakCanary

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

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

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

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

ในการใช้งานเพียงแค่เริ่มต้น leakCanary ด้วยออบเจ็กต์ของแอปของคุณ onCreate() :

 public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); // more initialisations } }

และคุณทำเสร็จแล้ว LeakCanary จะตรวจสอบการรั่วไหลของหน่วยความจำ และส่งการแจ้งเตือนหากตรวจพบ

LeakCanary บรรลุเวทย์มนตร์นี้โดยการฉีดวัตถุที่เรียกว่า ActivityRefWatcher ลงในกิจกรรมทั้งหมดของคุณโดยอัตโนมัติและติดตามจำนวนผู้อ้างอิงหลังจาก onDestroy() การนับผู้อ้างอิง > 0 ในกิจกรรมที่ถูกทำลายอาจหมายถึงการรั่วไหลเท่านั้น

สำคัญ: การตรวจจับการรั่วใช้ได้กับแอปพลิเคชันโหมดแก้ไขข้อบกพร่องเท่านั้น อย่าทดสอบการรั่วไหล (ไม่ใช่กับ LeakCanary) ใน APK ของโหมดเผยแพร่

แต่ถ้าฉันต้องการทดสอบส่วนอื่นๆ ของระบบเพื่อหารอยรั่วล่ะ ที่นี่ LeakCanary เสนอวัตถุที่เรียกว่า refWatcher ซึ่งอันที่จริงแล้วเป็นค่าส่งคืนของการเรียกการเริ่มต้น:

 refWatcher = LeakCanary.install(this);

สามารถใช้เพื่อดูค่าที่จะถูกเรียกคืนในไม่ช้า แม่นยำยิ่งขึ้น ค่าที่ฉันคิดว่าเร็ว ๆ นี้จะถูกเรียกคืน โทร:

 refWatcher.watch(my_soon_to_be_reclaimed_obj);

ห้องสมุดจะแจ้งให้คุณทราบหากวัตถุนี้ยังไม่ถูกปล่อยออกมาภายในระยะเวลาสั้นๆ หลังจากการเรียกนาฬิกา

ฉันไม่สามารถหาค่าของ "เวลาอันสั้น" นี้ได้ที่ไหน แต่มันคงไม่สำคัญขนาดนั้น ด้วยการรั่วไหล Canary สิ่งต่าง ๆ ก็ใช้ได้ ไม่มีค่า

สรุป

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

โดยสรุป นี่คือสิ่งที่ห้องสมุด Android ที่ฉันเลือกไว้สามารถช่วยคุณได้:

  • ButterKnife – โค้ดที่ฉีดอัตโนมัติจะช่วยคุณกำจัดโค้ดต้นแบบของแอปส่วนใหญ่ เป็นการแทรกโค้ดขั้นสุดยอดสำหรับ Android ฉันจำเป็นต้องพูดมากกว่านี้ไหม

  • AndroidAnnotations – ใช้คลาสที่สร้างอัตโนมัติอย่างรวดเร็วและการฉีดโค้ดตามชื่อเพื่อประหยัดเวลาโดยไม่มีการปรับประสิทธิภาพเหนือตรรกะที่เข้ารหัสด้วยมือ

  • EventBus – แยกส่วนประกอบสำหรับรหัสที่แข็งแกร่งยิ่งขึ้น การสื่อสารข้ามองค์ประกอบไม่เคยง่ายไปกว่านี้มาก่อน

  • OkHttp – การแทนที่อย่างชาญฉลาดสำหรับ HttpURLConnection ด้วยการสนับสนุนเครือข่ายแบบอะซิงโครนัส ขอการสืบค้นเส้นทางการเปลี่ยนเส้นทาง การสืบค้นแคชในเครื่อง และอื่นๆ

  • Picasso – การจัดการรูปภาพที่คล่องตัวซึ่งดีมากจน Google ใช้แล้ว เป็นการประหยัดเวลาที่สำคัญในโครงการหนักด้านสื่อและโครงการเดิมบางโครงการ

  • ActiveAndroid – ORM ทำได้ง่ายโดยไม่มีค่าใช้จ่ายด้านประสิทธิภาพ

  • LibStreaming – การสตรีมวิดีโอแบบเรียลไทม์ ใช้โดยแอพสตรีมมิ่งหลักๆ

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

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

ที่เกี่ยวข้อง: Android 7.0 สำหรับนักพัฒนา: คุณสมบัติใหม่ การอัปเกรดประสิทธิภาพ & สิ่งอื่น ๆ ที่คุณไม่สนใจ