Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Android

คู่มือ Android Storage: 演進, ประเภท, และ Best Practices

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

จุดสำคัญกว่านั้นคือ ดู evolution ของสิ่งที่จัดเก็บในหน่วยความจำ ก่อนสมาร์ทโฟน เราบันทึกรูปภาพไม่กี่รูป เกมบ้าง และข้อความเยอะมาก แต่วันนี้ โทรศัพท์มาตรฐานจะมีผสมผสานของ applications, documents, photos, videos, music files และอื่นๆ มาดูว่าเราสามารถใช้ storage ของอุปกรณ์สำหรับแอปพลิเคชันได้อย่างไร

สิ่งที่จะครอบคลุมในบทความนี้:

  1. ประเภท storage ต่างๆ บนโทรศัพท์ Android
  2. ความแตกต่างระหว่างประเภท storage
  3. วิธีใช้ storage ในแอปพลิเคชันของคุณ

แต่ละแอปพลิเคชันเข้าถึง storage 2 ประเภท: internal และ external มีความแตกต่างใหญ่ระหว่างสองประเภท การรู้จักจะช่วยเวลาออกแบบแอปถัดไป

ก่อนเริ่ม ต้องพูดถึง storage และ cache Storage ใช้สำหรับสิ่งที่ต้องการบันทึกอย่างถาวร (persistently) ในขณะที่ cache ใช้บันทึกชั่วคราว (temporarily)

คู่มือ Android Storage: 演進, ประเภท, และ Best Practices
Photo by Erda Estremera / Unsplash

Internal Storage

เมื่อแต่ละแอปพลิเคชันรันบน OS มันมี internal storage ของตัวเอง Storage นี้เป็น private และใช้ได้เฉพาะแอปนั้นเท่านั้น หมายความว่า แอปอื่นเข้าถึงไม่ได้ ผู้ใช้ก็เข้าถึงไม่ได้ อีกอย่าง Internal storage available เสมอสำหรับแอปของคุณ ไม่เหมือน external storage

การใช้ storage นี้มีข้อเสีย ถ้าผู้ใช้ uninstall แอป ข้อมูลทั้งหมดใน internal storage ของแอปจะหายไปด้วย 想像ถ้าคุณติดตั้งเกมบนโทรศัพท์ และภายหลังตัดสินใจลบ คุณอยากให้ความก้าวหน้าเกม saved ไว้ หากติดตั้งเกมอีกครั้ง

เราบันทึกไฟล์ไป internal storage ยังไง?

