วันเสาร์ที่ 19 กรกฎาคม พ.ศ. 2557

แนะนำ Library โหลดภาพดีๆ "Picasso"

เชื่อว่า Developer หลายๆคนที่ได้ทำงานเกี่ยวกับการแสดงรูปภาพบนแอพคงได้เคยเจอปัญหาเจ้า  OutofMemoryError: bitmap size exceeds VM budget . กันอย่างแน่ๆ   ผู้เขียนเองก็เจออย่างบ่อย เกิดจากการที่เราเรียกใช้งานรูปภาพที่เป็น Bitmap เยอะๆ แล้วทำให้ VM Size ที่ตัว OS ของ device จ่ายมาให้เรามันไม่พอ อาจจะเป็นเพราะรูปภาพที่เราใช้ในแอพเรามันมีจำนวนเยอะเกินไป หรือไม่ก็มีขนาดใหญ่มากเกินไป  ซึ่ง Google ก็มีการเพิ่มตัว Attribute มาให้เราใน  Android 3.0  ซึ่งก็คือการประกาศ  android:largeHeap=true   เพื่อเป็นการเพิ่มขนาดของ VM Heap size ให้มีขนาดใหญ่ขึ้น  แต่นั่นก็ไม่ใช่วิธีการแก้ปัญหาที่ถูกต้อง   โดยวิธีการตามตัวอย่างที่ Google แนะนำนั้นคือการให้เราใช้งานเจ้าตัว Lrucache กบัการทำ Sample Size ของรูปภาพที่นำมาแสดงให้มีขนาดเล็กลง ควบคู่กันไป 


หลายๆคนในที่นี่เข้าใจว่าบางคนก็อาจจะเขียนเองโดยอิงตัวอย่างจากทาง Google หรือใช้  Libraries อื่นๆ เช่น UniversalImageLoader , LazyList ฯลฯ อันนี้ก็แล้วแต่ความถนัด แต่ที่ตัว Picasso ผู้เขียนจะมาแนะนำนั้นตัวผู้เขียนชอบมากสาเหตุเนื่องจากว่า

  1. ใช้งานนั้นง่าย เขียนโค๊ตแค่ 1 Line ก็เสร็จ 
  2. สามารถทำการแสดงรูปภาพได้ทั้งที่เป็นรูปจาก URL, Drawable หรือจาก File 


ตัวอย่างการใช้งานเจ้า Picasso ทำการแสดงรูปที่เป็น URL:
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
ทำการ Resize และทำ ScaleType ได้ด้วย

Picasso.with(context)
  .load(url)
  .resize(50, 50)
  .centerCrop()
  .into(imageView)
ทำการใส่รูปภาพที่เป็น pre-load ก่อนแล้วค่อยโหลดภาพที่จะแสดงมา รวมถึง แสดงรูปภาพ error หากไม่สามารถโหลดรูปภาพได้

Picasso.with(context)
    .load(url)
    .placeholder(R.drawable.user_placeholder)
    .error(R.drawable.user_placeholder_error)
    .into(imageView);


ส่วนตัวผู้เขียนว่า เจ้า Lib ตัวนี้จัดว่าเป็น Lib ที่สะดวกและง่ายต่อการใช้งานจริงๆ เหมาะสำหรับคนที่ไม่คิดอะไรมากเรื่อง Performance ประกาศแค่ Line เดียวปุ๊ปเสร็จปั๊ป ไม่ต้องยุ่งกับการ cache อะไรทั้งสิ้น นับว่าสะดวกมากๆเลยทีเดียว

ใครไม่เคยลองเจ้า Lib ตัวนี้หากสนใจก็ไปโหลดมาเล่นกันได้เลยจ้า มีทั้ง source code ทั้ง .jar ทั้ง Maven dependency ^__^




วันเสาร์ที่ 12 กรกฎาคม พ.ศ. 2557

การใช้งาน Proguard กับ Android

บทความครั้งที่แล้ว เราได้พูดถึงการใช้งานเจ้าเครื่องมืออย่าง Dex2Jar และ JD-GUI ไปแล้วนะครับ วันนี้เราจะมาพูดถึงวิธีป้องกันไม่ให้คนเอาแอพเราไปเปิดดูแล้วได้โค๊ตไปได้  วิธีการนั้นก็คือการใช้เจ้า Proguard เนี่ยแหละครับ
ในส่วนนี้ผู้เขียนขออธิบายวิธีการใช้งานมันกับเจ้า Eclipse นะครับ ยังไม่เคยได้ลอง Android Studio สักที ว่าจะลองๆ แล้วก็ไม่ได้ลอง

โดยปกติแล้วถ้าเรา New project ใหม่ขึ้นมา เราจะสังเกตเห็นว่า มันมักจะมีไฟล์ตัวนึงโผล่ขึ้นมาด้วย เจ้านั่นก็คือ proguard-project.txt นั่นเองครับ
ผู้เขียนขอทำการ rename ไฟล์มันให้เป็น *.cfg หน่อยนะครับ จะได้รู้ว่ามันเปนไฟล์ Configure
จากนั้นทำการเปิดไฟล์ project.proporties ขึ้นมาแล้วทำการ uncomment บรรทัดนี้ออก


