نمایش تصاویر منابع در زمان اجرای برنامه

در این درس از دوره آموزشی توسعه اندروید، نحوه نمایش تصاویر ذخیرهشده در پوشه assets بررسی میشود. ابتدا با ایجاد این پوشه و افزودن فایلهای تصویری به آن آشنا میشویم. سپس با استفاده از کلاس AssetManager، نحوه دسترسی به فایلهای داخل پوشه و بارگذاری تصاویر بهصورت Drawable برای نمایش در ویجت ImageView توضیح داده میشود. این روش برای مدیریت منابع خاص و دسترسی مستقیم به فایلها در زمان اجرا کاربرد دارد و مزایای آن در مقایسه با استفاده از پوشههای res/drawable نیز بیان میگردد. در نهایت، نکات بهینهسازی حافظه و جلوگیری از مشکلاتی مانند OutOfMemoryError هنگام کار با تصاویر بزرگ مطرح میشود. این درس به طور کامل چگونگی مدیریت منابع گرافیکی در پروژههای اندروید را پوشش میدهد و برای توسعهدهندگانی که به بهینهسازی و استفاده مؤثر از منابع اهمیت میدهند، ضروری است.
تا اینجا، سه روش متفاوت برای نمایش تصویر با استفاده از کنترل Image View توضیح دادم. شما میتوانید همه اون کارها رو در فایل لایوت، با استفاده از یک image resource ثابت انجام بدهید، یا میتوانید به یکimage resource ثابت در کد جاواتون اشاره کنید، همینطور که می بینید من در ویدئو آموزشیِ قبلی در این خط این کارها رو انجام دادم. یا میتوانید بصورت پویا درش بیاورید، به طوری که با یک رشته شروع کنید و منبع اون عکس رو از این رشته بدست بیاورید. ولی راه دیگری هم هست که میشود از یک منبع استفاده نکرد، بلکه بجای آن از فایلی به نام asset استفاده میشود. فایل های asset در فولدر assets قرار دارند و برخلاف منابع، به هیچ وجه درون برنامه کامپایل نمیشوند و resource آیدی خاصی ندارند. بجای آن، شما آدرس یک فایل asset رو با استفاده از نامش میدهید و هیچ چیز دیگری هم برای انجام در کلاس جاوا نیاز نیست.
پروژه ای که دارم روی آن کار میکنم اسمش Image Asset هست و کارم رو در این پروژه با ساخت فولدری به نام assets شروع میکنم. در نسخه های قدیمی تر Android SDK tools، پروژه های جدیدی که تعریف می کردیم همیشه فولدر assets رو داشتند، ولی در این نسخه از Android Studio، خودتان باید فولدرِ assets پروژه های جدیدتان را بسازید.
روی ماژول app کلیک میکنم و بعد به منو میروم و با انتخاب File و بعد New و نهایتاً میآیم پایین Folder رو انتخاب میکنم و بعد هم Assets Folder.
مکان پیش فرض آن در فولدر main داخل ماژول جاری هست.
روی Finish کلیک میکنم.
این هم فولدر جدید من. درواقع داریم این فولدر رو در ویو Android میبینیم که محل واقعی نگهداری فولدر، روی دیسک رو به ما نشان نمیدهد.
پس میروم به ویو project و میبینیم که assets جدید ما در فولدر main قرار دارد.
اون داخل فولدر res یا resources یا همان منابع نیست.
ولی جز فایل های پکیج برنامه برای زمان توزیع اپلیکیشن هست.
حالا میروم سراغ فولدر منابعم یعنی فولدر res و زیر فولدر draw able و این فایل رو جابجا میکنم.
خب؛ این فایل دیگر جزء منابع نیست، ولی یک asset هست.
وقتی آنرا میگذارم توی این فولدر asset یک دیالوگ تأیید ظاهر میشود و اون رو اوکی میکنم و تصویر برای من نمایش داده میشود.
خب؛ حالا اگر بخواهیم میتوانیم با این فایل کار کنیم.
آنرا میبندم و به کد جاوا میروم.
میخواهم از برنامه اجرا بگیرم ولی قبل اجرا به شما بگویم که برنامه ارور میدهد و با شکست روبرو میشویم.
وقتی برنامه میخواهد روی صفحه نمایش بالا بیاید، این پیام unfortunate که میگوید H+ Sport has stopped ظاهر میشود. یعنی برنامه بخاطر وجود مشکل یا مشکلاتی متوقف شده.
اوکی میزنم.
روی خود دستگاه هیچ اطلاعات مفیدی برای اینکه بفهمم چه اتفاقی افتاده و دلیل ارور برنامه من چیست وجود ندارد. این استثناعاً اولین برنامه ای است که با آن با مشکل مواجه شدیم وباید بفهمیم چه اتفاقی در زمان اجرا در exception جاوا افتاده.
وقتی یک برنامه اندروید موقع اجرا روی دستگاه با مشکل روبرو میشود، اولین کاری که میکنید باید بروید سراغ این پنجره Android Monitor و بعد خروجی log cat رو، با کلمه Android Runtime فیلترش کنید و بعد میتوانید ارورها رو ببینید.
گاهی اوقات اون چیزی که دنبالش هستید در بالای این لیست از exception ها هست؛ ولی گاهی هم مثل الان پیدا کردن آن کمی سخت است.
بیایید تا به این برچسب یک نگاهی بیندازیم، منظورم برچسب Caused By هست و در این مورد میبینید که، مشکل این عبارت Resources NotFoundException هست، در واقع میگوید منبع مورد نظر پیدا نشد.
چون میبینیم که resource ID هم که پیدا کرده، صفر هست. خب مشکل اینجا است.
وقتی برنامه بالا میآید، این رشته jacket101 رو به عنوان string قرار میدهد و بعد کد خط 49 اجرا میشود که دنبال یک منبع draw able با نام داده شده میگردد؛ ولی پیدایش نمیکند و متد get Identifier مقدار صفر رو برمیگرداند.
و بعد رفتم و set ImageResource رو فراخونی کردم، و خواسته تصویری رو که در منابع وجود ندارد داخل image view قرار بدهد. خب؛ حالا به شما میگویم چطوری اینکار رو با فایلهایی که در فولدر assets هستند انجام بدهید.
این دو خط رو کامنت میکنم و کدهای پیدا کردن فایل تصویری از فولدر assets رو اضافه میکنم.
من یک نمونه از کلاس java.io با نام Input Stream ایجاد میکنم و اسمش رو میگذارم stream.
و بعد متدی رو تحت عنوان get Assets فراخوانی میکنم و از لیستی که در اون باز میشود open.و نهایتاً هم نام فایلی که دنبالش هستم رو وارد میکنم.
من image Name رو وارد میکنم.
ولی این نام کامل فایلی که دنبالش هستم نیست. نام کامل فایل من jacket101.png هست.
پس یک بعلاوه میگذارم و دات png رو اضافه میکنم.
ولی هنوز زیرش خط قرمز کشیده و ارور دارم و راهنما این ارور به من میگوید که این عبارت ممکن است رد بشود و موقع اجرا خطا بدهد؛ مثلاً ممکن است فایل مورد نظر رو پیدا نکند و پیشنهادش این است که از بلوک try/catch استفاده کنم.
آنرا انتخاب میکنم تا کدهای مورد نیاز رو اضافه کند و بقیه کدهایم رو اینجا داخل try اضافه میکنم.
خب؛ بعد ساخت stream، یک نمونه از کلاس Draw able ایجاد میکنم.
نمونه ای از کلاس Draw able که عضو پکیج android .graphics.drawable هست.
اسمش رو d میگذارم و با فراخوانی متدی از کلاس Draw able با نام create FromStream به آن مرجع میدهم.
این متد دو تا آرگومان میخواهد.
اول یک stream و بعد بعنوان آرگومان دوم یک رشته که من نیازش ندارم، پس مقدار null به آن میدهم.
خب؛ حالا میتوانم تصویر رو نمایش بدهم و اینکار رو با فراخوانی متد set ImageDrawable برایImage View انجام میدهم.
خب؛ الان متد Draw able رو فراخوانی میکنم نه متد Resource رو و شیء Draw able که ایجاد کردم رو به آن میدهم و کد رو اجرا میکنم و اینبار لود شدن تصویر با موفقیت انجام میشود.
بنابراین میتوانید هم با resources و هم با assets کار کنید و انتخاب استفاده از کدام نحوه عملکرد هم با خودتان است. توصیه من این است که وقتی دارید با یک تصویر تنها کار میکنید، همه چیز رو در فولدر resources نگهداری کنید؛ ولی وقتی در حال کار کردن با چندین تصویر هستید، که در این دوره بعداً میبینید که این مورد رو خواهیم داشت، و بعداً بالطبع شما متوجه خواهید شد که برای اجرای سریعتر برنامه و گیر زدن کمتر بهتر است از فولدر assets و باز کردن تصاویر به صورت پویا، یعنی با همین روش حال حاضر در کارتان پیش بروید و متوجه میشوید که بهتر است از این روش استفاده بشود.