<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ali Nasrabadi</title>
        <link>https://virgool.io/feed/@nasrabadiam</link>
        <description>مهندس نرم‌افزار | برنامه‌نویس‌ اندروید | علاقه‌مند به دانستن چگونگی چیز‌ها</description>
        <language>fa</language>
        <pubDate>2026-06-17 00:24:36</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/969/avatar/33BN3T.png?height=120&amp;width=120</url>
            <title>Ali Nasrabadi</title>
            <link>https://virgool.io/@nasrabadiam</link>
        </image>

                    <item>
                <title>قسمت سوم - لابه‌لای زندگی اکتیویتی - ۲</title>
                <link>https://virgool.io/@nasrabadiam/%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-%D9%84%D8%A7%D8%A8%D9%87%D9%84%D8%A7%DB%8C-%D8%B2%D9%86%D8%AF%DA%AF%DB%8C-%D8%A7%DA%A9%D8%AA%DB%8C%D9%88%DB%8C%D8%AA%DB%8C-%DB%B2-qu9dvdfxivcx</link>
                <description>در قسمت قبلی با عنوان قسمت دوم - لابه‌لای زندگی اکتیویتی - ۱ یک مقدار درباره چرخه‌حیات اکتیویتی صحبت کردیم و قرار شد توی این پست چند سناریو مختلف رو بررسی کنیم تا بیشتر با چرخه‌حیات اکتیویتی آشنا بشیم و اون رو بهتر بفهمیم.سناریو اول: اکتیویتی finish شده و دوباره باز شوددر صورتی اتفاق می‌افتد که: کاربر دکمه back  را بزند و اکتیویتی را دوباره باز کند(یا در کد این کار انجام شود). سناریو دوم: کاربر از اپ بیرون بروددر دو صورت اتفاق می‌افتد: کاربر دکمه Home  را بزند.کاربر برنامه دیگری را باز کند.(از طریق کلیک روی نوتیفیکیشن‌ها و ...)سناریو سوم: Configuration برنامه تغییر کنددر صورتی اتفاقی می‌افتد که: تغییرات Configuration  مثل چرخش صفحه.کاربر سایز برنامه را در حالت Multi-window  تغییر دهد. سناریو چهارم: برنامه pause شوددر صورتی اتفاق می‌افتد که: فعال کردن Multi-Window  در API +24  و از دست رفتن Focus.یک اپ دیگر قسمتی از صفحه را بپوشاند، مثل نمایش دیالوگ پرداخت برنامه‌ای دیگر، یا دیالوگ گرفتن ران‌تایم پرمیشن‌ها و ...یک Intent Chooser نمایش داده شود، مثل اینتنت Share.سناریو پنجم: جابجایی بین اکتیویتی‌ها ابتدا یک اکتیویتی باز شده، سپس یک اکتیویتی دیگر روی آن باز می‌شود و بعد از آن به ترتیب بسته می‌شوند.سناریو ششم: اکتیویتی در بک‌استک باشد و Configuration تغییر کنداکتیویتی۱ در بک‌استک قرار دارد و اکتیویتی۲ روی آن قرار دارد و در این حالت دستگاه را می‌چرخانیم.سناریو هفتم: پروسه اپ توسط اندروید ازبین برود و دوباره اجرا شوددر این حالت پروسه اپ توسط اندروید بسته می‌شود تا منابع برای دیگر برنامه‌ها استفاده شود.همچنین اکتیویتی۱ در بک‌استک قرار دارد و اکتیویتی۲ روی آن قرار دارد.اگر نظر یا سوالی داشتید، میتونید زیر همین پست کامنت بگذارید. در پست بعدی درباره‌ی اینکه چطور وضعیت‌های مختلف رو توی اکتیویتی‌مون هندل کنیم، صحبت میکنیم.منابعhttps://medium.com/androiddevelopers/the-android-lifecycle-cheat-sheet-part-i-single-activities-e49fd3d202ab</description>
                <category>Ali Nasrabadi</category>
                <author>Ali Nasrabadi</author>
                <pubDate>Mon, 02 Mar 2020 08:42:36 +0330</pubDate>
            </item>
                    <item>
                <title>گرفتن تغییرات به راحتی آب خوردن (git patch)</title>
                <link>https://virgool.io/@nasrabadiam/%DA%AF%D8%B1%D9%81%D8%AA%D9%86-%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1%D8%A7%D8%AA-%D8%A8%D9%87-%D8%B1%D8%A7%D8%AD%D8%AA%DB%8C-%D8%A2%D8%A8-%D8%AE%D9%88%D8%B1%D8%AF%D9%86-git-patch-scgtw1lxnllp</link>
                <description>جالبی گیت اینه که هر چقدر هم که بیشتر یادش میگیری، باز هم چیزهای جالبی توش پیدا میشه. کلا توی دنیای اپن‌سورس و محصولاتی که تو این فضا توسعه داده میشند، میشه خلاقیت‌های زیادی رو دید، چون هر کسی با هر ایده‌ و هر نیازی میتونه مشارکت داشته باشه. از مبحث اصلی دور نشیم.دیروز از یکی از همکارها، چیز جدیدی رو یاد گرفتم و اون هم استفاده از ابزار patch  در گیت بود.ماجرا از اینجا شروع شد که روی سیستم یکی از همکارها، یک سری تغییرات روی کد داده بودیم و نمی‌خواستیم که این تغییرات توسط اون شخص کامیت بشه، چون مسئول اون قسمت از کدها من بودم و باید توی برنچ خودم کامیتش می‌کردم. برای همین این همکار خوب پیشنهاد داد از ابزار patch  توی گیت استفاده کنیم. من که اولین بار بود این اسم رو میشنیدم، برام جالب بود که چی هست اصلا.خلاصه اینکه با یک دستور میشه از تغییراتی که هست یک فایل خروجی گرفت و اون رو، روی یک سیستم دیگه و با یک دستور روی پروژه اعمال کرد. به همین راحتی.برای گرفتن patch میشه از دستور زیر استفاده کرد: https://gist.github.com/nasrabadiAM/6260a702dbc5eb784bb027ff74ae66c1 و برای اعمال این patch هم میتونید از دستور زیر استفاده کنید: https://gist.github.com/nasrabadiAM/9e3e1bc588aea7938d0924bff8ab5746 معمولا ابزارهایی که استفاده می‌کنیم، این قابلیت‌ها رو توی خودشون دارند. مثلا اگر مثل من از خانواده ابزارهای Intelij  مثل Android Studio  استفاده می‌کنید، می‌تونید از تب VCS این گزینه رو پیدا کنید.</description>
                <category>Ali Nasrabadi</category>
                <author>Ali Nasrabadi</author>
                <pubDate>Wed, 17 Apr 2019 10:03:19 +0430</pubDate>
            </item>
                    <item>
                <title>قسمت دوم -  لابه‌لای زندگی اکتیویتی - ۱</title>
                <link>https://virgool.io/@nasrabadiam/activity-lifecycle-1-x8lhuxtfkdxy</link>
                <description>در این سری پست‌ها درباره چرخه‌حیات‌ معمول‌ترین و پراستفاده‌ترین کامپوننت‌های اندروید صحبت می‌کنیم. در قسمت قبلی درباره چرخه‌حیات و مدیریت حافظه در اندروید صحبت کردیم. اگر این قسمت را نخوانده‌اید، پیشنهاد می‌کنم قبل از شروع این مقاله نگاهی به آن بیندازید.در این قسمت می‌خواهیم از زاویه‌ای متفاوت با آنچه در پست قبلی درباره چرخه‌حیات به صورت کلی صحبت کردیم، درباره چرخه‌حیات اکتیویتی‌ها در اندروید صحبت کنیم، چیزی که معمولا خیلی عمیق آموزش داده نمی‌شود و در نتیجه خیلی عمیق آن را یاد نمیگیریم.اکتیویتی‌ها یکی از بلاک‌های سازنده اپلیکیشن‌های اندرویدی هستند، درواقع هر صفحه در اپلیکیشن‌ها حتما یک اکتیویتی است. اکتیوتی‌ چیزی فراتراز یک کلاس‌ جاوا در فریمورک اندروید نیست که رابط کاربری اپلیکیشن‌های ما را می‌سازد. پس چیز عجیب و غریبی نیست. اگر به android.app.Activity یا android.support.v7.app.AppCompatActivity یا  androidx.appcompat.app.AppCompatActivity در اندرویدایکس بروید، این کلاس را می‌بینید. که البته همه بچه‌های کلاس  android.app.Activity هستند. (از اینجا به بعد هرموقع از اکتیویتی صحبت کردیم، منظورمان هر کلاسی است که است که یکی از اجدادش android.app.Activity باشد.)مثل اپلیکیشن‌های جاوا که از متد main() شروع می‌شوند، اغلب اپلیکیشن‌های اندرویدی هم از یک اکتیوتی‌ شروع می‌شوند و حتی می‌توانیم در آن برنامه اکتیویتی‌های دیگری هم داشته باشیم.کار نمونه‌سازی اکتیوتی‌ها و مدیریت‌ آن‌ها به عهده سیستم‌عامل اندروید است. یعنی خود اندروید آن‌ها را مدیریت می‌کند و ما فقط می‌توانیم درخواست خود را برای استفاده از آن‌ها به وسیله یک Intent به اندروید بفرستیم و اندروید کار موردنظر را برای ما انجام دهد.اکتیویتی‌ها به درخواست ما ولی توسط خود اندروید ساخته و نگهداری می‌شوند. ما هیچ‌وقت در برنامه یک نمونه جدید از یک اکتیویتی را نمی‌سازیم، بلکه با استفاده از startActivity() به اندروید می‌گوییم تا این کار را برای ما انجام دهد. البته کنترل این فرآیند‌ها به صورت غیرمستقیم توسط خود ما انجام می‌شود. مثلا وقتی به اندروید می‌گوییم که اکتیویتی را start  کند، او هم این کار را انجام می‌دهد، یا حتی می‌توانیم بگوییم که این اکتیویتی جدید را در یک تسک جداگانه اجرا کند و ... .پس این کارها به صورت مستقیم در اختیار ما نیست ولی کنترل کاملی روی آن داریم و هر کاری که بخواهیم را با استفاده از ابزار‌هایی که اندروید دراختیار ما قرار داده انجام می‌دهیم.استفاده از اکتیوتی‌ها و اینتنت‌ها به اندروید این امکان را می‌دهد که از آخرین اینتنت‌های اجرا شده و در واقع از آخرین اولویت‌های کاربر آگاهی داشته باشد و بتواند براساس آن منابع را مدیریت کند. مثلا در شرایطی که مموری پر شده و اندروید نیاز دارد تا آبجکت‌های اضافی را از مموری پاک کند، با استفاده از این اینتنت‌ها و مدیریت اکتیویتی‌ها می‌فهمد که کاربر درحال حاضر با کدام اکتیویتی‌ها کار می‌کند و در نتیجه با کدام‌ها کار نمی‌کند و به این وسیله می‌تواند بقیه اکتیویتی‌هایی که کاربر با آنها کار نمی‌کند را از مموری پاک می کند.با این کار اندروید مدیریت تمام پروسه اپ و ساخت اکتیویتی‌ها را به عهده می‌گیرید. اما اینجا برای ما به عنوان برنامه‌نویس یک سری سوال به وجود می‌آید:۱. اگر من در یک اکتیویتی از برنامه‌ام در حال انجام کار مهمی باشم و اندروید اکتیویتی من را از حافظه پاک کند، چه بلایی به سر اپ من می‌آید؟۲. در این حالت باید چه کار کنم؟۳. اگر اندروید اکتیویتی‌هایی که به کاربر نمایش داده نمی‌شوند را پاک می‌کند، پس چطور کاربر با زدن دکمه back  در گوشی به اکتیویتی قبلی برمی‌گردد؟۴. و ...اما مشکل فقط اینحا نیست و اوضاع از این هم بدتر می‌شود. زمانی که کاربر گوشی را می‌چرخاند، برای آنکه تنظیمات صفحه از اول و به درستی تنظیم شوند، اندروید به صورت خودکار اکتیویتی فعلی را پاک کرده و از اول می‌سازد.دقیقا در اینجاست که متوجه می‌شویم، یک جای کار می‌لنگد. اندروید نمی‌تواند سرخود هرکاری دلش خواست بکند. این برای ما و اپلیکیشن‌مان مشکل‌ساز می‌شود. بله، دقیقا همینطور است و برای همین است که هر کاری که انجام می‌دهد را به ما خبر می‌دهد. و اینجا با چیزی روبه‌رو می‌شویم به نام چرخه‌حیات اکتیویتی. درواقع اندروید هر اتفاقی که برای اکتیویتی می‌افتد را از طریق متد‌هایی مثل onCreate()  به ما خبر می‌دهد. هر کدام از این متد‌ها در شرایط خاصی صدا زده می‌شوند تا ما بدانیم آن اتفاق خاص برای اکتیویتی ما افتاده است.خب حالا می‌خواهیم این اتفاقات خاصی که ممکن است برای اکتیویتی ما بیفتد را بررسی کنیم.ابتدا وضعیت‌هایی که اکتیویتی می‌تواند داشته باشد را بررسی می‌کنیم:وضعیت‌های مختلف اکتیویتیهمانطور که در تصویر بالا می‌بینید، هر اکتیویتی در یکی از این چهار وضعیت کلی دارد. از زمانی که درخواستی برای ایجاد یک اکتیویتی داده می‌شود تا زمانی که ازبین می‌رود، در یکی از این وضعیت‌ها قرار دارد.وارد‌شدن و خارج‌شدن اکتیویتی از هر وضعیت با کال‌بک‌هایی در اکتیویتی اعلام می‌شود. مثلا زمانیکه اکتیویتی ساخته می‌شود، متد  onCreate()  صدا زده می‌شود.وضعیت ۱ (Non-existence):این وضعیت زمانی است که اکتیویتی وجود ندارد. یعنی هنوز به وجود نیامده، یا اگر وجود داشته است، از بین رفته.به محض آنکه اکتیویتی در مموری ساخته شود، متد onCreate()  صدا زده می‌شود و اکتیوتی وارد وضعیت بعدی، یعنی وضعیت ۲ می‌شود.اگر هم اکتیویتی بخواهد از بین برود قبل از آن متد onDestroy()  صدا زده می‌شود.وضعیت ۲ (Stopped):بعد از آنکه اکتیویتی ساخته‌شد، اکتیویتی در وضعیت دوم یعنی وضعیت stopped  قرار می‌گیرد. از این لحظه زندگی اکتیویتی شروع می‌شود و نمونه آن در مموری قرار دارد ولی کاربر چیزی را نمی‌بیند.زمانی‌که  از وضعیت ۲ وارد وضعیت ۳ شویم متد () صدا زده می‌شود.و زمانی‌که از وضعیت ۳ وارد وضعیت ۲ می‌شویم مت () صدا زده می‌شود.وضعیت ۳ (Paused):در این وضعیت تمام ویو اکتیویتی یا قسمتی از آن به کاربر نشان داده می‌شود. مثلا وقتی که یک اکتیویتی را اجرا می‌کنیم که قسمتی از اکتیویتی قبلی را در پشت خود نشان می دهد و همه صفحه را نمی‌گیرد. اکتیویتی اول در حالت Paused  قرار خواهد گرفت.زمانی‌که از وضعیت ۳ وارد وضعیت ۴ می‌شویم، متد ()  صدا زده می‌شود.و زمانی‌که از وضعیت ۴ وارد وضعیت ۳ می‌شویم، متد ()  صدا زده می‌شود.وضعیت ۴ (Running):زمانیکه اکتیویتی به صورت کامل در صفحه نمایش داده می‌شود و کاربر درحال کار کردن با آن است، اکتیویتی در این وضعیت است.نکته: در هر لحظه و در کل سیستم‌عامل فقط یک اکتیویتی می تواند در وضعیت Running  قرار داشته باشد.حالا بیایید از زاویه‌ای دیگر به همین وضعیت‌ها نگاه کنیم، از زاویه اکتیویتی‌ای که درحال توسعه آن هستیم.چرخه‌حیات اکتیویتیاین تصویر همان وضعیت‌های قبلی را از زاویه اکتیویتی نمایش می‌دهد. درواقع کال‌بک‌های هروضعیت و شرایط صدا زده‌ شدن کال‌بک بعدی را نمایش می‌دهد. یعنی وقتی یک اکتیویتی را start می‌کنیم، ابتدا متد onCreate آن صدا زده می‌شود و بعد از آن متد  و همینطور الی آخر.در ادامه درمورد همه‌ی این متد‌هایی که در اکتیویتی صدا زده می‌شوند و اینکه چه زمانی صدا زده می‌شوند و همچنین اینکه در هرکدام از این متد‌ها باید چه کارهایی را انجام دهیم، صحبت می‌کنیم:onCreate()این متد اولین متدی است که بعد از ساخت اکتیویتی صدا زده می‌شود. در واقع می‌گوید که اکتیویتی ساخته شد. پس قبل از اینکه این متد صدا شود، اصلا اکتیویتی‌ای در رم وجود ندارد.حالت‌هایی که ممکن است اکتیویتی ساخته شود اینها هستند:۱. در زمانی‌که برای اولین بار اکتیویتی توسط برنامه‌نویس با startActivity ساخته می‌شود.۲. زمانی‌که برنامه را minimize کنیم و اندروید برای اجرای برنامه دیگری نیاز به مموری داشته باشد، پروسه اپ را کاملا از مموری پاک می‌کند. در این حالت اگر دوباره به برنامه برگردیم، اندروید خودش پروسه قبلی را از ابتدا ساخته و به همین دلیل اکتیویتی دوباره ساخته می‌شود.۳. زمانی‌که کاربر گوشی را بچرخاند و از حالت portrait به landscape  برود و یا بلعکس. اکتیویتی توسط خود اندروید از بین رفته و اکتیویتی دیگری با تنظیمات جدید ساخته می‌شود. برای همین این متد صدا زده می‌شود.همانطور که دیدید، اکتیویتی توسط دو نفر ممکن است ساخته شود، ۱. برنامه‌نویس ۲. اندرویدتنها در زمان‌هایی اکتیویتی توسط اندروید ساخته می‌شود که خود اندروید قبلا instance آن را از بین برده باشد.همانطور که از نام این متد (onCreate) مشخص است باید هر چیزی که می‌خواهیم بسازیم را در این قسمت بسازیم و آبجکت‌ها را مقداردهی کنیم. فایل xml مربوط به ui را به اکتیویتی وصل کنیم و آبجکت‌های آن را مقداردهی کنیم. و هر کار دیگری که در این دسته قرار می‌گیرد. اما به عنوان یک قانون کلی، در اینجا هرکاری که می‌خواهیم در طول کل زندگی اکتیویتی از آن استفاده کنیم را انجام می‌دهیم.()وقتی که اکتیویتی وارد وضعیت visible می‌شود،‌ این کال‌بک صدا زده خواهد شد. در این زمان تمام یا قسمتی از اکتیویتی درحال نمایش به کاربر است ولی هنوز کاربر نمی‌تواند با آن تعامل کند. در واقع این مرحله‌ای است که اکتیویتی درحال آماده شدن برای ورود به وضعیت foreground و تعامل با کاربر است.در این کال‌بک بهتر است کار‌هایی از قبیل نگهداری از ui و یا مقداردهی یک Broadcast Receiver را انجام دهیم. معمولا کارهای خیلی طولانی را نباید در این قسمت انجام دهیم مثل ارتباط با دیتابیس و ... .اگر کاری طولانی را در این قسمت انجام دهیم، باعث می‌شود فاصله بین نمایش اکتیویتی تا درتعامل قرار گرفتن آن بیشتر شود و تجربه خوبی را برای کاربر به وجود نمی‌آورد.()بعد از آنکه اکتیویتی وارد وضعیت Foreground می‌شود این متد صدا زده می‌شود. در این اینجاست که دیگر کاربر می‌تواند با اکتیوتی کار کند. بعد از صدا زده‌شدن  متد دیگری صدا زده‌ نمی‌شود تا اتفاقی بیفتد که وضعیت اکتیویتی را تغییر دهد(مثل: کاربر دکمه بک را بزند یا وارد اکتیویتی دیگری شود).در این متد فقط باید منابعی که کاربر در حین استفاده فقط به آنها نیاز دارد را مقداردهی کنیم، مثل انیمیشن‌ها.()به محض آنکه اتفاقی بیفتد که کاربر دیگر با اکتیویتی درتعامل نباشد، این متد صدا زده می‌شود. اگر کاربر دکمه back را بزند تا از اکتیویتی خارج شود، یا اکتیویتی دیگری اجرا شود، اولین متدی که صدا زده می‌شود، همین  است.همانطور که قبلا هم گفتیم، در هر لحظه فقط یک اکتیویتی در وضعیت Running هست و کاربر در هر لحظه فقط می‌تواند با یک اکتیویتی کار کند. اما از اندروید 7 قابلیت Multi-Window  به اندروید اضافه شد که به کاربر اجازه می‌دهد با بیش از یک اپ به صورت همزمان کار کند. شاید اینطور فکر کنید که در این حالت دو اپ یا اکتیویتی درحالت Running قرار دارند. اما اینطور نیست. وقتی درحالت Multi-Window قرار داریم، هر اکتیویتی‌ای که در آن لحظه درحال تعامل با آن هستیم، در وضعیت Running قرار می‌گیرد و اپ دیگر در حالت Visible است و آخرین متدی که از آن صدا زده شده، متد  است. در این حالت فقط متد  صدا زده شده و متد  صدا زده نمی‌شود.حالت مولتی‌ویندو در اندرویدحتی اگر یک اکتیویتی دیگر با صفحه transparent لانچ شود، و اکتیویتی قبلی هنوز نمایان باشد، در این حالت باقی می‌ماند.در این متد باید کارهایی از قبیل متوقف‌کردن انیمیشن‌ها، خالی کردن ریسورس‌هایی از قبیل برادکست‌ها  و ... که کاربر فقط در زمان تعامل با اکتیویتی به آن‌ها نیاز دارد، را انجام دهیم.در این متد نباید کارهای طولانی از قبیل ذخیره داده‌ها در دیتابیس و ... را انجام داد. این متد باید خیلی سریع اجرا شود تا اکتیویتی بعد از آن اجرا شود. پس کارهای خیلی طولانی در آن انجام ندهید.برای انجام کارهای نهایی طولانی و سنگین باید از  استفاده کنیم.()زمانیکه اکیتویتی دیگر به کاربر نمایش داده نمی‌شود، وارد این وضعیت شده و متد  صدا زده خواهد شد.همچنین در زمانیکه اکتیوتی در حال پایان یافتن (finish) است هم این متد صدازده خواهد شد. زمانیکه در وضعیت Stopped قرار داریم، Instance اکتیویتی در مموری می‌ماند و تمام متغیر‌ها و ... هم باقی خواهند ماند و فقط اکتیوتی به Window Manager متصل نیست و صفحه به کاربر نمایش داده نمی‌شود. همچنین وضعیت همه View های که id دارند نیز توسط اکتیویتی نگه‌داری می‌شود و نیازی نیست تا مقادیر آنها را نگه داریم.آخرین متد در اکتیویتی که مطمئن هستیم حتما اجرا خواهد شد،  است و هرکاری که می خواهیم در آخر اکتیویتی انجام دهیم، اینجاست. کارهایی مثل ذخیره وضعیت یا اطلاعات ورودی توسط کاربر.تمام کارهای سنگین و آن‌هایی که زمان زیادی برای انجام می‌خواهند را در این متد انجام دهید مثل ارتباط با دیتابیس و ... .همچنین همه منابعی که در اکتیویتی استفاده کردیم را باید در اینجا آزاد کنیم.onDestroy()این متد قبل از آنکه اکتیوتی از مموری پاک‌شود، صدا زده می‌شود. مثلا زمانیکه متد finish را کال می‌کنیم تا اکتیویتی بسته‌شود و یا زمانیکه سیستم‌عامل به خاطر کمبود حافظه activity/Process اپ را از بین می‌برد، بعد از  و قبل از آنکه همه‌چیز نابود شود این متد صدا زده خواهد شد.البته با متد  isFinishing در اکتیویتی می‌توانیم تفاوت این دو را متوجه شویم.ممکن است سیستم عامل به خاطر چرخش دستگاه هم این متد را صدا بزند که بلافاصله بعد از آن متد onCreate (همراه با مقادیر ذخیره شده در onSaveInstanceState) اجرا می‌شود.در پست بعدی با عنوان قسمت سوم - لابه‌لای زندگی اکتیویتی - ۲ چند سناریو مختلف را بررسی می‌‌کنیم تا بیشتر متوجه موضوعاتی که در این پست صحبت‌کردیم، بشویم.اگر این مطلب براتون مفید بوده، لطفا اون رو به بقیه هم معرفی کنید.منتظر نظرات و سوالاتتون هستم♥.منابعhttps://developer.android.com/guide/components/activities/intro-activitieshttps://academy.realm.io/posts/activities-in-the-wild-exploring-the-activity-lifecycle-android/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br/&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;</description>
                <category>Ali Nasrabadi</category>
                <author>Ali Nasrabadi</author>
                <pubDate>Thu, 03 Jan 2019 13:32:46 +0330</pubDate>
            </item>
                    <item>
                <title>قسمت اول - چرخه‌حیات و مدیریت حافظه در اندروید</title>
                <link>https://virgool.io/@nasrabadiam/android-lifecycle-vjird8iltqw1</link>
                <description>به عنوان یک برنامه‌نویس اپ‌های اندرویدی، یکی از بزرگترین چالش‌های پیش‌رو، مدیریت چرخه‌های حیات در برنامه‌ها و قسمت‌های مختلف آن است. از همین تریبون از طرف تیم توسعه‌دهنده فریمورک اندروید از این دوست عزیزمون و شما به خاطر طراحی مزخرف و پیچیده این باگ(به فریمورک کذایی اشاره دارد) عذرخواهی می‌کنم.شاید به محض دیدن موضوع این نوشته، بپرسید: چرخه‌حیاتِ چه‌ چیزی؟ و کاملا سوال به جا و درستی پرسیده‌اید. تقریبا هر کامپوننتی که در اندروید (جاوا) با آن کار می‌کنیم، چرخه‌حیات مربوط به خودش را دارد، روزی به دنیا می‌آید و روزی هم توسط Garbage Collector از صفحه‌ی روزگار (مموری) حذف می‌شود.بعضی از چرخه‌ها مثل چرخه‌حیات یک String خیلی ساده هستند و بعضی دیگر مثل چرخه‌حیات فرگمنت بسیار پیچیده‌تر(البته هر دو آبجکت هستند). اما قبل از آنکه وارد بحث چرخه‌حیات شویم، بیایید ببینیم چرا و چطور این چرخه‌ها به‌وجود می‌آیند. برای آنکه این موضوع را بفهمیم باید کمی با نحوه مدیریت حافظه در اندروید آشنا شویم. چرخه‌حیاتاندروید از Android Runtime (و یا Dalvik virtual Machine)  برای مدیریت مموری استفاده می‌کند و این سیستم هم برپایه سیستم مدیریت حافظه جاوا  یا همان Garbage Collector جاوا است. اگر با زبان c کار کرده باشید، می‌دانید که مدیریت حافظه در این زبان به عهده برنامه‌نویس است. مثلاً برنامه‌‌نویس مقداری فضا برای ذخیره یک رشته در مموری می‌گیرد و در انتها که کارش با آن رشته تمام شد، باید آن را از حافظه پاک کند و اگر نه، آن رشته در حافظه خواهد ماند و حافظه را بدون دلیل اِشغال می‌کند. این کار در جاوا به صورت اتوماتیک و توسط سیستمی به نام Garbage Collector انجام می‌شود. سیستم Garbage Collector وظیه دارد، آبجکت‌هایی که دیگر نیازی به آن‌ها نیست را از مموری پاک کند و فضای حافظه را برای استفاده مجدد آماده کند. حال وقتی که یک آبجکت می‌سازیم (در جاوا همه چیز آبجکت است به جز Primitive typeها)، فضایی برای آن در ‌هیپ‌مموری اشغال می‌شود، سپس از آن استفاده می‌کنیم و به آن مقادیر و حالت‌های مختلف می‌دهیم و در انتها(زمانی که کار ما با آن آبجکت تمام می‌شود) توسط GC (همان Garbage Collector) پاک می‌شود. به این چرخه از زمان ایجاد آبجکت تا زمانی که توسط GC از مموری پاک می‌شود، چرخه‌حیات آبجکت می‌گوییم. چرخه‌حیات بعضی از آبجکت‌ها مثل رشته‌ها به همین سادگی است که زمانی به‌وجود می‌آیند و بعد از استفاده از بین‌می‌روند، اما چرخه‌حیات بعضی دیگر مثل فرگمنت شامل پیچیدگی‌های بیشتری است و حالت‌های متفاوتی برای آن ایجاد می‌شود.مدیریت حافظه در اندرویدهمانطور که گفتیم مدیریت حافظه توسط GC انجام می‌شود. در این بخش می‌خواهیم ببینیم GC این کار را چطور انجام می‌دهد.جاوا مموری را به دو قسمت تقسیم می‌کند: هیپ‌مموری (Heap Memory)استک مموری (Stack Memory) هیپ مموریاین مموری به وسیله Java Runtime Environment  برای لود شدن کلاس‌های خودِ JRE و ساخت آبجکت‌های برنامه استفاده می‌شود. در واقع هرپروسه‌ای که توسط JVM اجرا می‌شود، یک هیپ‌مموری مجزا برای آن ساخته می‌شود و هر آبجکت جدیدی که در آن پروسه ساخته شود، در این مموری قرار می‌گیرد. سیستم GC جاوا بر روی این مموری اجرا می‌شود.نکته کم‌اهمیت‌تر اما جالب این هست که این مموری هیچ رابطه‌ای با ساختار داده درخت هیپ (Heap Tree) ندارد و این که نام این دو یکسان است، فقط یک تشابه اسمی است.استک مموریبرای هر تردی که در برنامه ساخته می‌شود (از جمله ترد اصلی یا  Main Thread) یک استک‌مموری جداگانه ساخته می‌شود(دوباره به عکس نگاه کنید).استک‌مموری‌ها دو چیز را در خود ذخیره می‌کنند: ۱-primitive typeها(که بالاتر گفتیم آبجکت نیستند) و ۲-رفرنسی از آبجکت‌هایشان در هیپ‌مموریدر واقع آبجکت‌ها در هیپ‌مموری ساخته می‌شوند و فقط رفرنسی از آن‌ها در استک‌مموری نگهداری می‌شود تا به آن آبجکت دسترسی داشته باشیم.استک‌مموری مثل ساختار داده استک عمل می‌کند، یعنی LIFO یا Last in First out است و هر آیتمی که دیرتر وارد آن شده باشد، زودتر خارج خواهد شد.  هر زمان که متد جدیدی صدا زده می‌شود، یک بلاک جدید به بالای استک اضافه می‌شود و در دسترس آن متد قرار می‌گیرد و بعد از آنکه اجرای آن قسمت از کد به پایان برسد، آن بلاکِ بالای استک هم پاپ (pop) می‌شود.اگر بخواهیم یک جمع‌بندی کوچک روی این قسمت داشته باشیم باید بگوییم که هر پروسه‌ای که در یک برنامه جاوا اجرا می‌شود، یک و تنها یک هیپ‌مموری مختص به خودش دارد که همه آبجکت‌های آن پروسه در همان هیپ‌مموری ذخیره می‌شوند(بین کل پروسه مشترک است) و هر تردی که در پروسه برنامه ایجاد می‌شود استک‌مموری مربوط به خودش هم، همراه خودش ساخته می‌شود، و هر متد که در ترد اجرا می‌شود هم، بلاک مربوط به خودش را در استک‌مموری دارد. پس به ازای هر ترد یک استک مموری داریم ولی کلا یک هیپ مموری برای کل برنامه(در اینجا فرض می‌کنیم هر برنامه یک پروسه است) خواهیم داشت. این دو مموری(هیپ و استک) با هم و به این صورت کار می‌کنند که همه آبجکت‌ها در هیپ مموری و متغیر‌های primitive  و رفرنسی از آبجکت‌های هر ترد در استک مموری ذخیره می‌شوند. Garbage Collectorاین پروسه وظیفه مدیریت مموری در جاوا را برعهده دارد. برخلاف زبان سی که مموری الوکیشن و دی‌الوکیشن توسط خود برنامه‌نویس و به صورت دستی باید انجام شود، جاوا سیستمی هوشمند برای مدیریت مموری دارد که برنامه‌نویس را از این کار معاف می‌کند.پروسه‌ی Garbage Collection به تصمیم JVM اجرا می‌شود و زمانی که اجرا می‌شود تمام ترد‌ها (هر تردی که در پروسه اجرا شده به جز آنهایی که مربوط به GC هستند) تا کامل شدن آن متوقف می‌شوند. بعد از آنکه به پایان رسید، ترد‌ها ادامه پیدا می‌کنند.همانطور که صحبت کردیم، GC روی هیپ‌مموری اجرا می‌شود تا آبجکت‌هایی که دیگر از آن‌ها استفاده نمی‌شود را پاک کند و مموری برای استفاده‌های دیگر آماده شود.نحوه کارکرد GC در جاوا را با استفاده از تصویر زیر بررسی می کنیم: این تصویر را به سه قسمت تقسیم می‌کنیم:قسمت اول یا GC Roots آبجکت‌های اولیه در هیپ مموری هستند، این‌ آبجکت‌ها پدربزرگ همه آبجکت‌هایی هستند که در مموری به وجود می‌آیند.قسمت دوم یا همان Reachable Objectها، آبجکت‌هایی هستند که از طریق ریشه‌ها در دسترس‌اند و می‌توانیم از آن‌ها استفاده کنیم. در واقع رفرنسی از ریشه به آن‌ها وجود دارد.و قسمت آخر یا Non Reachable Objectها، آبجکت‌هایی هستند که هیچ رفرنسی به آن‌ها وجود ندارد و به اصطلاح Garbage (آشغال) هستند.بیایید با یک مثال این سه قسمت را بهتر بررسی کنیم. فرض کنید یک آبجکتی از یک کلاس می‌سازیم(ریشه)، به محض ساختن این آبجکت، و در کانستراکتور آن کلی آبجکت دیگر (فرزندان ریشه) که در آن کلاس استفاده کردیم، ساخته می‌شوند. در اینجا آبجکت اولی که ساختیم ریشه بوده و آبجکت‌هایی که در آن ساخته می‌شوند، فرزندان آن ریشه هستند. این آبجکت‌ها از طریق ریشه در دسترس هستند(یک رفرنس به آن‌ها وجود دارد) و از آن‌ها استفاده می‌شود. حالا اگر رفرنسی که به این آبجکت‌ها داریم به هر دلیلی از ریشه جدا شود، یعنی دیگر هیچ رفرنسی به یکی از فرزندان ریشه وجود نداشته باشد، در این حالت آن آبجکت‌ به عنوان garbage تلقی شده و در دفعه بعدی که GC اجرا می‌شود، از مموری پاک خواهد شد.دقت کنید که معیار GC از اینکه آبجکتی را به عنوان garbage  کاندید کند، تعداد رفرنس‌ها به آن آبجکت‌ خواهد بود. پس اگر به یک آبجکت هیچ رفرنسی وجود نداشته باشد به عنوان garbage کاندید شده و از مموری پاک خواهد شد و برعکس. یعنی اگر به آبجکتی نیاز نداشته باشیم و عمداً یا سهواً به آن آبجکت رفرنسی را نگه داریم، آن آبجکت در مموری خواهد ماند و پاک نخواهد شد که به این پدیده مموری لیک می‌گوییم.اما سوالی که پیش می‌آید این است که چرا خود اندروید(GC) این چرخه‌ها را کنترل نمی‌کند؟در واقع اندروید کار سخت که سروکله‌زدن با مموری هست را انجام داده و سعی کرده با اطلاع‌رسانی قسمت‌های مختلف این چرخه به ما کمک کند تا مدیریت بهتری روی آبجکت‌مان داشته باشیم. مثلاً در فرگمت با کال‌بک‌هایی مثل: onAttach, onCreate  و.... می خواهد وضعیتی که آبجکت فرگمنت ما در آن قرار دارد را به ما اطلاع دهد تا بتوانیم بر اساس آن کارهایی که می‌خواهیم را درست و به‌موقع انجام دهیم. فقط باید این چرخه‌ها را به درستی درک کرده و یادبگیریم، تا بتوانیم درست از آن‌ها استفاده کنیم. اندروید با این کار سعی کرده اختیار را به برنامه‌نویس بدهد و دست او را باز بگذارد تا بتواند کارها را به راحتی کنترل کند و از اتفاقاتی که می‌افتد با خبر شود. از این توضیحات اولیه که بگذریم، به نکته‌ای ساده اما مهم می‌رسیم:هرچه یک چیز را بیشتر بشناسیم، می‌توانیم بهتر از آن استفاده کنیم.چرخه‌حیات هم یکی از قسمت‌هایی است که باعث شناخت بیشتر ما از یک کامپوننت می‌شود، مثلاً با شناخت چرخه‌حیات اکتیویتی می‌توانیم به راحتی تصمیم بگیریم که در چه زمانی و در چه جایی، چه کاری را در اکتیویتی انجام دهیم.مشکل آنجاست که اغلب برنامه‌نویس‌ها بدون آنکه آشنایی کاملی، مثلا با چرخه‌حیات فرگمنت داشته باشند، از روی یک‌سری نمونه‌کد آماده شروع به کار کردن با آن می‌کنند و بعد از آنکه به اولین مشکل می‌خورند، شروع به بدوبیراه گفتن به اندروید و فرگمنت و... می‌کنند.در ادامه این رشته پست می‌خواهم درباره چرخه‌حیات‌ معمول‌ترین و پراستفاده‌ترین کامپوننت‌های اندروید صحبت کنم. ابتدا از چرخه حیات اکتیویتی‌ها شروع می‌کنیم، در ادامه به چرخه‌حیات فرگمنت‌ها می‌رسیم و در انتها درباره چرخه‌حیات ویو‌ها صحبت می‌کنیم.در پست بعدی درباره چرخه‌حیات اکتیویتی‌ها در اندروید صحبت کرده و از زوایای مختلف نگاهی عمیق به آن می‌کنیم.منتظر نظراتتون گرمتون هستم♥.منابعhttps://developer.android.com/topic/performance/memory-overviewhttps://dzone.com/articles/java-memory-managementhttps://www.journaldev.com/4098/java-heap-space-vs-stack-memory</description>
                <category>Ali Nasrabadi</category>
                <author>Ali Nasrabadi</author>
                <pubDate>Wed, 03 Oct 2018 10:24:30 +0330</pubDate>
            </item>
                    <item>
                <title>تفاوت Serializable و Parcelable</title>
                <link>https://virgool.io/@nasrabadiam/serializable-vs-parcelable-lqmmpsfyfrmp</link>
                <description>اگر کمی اندروید دولوپ کرده باشید، احتمالا این اسم‌ها برایتان آشنا هستند. در این مقاله کمی درباره این دو اینترفیس به ظاهر مشابه صحبت و تفاوت‌های آن‌ها را بررسی می‌کنیم. تشابه‌هاهر دو این اینترفیس‌ها برای خواندن و نوشتن اطلاعات روی دیسک استفاده می‌شوند و به عبارت دیگر مکانیزم ذخیره و بازیابی آبجکت‌ها روی حافظه هستند.در ادامه بیشتر درباره هریک و جزئیاتشان بحث می کنیم. Serializableیک اینترفیس خالی بدون هیچ متدی است و در واقع یک Marker Interface است.برای استفاده از این قابلیت جاوا تنها کاری که لازم است انجام دهیم آن است که کلاس موردنظر Serializable  را ایمپلمنت کند.کلاسی که این اینترفیس را ایمپلمنت می‌کند، از این نوع Serializable خواهد شد و می تواند سریال یا دیسریال شود.در کلاس Person می‌بینیم که این کلاس Serialize را ایمپلمنت کرده است: https://gist.github.com/nasrabadiAM/9783cdea0ac44a01b527d8ec02916d39 و به صورت زیر آبجکت‌هایی از Person را ذخیره و بازیابی می‌کنیم: https://gist.github.com/nasrabadiAM/aeef81257afb98a20fbb0fe2c2442a43 Parcelableاین اینترفیس فقط یک Marker Interface نیست و استفاده از ان هم به راحتی استفاده از Serializable نیست. Parcelable از پکیج‌های اندروید است و به صورت تخصصی برای خواندن و نوشتن اطلاعات نوشته شده است. برای آنکه یک کلاس Parcelable شود، علاوه بر آنکه اینترفیس Parcelable را ایمپلمنت می‌کند باید مقداری کد اضافه‌تر هم داشته باشد.یک کلاس ساده که از این اینترفیس استفاده می‌کند، به صورت زیر است: https://gist.github.com/nasrabadiAM/7d4321b9b4ce0b2ab49d13bc92d7a056 و برای استفاده از آن به صورت زیر عمل می‌کنیم: https://gist.github.com/nasrabadiAM/e37fffc8a08ad9df5081fa39b66b8602 تفاوت‌هااولین و ساده‌ترین تفاوت آن است که Parcelable جزئی از کلاس‌های اندروید (android.os.Parcelable) است ولی Serializable از جاوا (java.io.Serializable).تفاوت بعدی در سرعت و پرفورمنس این دو است، Serializable  جاوا از رفلکشن استفاده می‌کند، برای همین سرعت بسیار پایین‌تری نسبت به Parcelable  دارد. همچنین Serializable جاوا تعداد زیادی آبجکت‌های موقتی تولید می‌کند که کمی برروی garbage collectionجاوا تاثیرگذار است و کار آن را بیشتر میکند. اما Parcelable  بسیار سریعتر است و یکی از دلایل اصلی این پرفورمنس به استفاده نکردن از رفلکشن برمی‌گردد. و البته این‌که Parcelable به خوبی برای این کار بهینه شده است. برای آنکه یک مقیاس از این پرفورمنس داشته باشید، به دیاگرام زیر توجه کنید:  تفاوت بعدی در سادگی استفاده از Serializable نسبت به Parcelable است که نمونه کدهای آن‌ها را در ابتدای همین مقاله دیدیم. این که از هرکدام از این دو در چه مواردی استفاده کنیم، کاملاً بستگی به مورد استفاده شما دارد، اما برای تصمیم‌گیری کارآمدتر، بهتر است این تفاوت‌ها را در ذهن داشته باشید. تا بتوانید براساس نیاز و شرایط مورد مناسب‌تر را انتخاب کنید.اگر دوست داشتید بیشتر درباره Serializableها بدونید، میتونید فصل ۱۱ کتاب EffectiveJava  رو بخونید.این مقاله در اینجا تمام نمی‌شود، با اشتیاق منتظر شنیدن نظراتتون هستم ♥.منابعhttps://android.jlelse.eu/parcelable-vs-serializable-6a2556d51538https://stackoverflow.com/questions/3323074/android-difference-between-parcelable-and-serializable</description>
                <category>Ali Nasrabadi</category>
                <author>Ali Nasrabadi</author>
                <pubDate>Mon, 10 Sep 2018 12:54:41 +0430</pubDate>
            </item>
            </channel>
</rss>