ใครหาบรรทัดนั้นไม่เจอก็ copy ไปนะครับ

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.cfg


จากนั้นผู้เขียนขอทำการ copy ค่า Default ของ Configure ของเจ้า proguard มาแปะเลยละกัน

หน้าตาเป็นแบบนี้

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.billing.IInAppBillingService
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.content.Context {
    public void *(android.view.View);
    public void *(android.view.MenuItem);
}

ทำไปแปะใน file proguard.cfg เราซะ 
จากนั้นก็ทำการ build เลย!!

เมื่อได้ apk แล้ว ตัวนี้หละครับมันถูก Obfuscated มาเรียบร้อยละ ถ้าอยากจะรู้ว่าหน้าตามันเป็นยังไงก็ลองใช้ dex2Jar ดูนะครับ  หน้าตามันออกมาก็ประมาณนี้


สังเกตว่าคลาส MainActivity ชื่อยังเหมือนเดิม แต่ข้างในโค๊ตมันมีตัวแปล a ไรก็ไม่รู้ แถมมี class นึงชื่อ a โผล่มาอีกต่างหาก ใช่แล้วครับ เจ้า proguard มันเปลี่ยนชื่อไปให้เรา
จริงๆแล้วผู้เขียนได้ทำการใส่ class ที่เป็น Utility เข้าไปอีกกระปินึง แต่มันเห็นว่าเราไม่ใช้มันเลยดันลบทิ้งหมดเลย
อ้าา ใช่แล้วครับ ข้อนี่เป็นข้อระวังเลยล่ะในการใช้งานเจ้านี่ เพราะบางครั้งมันก็ดันไปลบในสิ่งที่เราไม่ได้อยากให้ลบด้วย เพราะฉะนั้น เราอยากจะให้อะไรอยู่เราก็ต้อง "keep" มันเอไว้นะครับ อยากรู้ว่า command ในการ keep ไว้ทำไง เลื่อนไปดูด้านบนได้เลยครับ ^__^  ข้อนี่เป็นสิ่งที่ต้องระวังนะครับขอย้ำ โดยเฉพาะในการใช้ Library ต่างๆ เราก็ต้องดูด้วยว่ามันกระทบหรือเปล่า พูดง่ายๆคือต้อง test ทุกครั้งหลังจากกการใช้มันน่ะครับ

ข้อดีของมันอีกอย่างคือเมื่อมันลบ class เราทิ้งไปหลายๆ classes มันทำให้ ขนาดของ *.dex ลดลง หรือ ขนาดของเจ้าไฟล์ *.apk นี่เองที่ลดลง

สิ่งสุดท้ายที่ขาดไม่ได้เลยคือ เรารู้ครับว่าคลาสที่โดนเปลี่ยนชื่อไปก่อนหน้านั้นมันชื่อว่าอะไร วิธีการไม่ยากครับ หลังจากเรา build ด้วย proguard เสร็จ มันจะปรากฏมี Folder นึง โผล่ขึ้นมาในโปรเจกเรา point ที่สำคัญก็คือ เค้าตัวไฟล์ที่ชื่อว่า mapping.txt เนี่ยแหละครับ จะเป็นตัวบอกว่า class ไหนถูกเปลี่ยนชื่อเป็นอะไร


หน้าตาของเจ้า mapping file


เป็นไงครับ ทีนี้ก็ใช้กันเปนแล้วสินะครับ ยังไงก็อย่าลืม test กันก่อนด้วยล่ะว่าโปรแกรมเรายังทำงานถูกต้องมั๊ยย อย่าลืมนะครับ!

วันพฤหัสบดีที่ 10 กรกฎาคม พ.ศ. 2557

การใช้งาน Dex2Jar และ JD-GUI กับ Android

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

* หมายเหตุ บทความนี้เป็นเพียงบทความเพื่อแจ้งในนักพัฒนาทราบว่าเราสามารถทำการ De-compile หรือดู source code ได้จากเครื่องมือเหล่านี้ ซึ่งเป็นวิธีการแพร่หลายอยู่แล้ว ผู้เขียนเพียงเพื่อจะแนะนำวิธีการแหละการป้องกัน (ซึ่งจะกล่าวใน Blog ถัดไป) ไม่ได้มีเจตนาในการสอนหรือทำการเผยแพร่วิธีการ Hack ใดๆทั้งสิ้น

ผู้เขียนขอแยกประเป็น เนื้อหา Blog นี้เป็น2 ประเด็นละกัน คือเรื่อง Dex2Jar และ JD-GUI

