1- برای رفع خطای OutOfMemory هنگام کار با تصاویر راه های زیر رو دنبال کنید:
- مقدار خاصیت largeHeap
در فایل مانیفست رو true
قرار بدید.
- سعی کنید از LRU cache manager استفاده کنید.
- تصاویر رو compress کنید.
- کدهارو بررسی کنید که memory leak رخ نداده باشه. (که 90% بخاطر بی توجهی به activity life cycle رخ میده)
- برای سرویس ها و Toast ها از ApplicationContext استفاده کنید.
- دقت کنید که broadcast receiver ها رو Unreg
کنید.
- همه Observer ها رو بعد از استفاده delete کنید.
- همه resource ها رو(مثل XML) بعد از استفاده destroy کنید.
مقاله کامل و قابل فهم از حافظه Stack و حافظه Heap.
2- مقدار صفت android:targetSdkVersion
در تگ uses-sdk
فایل AndroidManifest.xml، به دستگاه با نسخه مشابه SDK فرمان میده که سیستم compability رو غیرفعال کنه. بنابراین سرعت پردازش برنامه افزایش و کارایی برنامه بهبود پیدا می کنه.
3- یادتون باشه که synchronized
و Thread-Safe در جاوا یک مفهوم دارن: دسترسی همزمان به کد توسط چند Thread بدون بروز مشکلات. یعنی کد/متد synchronized
اجازه دسترسی همزمان چند Thread به کد/متد رو نمیده، پس Thread ها باید نوبتی به کد/متد دسترسی پیدا کنن بنابراین آخرین وضعیت کد/متد در همه Thread ها مشترک هستش.
نکته: این مسئله فقط در مورد برنامه های Multi-Thread صدق میکنه و نه Single-Thread.
4- برای حل مشکل minSdk(API x) != deviceSdk(API y) در Android Studio یکی از راه های زیر رو دنبال کنید:
راه اول: داخل گوشی/emulator به مسیر Settings -> منوی Developer options برید و گزینه USB debugging رو فعال کنید.
راه دوم: زمانی که گوشی/emulator رو وصل می کنید، داخل گوشی پنجره Allow USB Debugging باز میشه که حاوی fingerprint هم هست... اون رو ALLOW کنید.
راه سوم: مطمعن شید که حافظه گوشی/emulator پر نشده باشه... اگر شده خالیش کنید.
راه چهارم: داخل گوشی/emulator به مسیر Settings -> منوی Storage برید و از بالا options رو باز کنید، سپس گزینه USB computer connection رو بزنید و نهایتا Media device MTP رو فعال کنید. (اگر درست نشد، Camera device رو فعال کنید)
راه پنجم: نسخه targetSdkVersion و compileSdkVersion رو یکی کنید.
راه ششم: فایل build.gradle رو باز کنید و مقدار عددی minSdkVersion رو به مقدار عددی deviceSdk تغییر بدید.
راه هفتم: داخل Android Studio به منوی Tools -> گزینه Android برید و ADB Integration رو فعال کنید.
راه هشتم: داخل Android Studio به قسمت Build Tools Version برید و نسخه رو به مقدار عددی minSdk یا deviceSdk تغییر بدید.
راه نهم: کلاً از device های سری Preview, N, L استفاده نکنید.
5- کدام کتابخانه Networking؟
OkHTTP, Retrofit, Volley
کتابخانه OkHTTP: توسط Square تولید شده. مناسب برای Streaming و استفاده General مبتنی بر HTTP. پشتیبانی از POST, GET, UPLOAD. دارای مستندات آموزشی. زیربنای پیشفرض Retrofit و Picasso. یکی از زیربناهای Volley هستش. دارای disk cache. پشتیبانی از conn pooling. از پروتکل SPDY پشتیبانی می کنه. از اندروید 4.4 به بعد بصورت builtin در زیربنای اندروید استفاده شده. پشتیبانی از NewIO و...
کتابخانه Retrofit: توسط Square تولید شده. مناسب برای RESTful API / Web Service. پشتیبانی از POST, GET, PUT, DELETE, Multipart. دارای مستندات آموزشی. مبتنی بر کلاینت OkHTTP. دارای disk cache. پشتیبانی از async با کمترین کد. دارای cancellation و retry برای درخواست ها. پشتیبانی از Dynamic URL. کمی کندتر از Volley اما سریعتر از AsyncTask هستش. دارای مفسر پیشفرض JSON و تبدیلش به POJO بکمک GSON. پشتیبانی از NewIO. پشتیبانی از فعالیت های background.
کتابخانه Volley: توسط Google پشتیبانی شده. مناسب برای استفاده General و کار با تصاویر. پشتیبانی از POST, GET, PUT, DELETE. دارای مستندات آموزشی. دارای کلاینت های OkHTTP, Apache, HttpUrlConnection. دارای memory cache. پشتیبانی از conn pooling. پشتیبانی از async با کمترین کد. دارای prioritization, cancellation, retrying برای درخواست ها. پشتیبانی از Dynamic URL. کمی سریعتر از Retrofit هستش. پشتیبانی از Image loading. دارای bitmap caching. سازگاری مناسب با activity lifecycle. دارای memory error handing مناسب. هندل کننده duplicate calls. استفاده نسبتاً آسان.
این نکته رو هم در نظر داشته باشید که هرکدوم مزایا و معایب خودشونو دارن و باید درجای مناسبش کتابخانه مناسب رو انتخاب کنید.
6- برای حل مشکل Error: duplicate class: com.x.x.R در Android Studio، کافیه پوشه build رو حذف کنید تا مجدداً تولید بشه. (اگر درست نشد بدنبال فایل R.java بگردید و دستی حذفش کنید)
7- آیا میدونید گوگل در اندروید Nougat به قبل برای Davlik VM از subset های پروژه Apache Harmony Development Kit برای Class Library هاش استفاده می کرد و نه JDK؟ و توسعه این پروژه Apache HDK هم در سال 2011 متوقف شده...
8- برای حل مشکل No Java virtual machine was found after searching the following locations در برنامه Eclipse یکی از راه های زیر رو دنبال کنید:
C:\Program Files\eclipse\jre\bin\javaw.exe
javaw.exe in your current PATH"
-مطمعن بشید که JRE روی سیستم نصب شده باشه.
-مطمعن بشید که JRE و Eclipse نصب شده هردو از یک معماری باشن. (هردو x86 یا هردو x64 باشن)
-سیستم رو یکبار خاموش و روشن کنید.
-به مسیر نصب شده برنامه Eclipse برید و فایل eclipse.ini رو باز کنید و عبارات زیر رو در خط اولش قرار بدید:
-vm C:\Program Files\Java\re\bin\javaw.exe
بجای مسیر بالا، مسیر JRE مال خودتون رو قرار بدید.
9- Dalvik-VM نه کتابخانست و نه سیستم عامل! بلکه یک ماشین مجازی در اندروید هست که برنامه های نوشته شده برای اندروید رو اجرا میکنه.
درواقع برنامه هایی که توسط جاوا(test.java) نوشته میشن، توسط برنامه javac برای JVM تبدیل به بایت کد(test.class یا test.jar) میشن و بعد به بایت کد مخصوص Dalvik-VM با پسوند DEx و ODEx ترجمه میشن... اما گوگل از اندروید 4.4 به بعد، در کنار Dalvik-VM نرم افزار جدید ART خودش رو (بصورت آزمایشی) رونمایی کرد و سرانجام در اندروید 5.0 بصورت رسمی با Dalvik-VM خداحافظی کرد.
10- برای حل مشکل Android requires compiler compliance level 'Y'. Found 'X' instead و Description Resource Path Location Type Incompatible .class files version in required binaries روی پروژه راست کلیک کنید و گزینه Android tools -> Fix project properties رو بزنید.
نکته: اون خطا یعنی باید نسخه Java Compiler برنامه Eclipse با نسخه Project build target اندروید سازگار باشه... برای نمونه، کامپایل پروژه با اندروید 1 و 2 و 3 نیازمند JDK 6(یا همون 1.6) به قبل هستش ولی کامپایل پروژه با اندروید 4 و 5 نیازمند JDK 7(یا همون 1.7) به بعد هستش. و کامپایل پروژه با اندروید 7 به بعد نیازمند JDK 8(یا همون 1.8) به بعد هستش.
11- برای حل مشکل ...sdk.dir is missing. Make sure to generate local.properties using یک فایل با نام local.properties در پوشه اصلی پروژه ایجاد و محتوای زیر رو داخلش کپی کنید:
sdk.dir=<YOUR-ANDROID-SDK-HOME>
بجای عبارت <YOUR-ANDROID-SDK-HOME>، مسیر Android SDK خودتون رو وارد کنید.
12- اگر درحین اجرای برنامه یا Emulator ها با خطای ERROR: x86 emulation currently requires hardware acceleration مواجه شدید، یکی از راه های زیر رو دنبال کنید:
- برنامه Intel Hardware Accelerated Execution Manager رو دانلود و در پوشه extras داخل دایرکتوری SDK کپی کنید، و بعد از کپی اون رو اجرا کنید تا نصب بشه. نهایتا Android Studio/Eclipse رو ببندید و دوباره بازش کنید. (برای دانلود می تونید ازطریق خود برنامه SDK Manager یا سایت رسمی Intel اقدام کنید)
نکته: شاید لازم باشه که Virtualization Technology رو در BIOS سیستمتون On کنید.
نکته 2: Intel HAXM نیازمند Android SDK +17 و ویندوز 7, 8, 8.1 یا 10 یا مک هستش.
- یا امولاتور Android های ARM رو نصب و استفاده کنید.
13- اگر داخل برنامه SDK Manager در جلوی عنوان emulator ها پیام not compatible with windows نوشته شده بود، برنامه SDK Manager رو ببندید و مجدداً از طریق گزینه Run as administrator در منوی کلیک راست بازش کنید. اگر از این طریق هم درست نشد، به آدرس http://downloads.puresoftware.org/files/android/API مراجعه و نسخه مورد نظر رو دانلود کنید، بعد از دانلود در پوشه platforms در مسیر نصب شده SDK تون extract ش کنید.
14- فراموش نکنید که برای تولید اعداد صحیح random باید از کلاس Random()
یا ThreadLocalRandom
استفاده کنید و برای تولید اعداد دوبل random از Math.random()
.
15- برای حل مشکل AndroidManifest.xml file missing در برنامه Eclipse یکی از راه های زیر رو دنبال کنید:
راه اول: برنامه Eclipse رو ببندید و مجدداً باز کنید.
راه دوم: به مسیر Menu -> Project -> Properties -> Builders برید و گزین Android Pre Compiler رو تیک بزنید.
راه سوم: پروژه رو Clean کنید: Menu -> Project ->Clean.
راه چهارم: مطمعن بشید که مسیر /Android SDK/tools و /Android SDK/platform-tools در PATH سیستم وجود دارن.
16- بدنبال استفاده از Java Db / Apache Derby در اندروید نباشید، اندروید در حال حاضر از این دیتابیس پشتیبانی نمی کنه! و باید از SQLite استفاده کنید.
نکته: قطعاً در موارد دیگر Java Db / Apache Derby جایگزین خوبی برای SQLite هستش. چون هم از SQL99 پشتیبانی میکنن و هم از SQL92 بصورت کامل.
17- برای اضافه کردن کتابخانه به CLASSPATH پروژه در Eclipse یکی از راه های زیر رو دنبال کنید:
راه اول: کتابخانه موردنظر رو در پوشه libs پروژه کپی کنید، بعد روی نام فایل کتابخانه راست کلیک کنید و گزینه Build path -> Add to build path رو انتخاب کنید.
راه دوم: فایل کتابخانه مورد نظر رو در پوشه libs پروژه کپی کنید، به مسیر Project -> Properties -> Build path -> Libraries برید، بعد دکمه Add JArs رو بزنید و پوشه libs رو انتخاب و فایل کتابخانه رو باز کنید.
راه سوم: به مسیر Project -> Properties -> Build path -> Libraries برید و دکمه Add External JAr رو بزنید، بعد فایل کتابخانه مورد نظر رو باز کنید.
توجه: با این روش فایل کتابخانه در پوشه پروژه شما کپی نمیشه و فقط بصورت Relative link استفاده میشه.
راه چهارم: به مسیر Window -> Preferences -> Java -> Build path -> Classpath variables برید و دکمه New رو بزنید، بعد در پنجره باز شده عنوان مناسبی در Name بنویسید، حالا دکمه File رو بزنید و کتابخانه مورد نظر رو باز کنید. نهایتاً به مسیر Project -> Properties -> Build path -> Libraries برید، بعد دکمه Add variable رو بزنید و کتابخانه مورد نظر رو انتخاب کنید.
توجه: با این روش فایل کتابخانه در پوشه پروژه شما کپی نمیشه و فقط بصورت Relative link استفاده میشه.
18- همیشه در طراحی inner class ها سعی در استفاده از کلاس static
کنید... چون کلاسهای غیر static
رفرنسی رو به کلاس والد در خودشون ذخیره میکنن. و با این رفرنس می تونن فیلدها و متدهای کلاس والدشون رو صدا بزنن. لذا بکمک کلاس static
کاهش مصرف فضا رو خواهید داشت.
19- آیا می دونید حداکثر ظرفیت حافظه Heap در اندروید، بیشتر مبتنی بر اندازه resolution و مقدار density صفحه هست؟
برای نمونه، ظرفیت حافظه Heap در گوشی HTC Salsa فقط 20 مگابایته ولی در گوشی HTC Desire بین 32 تا 48 مگابایته! درصورتی که هردو از اندروید 2.3.3 استفاده می کنن، حدوداً 400 تا 600 مگابایت RAM دارن و برای یک شرکت هم هستن. البته فقط درصد کمی از این مقدار مختص برنامه شماست، بقیه صرف خود سیستم عامل، ART/DVM، سرویس ها و غیره میشه.
نکته: resolution، تعداد پیکسل های افقی و عمودی در صفحه رو تعریف می کنه. ولی density فاصله اون پیکسل ها نسبت به یکدیگر رو تعریف میکنه. (که درواقع sharp بودن یا نبودن صفحه رو تعیین میکنه - کلمه اختصاریش هم DPI هستش)
20- LeakCanary یک کتابخانه جاوا بسیار عالی برای پیدا کردن memory leak ها در برنامه.
21- در صورتی که قادر نیستید پلاگین ای رو در برنامه Eclipse نصب کنید، کافیه فایل zip/jar پلاگین رو extract و پوشه های plugins و features رو در محل نصب Eclipse کپی کنید. بعد Eclipse رو بسته و مجدداً باز کنید.
22- نکته جزیی: JavaDoc و AndroidDoc برای نمایش decleration یا tooltips طراحی نشدن و فقط برای باز کردن لینک مستند در مرورگر هستن. مثل http://docs.oracle.com/javase/6/docs/api/javax/swing/AbstractCellEditor.html
23- همیشه resource هایی مثل XmlResourceParser
, FileInputStream
, Scanner
, DataOutputStream
و... رو بعد از استفاده close()
, destroy()
یا shutdown()
کنید تا memory leak بوجود نیاد.
24- فراموش نکنید که در اندروید System.getProperty("os.name"))
نسخه Kernel لینوکس رو برمیگردونه، و نه نسخه اندروید رو.
25- اگر در برنامه Eclipse برای دیدن Decleration یا Tooltips دستورات اندروید (یا همون API اندروید) با مشکل source not found مواجه هستید، کافیه سورس Android SDK رو در Eclipse ضمیمه کنید:
راه اول: دکمه Attach source رو بزنید و در پنجره باز شده گزینه External folder رو انتخاب کنید، بعد پوشه sources رو از محل نصب Android SDK انتخاب و همه پنجره هارو Ok/Finish کنید.
راه دوم: به مسیر Project -> Properties -> Java build path برید، بعد نسخه اندروید مورد نظر رو انتخاب و باز کنید، سپس در لیست باز شده گزینه android.jar رو انتخاب و باز کنید، بعد گزینه source attachment رو انتخاب و دکمه Edit رو بزنید، حالا در پنجره باز شده گزینه External location رو انتخاب کنید و دکمه External folder رو بزنید، نهایتاً پوشه sources رو از محل نصب Android SDK انتخاب و همه پنجره هارو Ok/Finish کنید.
نکته: برای دانلود سورس Android SDK، برنامه Android SDK Manager رو از مسیر نصب شده یا Window -> Android SDK Manager باز کنید، بعد پکیج Source for Android SDK رو تیک زده و Install کنید. (یا مستقیماً از آدرس http://repository.grepcode.com/java/ext/com/google/android/android یا http://downloads.puresoftware.org/files/android/sources دانلود کنید)
26- مهمترین تفاوت الگوی Adapter و الگوی Facade:
- الگوی Adapter عمل تبدیل(convert) کلاس انجام میده اما الگوی Facade عمل ساده/خلاصه سازی(simplify) کلاس انجام میده.
- الگوی Adapter در نهایت یک کلاس رو پوشش میده اما الگوی Facade چندین کلاس رو پوشش میده.
27- نکته جزیی: آیا میدونید گوگل از اندروید Nougat به بعد از OpenJDK استفاده می کنه؟
28- برنامه Eclipse نیازمند JRE هستش و نه JDK! چراکه Eclipse بصورت built-in کامپایلر جاوا داره و فقط برای اجرای برنامه به JRE نیاز داره. (لذا JDK فقط صرف برنامه هایی مثل Maven, Ant, Gradle خواهد شد)
29- چه زمانی باید از الگوی Facade استفاده بشه؟
1. زمانی که نیاز به کپسوله سازی(encapsulation) قابلیت های سیستم داریم.
2. نیاز نیست از تمام قابلیت ها و پیچیدگی های سیستم استفاده بشه. بنابراین API جدید درست شده از API فعلی سیستم ساده تر و محدودتر خواهد بود.
30- نکته جزیی: حتی اگر Thread main برنامه متوقف/بسته بشه، درصورت وجود Thread های دیگر(non-daemon)، برنامه کماکان به کار کردن ادامه میده. (مگر اینکه متدSystem.exit()
یا Runtime.exit()
صراحتاً صدا زده بشه)
نکته: اگر هنگام ساخت Thread از متد Thread.setDaemon(true)
استفاده بشه، Thread ساخته شده از نوع daemon خواهد بود.
31- مفهوم Native app و Native programming:
در دستگاه های مبتنی بر اندروید، برنامه هایی که با Java نوشته میشن داخل VM (یا DVM/ART) اجرا میشن و این ماشین مجازی byte-code های تولید شده رو تفسیر میکنه.
اما برنامه هایی که با C/Cpp نوشته میشن به instruction های ماشین سخت افزاری کامپایل میشن که مستقیماً توسط CPU اجرا میشن. به این گونه از برنامه نویسی و برنامه ها Native گفته میشه. چون برای CPU بومی/native هستش.
اینم بدونید که هر گونه ای از CPU(مثل ARM و Intel-AMD) ساختار و instruction مخصوص خودشونو دارن. یعنی تفاوتشون مثل تفاوت زبان Java و زبان PHP هستش!
نکته: زمانی که از NDK اندروید استفاده میکنید قادرید کدها رو برای انواع مختلفی از CPU کامپایل/تولید کنید اما در نهایت یک APK هستش که براتون باقی می مونه.
32- برای حذف شدن notification هنگام کرش برنامه یا ویدجت، همیشه از یک ID ثابت برای Notification
استفاده کنید.
33- همیشه static initializer های کلاس رو در بالاترین قسمت کلاس قرار بدید.
public class Foo() { static { System.setProperty("java.awt.headless", "true"); System.out.println("Hello world!"); } private int number; public static void main() {} // ... }
34- برای جلوگیری از recreate/destroy شدن Activity هنگام بیرون کشیدن صفحه کلید سخت افزاری، کافیه صفت android:configChanges="keyboardHidden"
رو در تگ activity
موردنظر فایل AndroidManifest.xml اضافه کنید.
35- برای حل مشکل Cannot reload AVD list: cvc-enumeration-valid: value '280dpi' is not facet-valid with respect to enumeration... در برنامه Android Studio یکی از راه های زیر رو دنبال کنید:
راه اول: مطمعن بشید که USB Debugging در اون Emulator فعال باشه!
راه دوم: برید به مسیر Android\SDK\system-images\android-X\android-wear\armeabi-v7a\ و فایل devices.xml رو با ویرایشگر باز کنید. بعد بدنبال 280dpi بگردید و با 280hdpi جایگزینش کنید. همچنین برید به مسیر Android\SDK\system-images\android-X\android-wear\x86\ و فایل devices.xml رو با ویرایشگر باز کنید. بعد بدنبال 280dpi بگردید و با 280xhdpi جایگزینش کنید. حالا همه برنامه هارو ببندید و دوباره باز کنید و تست کنید. (اگر درست نشد 280xhdpi رو جایگزینشون کنید)
راه سوم: فایل devices.xml رو در مسیر Android\SDK\system-images\android-X\android-wear\armeabi-v7a\ و مسیر Android\SDK\system-images\android-23\android-wear\x86\ حذف کنید.
راه چهارم: برنامه Android SDK رو باز کنید و پکیج های Android Wear ARM و Android Wear Intel x86 Atom رو Uninstall کنید.
راه پنجم: کلاً پوشه android-wear در مسیر \Android\SDK\system-images\android-X رو حذف کنید.
36- با اضافه کردن صفت manifestmerger.enabled=true
برای Ant در فایل build.xml می تونید manifest برنامه و کتابخانه اندروید ضمیمه شده رو merge کنید.
37- توسط کالبک onRestoreInstanceState
و onSaveInstanceState
می تونید داده های موقتی کاربر رو ذخیره و مجدداً بازیابی کنید.
نکته: کالبد onRestoreInstanceState در هنگام چرخش گوشی یا ذخیره داده توسط onSaveInstanceState فعال میشه.
38- نکته جزیی: طبق گفته گوگل، آیکون های notification/status باید سیاه و سفید و بترتیب در سایزهای زیر طراحی بشن:
ldpi = 12x19, mdpi = 16x25, hdpi = 24x38, xhdpi = 32x50, xxhdpi = 48x48, xx*xhdpi 64x100
39- تفاوت ساختار دایکتوری پروژه در Android Studio و Eclipse:
Android Studio | Eclipse |
واژه module | واژه project |
srs/main/assets/ | assets/ |
srs/main/java/ | srs/ |
srs/main/res/ | res/ |
srs/main/libs/ | libs/ |
idea. | project.properties |
واژه External Libraries | واژه Refrenced Libraries |
local.properties | local.properties |
build/ | bin/ |
build/generated/ | gen/ |
Gradle - build.gradle | Ant, Maven, Gradle |
src/main/jniLibs/ | native-libs/ |
40- برای نصب همزمان برنامه و widget بر روی صفحه home باید صفت installLocation="internalOnly"
رو در تگ manifest
فایل AndroidManifest.xml اضافه کنید:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.package.name" android:versionCode="1" android:versionName="1.0.0" android:installLocation="internalOnly">
مقالات مرتبط
نکات و اصول مهم در برنامه نویسی Java/Android
#2 - نکات و اصول مهم در برنامه نویسی Java/Android
#3 - نکات و اصول مهم در برنامه نویسی Java/Android
#5 - نکات و اصول مهم در برنامه نویسی Java/Android
هروقت نکته ای یافتین یا به مشکلی برخوردین توی یه فایلی ثبت میکنید؟