public void saveFileInternalStorage() { String FILENAME = "hello_world_file"; String inputToFile = "Hello From Internal Storage!"; try { FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE); fileOutputStream.write(inputToFile.getBytes()); fileOutputStream.close(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has been saved successfully", Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } }
บันทึกไฟล์ชื่อ hello_world_file

เห็นในตัวอย่างโค้ด เราบันทึกไฟล์ hello_world_file ที่มีข้อความ “Hello From Internal Storage!” สร้าง 2 catch clauses เพื่อ demonstrate exceptions ที่อาจเกิดขึ้น แต่ลดเหลือ 1 catch clause กับ Exception object ทั่วไปได้

สังเกต method openFileOutput จะเปิดไฟล์ถ้ามีอยู่แล้ว แต่ถ้าไม่มี จะสร้างใหม่ พารามิเตอร์ที่สองคือ file mode ระบุ scope ของไฟล์และการเข้าถึง ค่า default คือ MODE_PRIVATE ทำให้ไฟล์เข้าถึงได้เฉพาะแอปของคุณ

ค่าอื่นอีก 2 ค่า คือ MODE_WORLD_READABLE และ MODE_WORLD_WRITEABLE แต่ deprecated ตั้งแต่ API 17 การแชร์ไฟล์ private กับแอปอื่นใช้ logic ชุดอื่น อ่านเพิ่มได้ที่นี่ ตอนเขียนไฟล์ เราแปลง string เป็น bytes และปิดไฟล์ท้ายสุด

คู่มือ Android Storage: 演進, ประเภท, และ Best Practices
Photo by Markus Spiske / Unsplash

External Storage

ขัดกับชื่อที่บ่งชี้ นี่คือ storage ที่กำหนดโดยว่าไม่ได้ accessible เสมอไป อาจหมายถึง external SD card (secondary external storage) หรือ storage บนอุปกรณ์ (primary external storage)

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

ก่อน demo การบันทึกไฟล์ไป external storage ต้องทำ 2 อย่าง:

  1. ตรวจสอบว่ามีพื้นที่พอสำหรับบันทึกไฟล์
  2. ขอ permission ระหว่าง runtime

ตรวจสอบพื้นที่ว่างต้องใช้โค้ด:

//Check if you can read/write to external storage public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; }
ตรวจสอบว่าเขียน/อ่าน external storage ได้ไหม

เพื่อเข้าถึง external storage ต้องเพิ่ม permission ใน AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Write external storage permission

เพิ่มเติม ตั้งแต่ API 23 dangerous permissions ไม่ได้ authorize ตอน install แต่ตอน runtime การเขียน external storage อยู่ในกลุ่มนี้ ต้องเพิ่ม logic ให้ผู้ใช้ตัดสินใจ grant permission หรือไม่

public void saveFileExternalStorage(View view) { if (isExternalStorageWritable()) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { writeFileToExternalStorage(); } else{ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case 0: { writeFileToExternalStorage(); break; } } }
ตรวจสอบว่าผู้ใช้ grant permission แล้วหรือยัง

writeFileToExternalStorage จะเป็นแบบนี้:

public void writeFileToExternalStorage() { String root = Environment.getExternalStorageDirectory().toString(); File myDir = new File(root + "/saved_files"); if (!myDir.exists()) { myDir.mkdirs(); } try { File file = new File(myDir, "myfile.txt"); FileOutputStream out = new FileOutputStream(file); out.write(inputToFile.getBytes()); out.close(); Toast.makeText(getApplicationContext(), "File myfile.txt" + " has been saved successfully to external storage", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } }
เขียนไฟล์ไป external storage

อยากดูตัวอย่างโค้ดทั้งหมด ไปที่ GitHub repository นี้

คู่มือ Android Storage: 演進, ประเภท, และ Best Practices
Photo by Steve Johnson / Unsplash

Good To Know

ข้างต้นเป็นแค่ 2 ตัวอย่างง่ายๆ การทำงานกับ storage ประเภทต่างๆ เนื่องจากจัดการ resource ที่ system manages เราควรรู้พฤติกรรมที่เกี่ยวข้อง

โดย default แอปจะติดตั้งไป internal storage (see internalOnly explanation) แต่ตั้งแต่ API level 8 สามารถเพิ่ม attribute installLocation ใน manifest ให้แอปติดตั้งไป external storage ได้ เหตุผลหนึ่งคือถ้าแอปใหญ่มาก และอยากให้ user ติดตั้งบน external storage เพราะมีพื้นที่มากกว่า

มี 3 ค่าสำหรับ attribute นี้:

  • auto - ไม่มี preference ตรงไหน แอพพยายามติดตั้ง internal storage แต่ถ้าเต็ม จะติดตั้ง external storage
  • internalOnly - ติดตั้ง internal storage เท่านั้น ถ้าไม่พอ จะไม่ติดตั้ง
  • preferExternal - อยากติดตั้ง external storage แต่ถ้าไม่พอ จะติดตั้ง internal แทน

ทั้ง auto และ preferExternal ผู้ใช้สามารถย้ายแอปจาก external ไป internal และ vice versa ได้

จำไว้ว่า เมื่อ userต่ออุปกรณ์กับคอมพิวเตอร์และ enable sharing หรือ unmount SD card แอปทั้งหมดที่รันจาก external storage จะถูก destroy หากแอปใช้ features ต่อไปนี้ ไม่ควรติดตั้ง external storage:

Various services (alarm servicess in particular), Input Method Engines, Live Wallpapers, Application Widgets, Account Managers, Sync Adapters, Device Administrators และ Broadcast receivers listening for boot completed.