Dex2Jar คืออะไร
เชื่อว่าหลายคนที่หลงเข้ามาอ่านน่าจะต้องเกิดคำถาม ตอบตรงๆผู้เขียนก็ไม่รู้เหมือนกัน (วะฮะฮ่า) แต่ถ้าแปลเฉพาะในส่วนของความสามารถมันแล้วล่ะก็ เจ้า Tools ตัวนี้สามารถ convert ไฟล์ *.dex เป็น *.jar ได้แล้วถามว่ามันมีประโยชน์ยังไง ล่ะ เอ๋?   เรื่องของเรื่องก็คือ โดยปกติแล้วหลังจากที่ Android Developer อย่างเราๆ ทำการ build apk ออกมาแล้วเตรียมตัว Deploy ขึ้น Play Store หรืออะไรก็แล้วแต่ จริงๆแล้วเราสามารถที่จะ rename เจ้าตัว apk นี้เป็น zip ได้ เช่น   Facebook.apk &gt;&gt;  Facebook.zip แทน แล้วจากนั้นถ้าเราโปรแกรมจำพวก winrar เป็นดู หน้าตามันจะออกมาประมาณนี้



จะสังเกตว่าหน้าตา structure มันค่อนข้างคล้ายกันกับ project ของเรา ถ้าเราลองกดเข้าไปใน res เราก็จะเจอ folder drawable เหมือนปกติ รูปภาพในนั้นสามารถเปิดขึ้นมาดูได้  resource อื่นๆที่เป็น .xml ก็เปิดมาดูได้ แต่จะอ่านไม่รู้เรื่อง ส่วนถ้าใครถามว่าแล้วตัว Source code เราล่ะอยู่ไหน ... ครับมันก็คือไฟล์ classes.dex นั่นเอง :D  ลองย้อนกลับไปดูรูปแรก ทีนี้ถ้าเราอยากจะเห็น Source code พวกนี้ทำไง ก็เจ้า Tools ตัวนี้แหละครับที่ช่วยเราได้ วิธีการก็คือ


หลังจากโหลด zip มาแล้วก็แตก zip เลย ผู้เขียนขอแตก zip ไปไว้ที่ Drive C ละกัน

จากนั้นนำไฟล์ apk ไปวางไว้ข้างใน Folder ของ dex2jar เลยเพื่อความง่ายต่อการ Run command
จากนั้นเปิดหน้าต่าง command ขึ้นมา แล้วใช้คำสั่ง
 d2j-dex2jar.sh myapp.apk
เท่านี้ก็เปนอันเสร็จเรียบร้อย

จากนั้นเราก็สามารถเปิดไฟล์ .jar เหล่านี้มาดูได้ด้วยโปรแกรม winrar เจ้าเก่าเนี่ยแหละ ภายในเราก็จะเห็น ไฟล์ *.class เต็มไปหมด โดย Structure ก็จะเหมือนกับ Project เราแทบทุกอย่าง

อ้าา หลายคนสงสัยว่าได้ class มาแล้วยังไง ก็เปิดดูไม่ได้ หรือได้แล้วก็อ่านไม่รู้เรื่องอยู่ดี


ใช่แล้วครับเราถึงต้องมีเจ้า Tools ตัวนี้ที่ชื่อว่า JD-GUI เนี่ยแหละ เวลาไว้ดู code ที่อยู่ใน *.class วิธีการนั้นแสนง่ายมากโดย
เริ่มจาก Download มาก่อนเลย

แตก zip แล้วทำการเปิดไฟล์ท่ชื่อ jd-gui ขึ้นมา
จากนั้นทำการเลือกไฟล์ *.jar ที่เราต้องการจะเปิด


แต่นแต๊นนน

เห็นหมดเลย

Source ข้างในหลังจากที่ผู้เขียนได้ลองตรวจสอบแล้ว บางครั้งมันก็ไม่ได้ถูกต้อง 100% นะครับ มี compile Error หลายที่    หลายคนอาจจะสงสัยว่าอ่าวแล้วแบบนี้เราจะป้องกันการแอบเอา apk ไฟล์เราไปดู source code ยังไง   :3  มีวิธีครับ หนึ่งในนั้นก็คือการทำ Obfuscation Code ข้างในมันด้วย proguard ทำให้ต่อให้ Hacker ได้โค๊ตไปก็อ่านไม่รู้เรื่องอยู่ดี โดยเรื่องนี้ผู้เขียนจะขออธิบายไปใน Blog ถัดไปนะครับ   เอาเป็นว่า อยากแอบดู source code ใครก็ลองทำดูเอ้ย ไม่ใช่ &gt;///&lt; ประโยชน์ที่ผู้เขียนได้รับจากการทำคือ บางครั้งเราจำเป็นต้อง Hack Library บ้างเพื่อให้มันทำงานสอดคล้องกับที่เราต้องการ เข้าไปดูว่าเขาเขียนยังไงตรงไหนแล้วทำไมมันมี impact กับ Logic เรา ก็ไปทำการ Over write class นั้นๆซะ ประมาณนี้แหละครับ 
ครั้งหน้าผมจะมาอธิบายการใช้ Proguard เพื่อป้องกันการถูก Hack โค๊ตเรานะครับบ ^__^