آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

#4 - نکات و اصول مهم در برنامه نویسی Java/Android

Y.P.Y  8 سال پیش  8 سال پیش
+6 0

در ادامه مقاله قبلیم که شماره سه "نکات و اصول مهم در برنامه نویسی Java/Android" بود، در این مقاله شماره چهار همین موضوع رو ارائه میدم... منتها بیشتر به رفع مشکلات و خطاها می پردازم.

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 در جاوا یک مفهوم دارن: دسترسی همزمان به کد توسط چند Threads بدون بروز مشکلات. یعنی کد/متد 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 یکی از راه های زیر رو دنبال کنید:

"A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the following locations:
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 در پوشه اصلی پروژه ایجاد و محتوای زیر رو داخلش کپی کنید:

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.

# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
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 هستش.


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- تشریح CLASSPATH: برای استفاده ClassLoader های خود Java طراحی شده و حاوی bytecode(در Java با نام class. یا JAr) یا nativecode(در C با نام o. یا obj.) های کامپایل شده هستش. درواقع بخشی از پکیج اصلی Java/C هستش و به java و javac اعلام میکنه که فایلهای کامپایل شده در کجا قرار دارن.

توجه: با اضافه کردن کتابخانه به CLASSPATH، کتابخانه مورد نظر در تمام پروژه ها قابل استفاده هستش، لیکن بصورت Relative link.

نکته 1: مقدار CLASSPATH میتونه توسط پارامتر -cp در برنامه java و javac و خاصیت Class-Path در فایل manifest.mf تغییر پیدا کنه. اما نهایتاً خاصیت Class-Path در فایل manifest.mf نسبت به CLASSPATH و پارامتر -cp اولویت داره.

نکته 2: همیشه علاوه بر مسیر lib خود JDK، مسیر جاری رو هم توسط نقطه . در CLASSPATH اضافه کنید.

نکته 3: در صورت وجود کتابخانه در همه مسیرهای موجود در CLASSPATH، همیشه اولین مسیر انتخاب خواهد شد.

نکته 4: این تنظیم در برنامه Eclipse در مسیر Preferences -> [Java/C] -> Build path -> Classpath قرار داره.


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 کاهش مصرف فضا به میزان 4 تا 8 بایت رو خواهید داشت.


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 هایی مثل XmlResourceParserFileInputStreamScannerDataOutputStream و... رو بعد از استفاده close()destroy() یا shutdown() کنید تا memory leak بوجود نیاد.


24- فراموش نکنید که System.getProperty("os.name")) نسخه Kernel لینوکس رو برمیگردونه، و نه نسخه اندروید رو.


25- اگر در Eclipse برای دیدن Decleration یا Tooltips دستورات جاوا (یا همون API جاوا) با مشکل source not found مواجه هستید، کافیه سورس JRE رو در Eclipse ضمیمه کنید:

راه اول: دکمه Attach source رو بزنید و در پنجره باز شده گزینه External folder رو انتخاب کنید، بعد فایل src.zip رو از محل نصب JDK باز و همه پنجره هارو Ok/Finish کنید.

راه دوم: به مسیر Window -> Preferences -> Java -> Installed JRE برید، بعد JRE مورد نظر رو انتخاب و دکمه Edit رو بزنید، سپس در لیست باز شده همه گزینه ها رو انتخاب و دکمه Source attachment رو بزنید، حالا گزینه External location رو انتخاب و دکمه External file رو بزنید، نهایتاً فایل src.zip رو از محل نصب JDK باز کنید و همه پنجره هارو Ok/Finish کنید.

نکته: برای دانلود سورس JRE، در لینوکس باید پکیج openjdk-7-source یا openjdk-6-source رو دانلود کنید و در Mac پکیج Java for OS X Developer Package رو.


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 نوشته میشن داخل JVM(یا 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- نکته جزیی: آیا میدونید موقعیت keyguard در widgetCategory فقط در اندروید 5 به قبل موجود هستش؟


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">
+1 0
سلام.ممنونم از به اشتراک گذاشتن مقالتون. (8 سال پیش)
 برای این سوال پاسخی وجود ندارد.

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .