<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد حسینی</title>
        <link>https://virgool.io/feed/@mohosyny</link>
        <description>برنامه نویس اندروید و علاقه مند به تکنولوژی</description>
        <language>fa</language>
        <pubDate>2026-06-07 10:00:45</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/18836/avatar/efL9RI.png?height=120&amp;width=120</url>
            <title>محمد حسینی</title>
            <link>https://virgool.io/@mohosyny</link>
        </image>

                    <item>
                <title>تعویض فیلتر مغز</title>
                <link>https://virgool.io/@mohosyny/%D8%AA%D8%B9%D9%88%DB%8C%D8%B6-%D9%81%DB%8C%D9%84%D8%AA%D8%B1-%D9%85%D8%BA%D8%B2-inwhw3eildpq</link>
                <description>اگه مثل من تو یه دوره‌ای توی قلم‌چی بوده باشین حتما یه دفتر برنامه‌ ریزی آبی رنگ داشتین که برنامه ریزی به سبک قلم‌چی بود.توی  دفتر برنامه‌ ریزی یه مطلبی بود درباره سیستم فعال‌کننده مشبک (Reticular  activating system) که به اختصارRAS گفته میشه. حالا این RAS چی هست و چه  تاثیری رو زندگی ما داره.تعریفی که تو ویکیپدیا شده :قسمتی از دستگاه عصبی مرکزی است که ساختمانی پراکنده و شبکه مانند دارد که از رشته‌های ریز با تعداد فراوانی هسته تشکیل یافته‌است.حالا خودمونیش چی میشه ؟گفته  میشه در هر ثانیه میلیون ها (به طور تقریبی ۴ میلیون ) ورودی به مغز ما  وارد میشه و اگر ضمیر خودآگاه بخواد به این همه ورودی توجه کنه که امکان  پذیر نیست و منفجر میشه.. بخاطر همین ذهن ما (ضمیر ناخودآگاه) یا این سیستم  میگه این همه رو نبین و اونایی که برای شما مهم هستن رو ببین. RAS یه  قسمتی شبکه‌ای مانند توی مغزه که ورودی ها (بینایی ، چشایی و ..) رو فیلتر  می‌کنه. وظیفه RAS مغز فیلتر کردن اطلاعات خاص از بین اطلاعاتی که به ما  میرسن. اطلاعاتی که اکثر اوقات به اونا فکر می کنیم.مثال  معروفش خرید ماشینه. تا حالا شده یه ماشین خاص بخرین (پراید بژ J) بعد که  میرین تو شهر یهو می‌بینین عه چقد اون ماشین خاص زیاد شده! در صورتی که  قبلا اینطوری نبود.یه مدل گوشی جدید خریدین بعد می بینین که دیگران هم گوشی شما رو دارن.یه کفش میخرین بعدش وقتی بیرون میرین دائما کفش هایی از نوع و رنگ کفش خودتون رو می بینید.در  مورد دولوپرها میشه به یادگیری یه زبان ،ابزار یا تکنولوژی جدید اشاره  کرد. مثلا من خودم تازه که میخوام برم سراغ فلاتر، هرجا میرم کلی پست و  مطلب تو شبکه های اجتماعی و جاهای دیگه درباره فلاتر و مزایا و ... به چشمم  میاد. در صورتی که اینا قبلا هم بود و صرفا شبکه های اجتماعی بهم پیشنهاد  ندادن. اما الان RAS ‌ توی مغزم توجه بیشتری به این کلمه داره.این سیستم رو مثل یک توری در نظر بگیرین که یکسری چیزها از اون رد میشه و یکسری چیزها رد نمیشن.یا  مثل تنظیم کردن بادبان های کشتی در نظر بگیرین که از بین چندین جهت و مسیر  وزیدن باد، حرکت کشتی رو به سمت مسیر و هدفی که شما می خواین هدایت  می‌کنن.حالا باهاش میشه چیکار کرد یا چطوری کنترلش کنیم :اگر  فکر کنین که همه چیز در دنیا بده و یا آدم بدشانسی هستین، سیستم فعال  کننده مشبک (RAS) مشغول جمع آوری شواهدی از محیط مبتنی بر بدشانسی شما میشه  و سپس اونا رو در اختیار رایانه ذهن شما قرار میده تا اون هم به روش خودش  به شما ثابت کنه که حق با شماست و واقعا بدشانس هستین و دنیا بده.اگر  هدف‌هامون رو تو ذهن مرور کنیم و به طور مداوم به اون توجه داشته باشیم،  در واقع اولویت ها رو برای مغزمون تعیین کردیم و به ذهنمون گفتیم که از این  به بعد به چه چیزی توجه کنه و اطلاعات رو جطوری پالایش و تصویر کنه. پس به  صورت خلاصه :۱- اهداف و آرزوهای خودتون رو تصور کنین و بعد روی کاغذ بیارین . هر چقدر واضح تر، ملموس تر بهتر ترجیحا با زمان.۲- اون ها رو در معرض دیدتون قرار بدید.۳- هر چند وقت یک بار به اهداف و آرزوهای خودتون فکر کنین. بذارین خودآگاه شما، ناخودآگاه شما رو تعلیم بده.در  آخر نمیگم که وضع موجود خیلی خوبه (مخصوصا تو ایران) و هر روز اخبار خوب و  عالی می‌شنویم و خیلی شادو شنگولیم. اما بازم خیلی از فکرها و احوال و  اخبار رو میتونیم فیلتر کنیم . حداقل کمی حالمون رو بهتر کنیم. مغز و ذهن  ما این توانایی رو داره و به خوبی از عهدش برمیاد.</description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Fri, 17 Jul 2020 18:45:05 +0430</pubDate>
            </item>
                    <item>
                <title>توهم الگوهای موفقیت</title>
                <link>https://virgool.io/@mohosyny/%D8%AA%D9%88%D9%87%D9%85-%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D9%85%D9%88%D9%81%D9%82%DB%8C%D8%AA-igceietm2xlq</link>
                <description>در خلال جنگ جهانی دوم آمریکایی‌ها بمب‌افکن‌هاشون رو‌ که گلوله ضدهوایی می‌خورد بررسی و تصمیم‌ گرفتن نقاطی که بیشتر گلوله می‌خورن رو‌ مقاوم‌تر کنن و‌ زره پوششی نقاطی که کمتر گلوله نمی‌خورن ‌رو سبک‌تر کنناما نتیجه کاملاً برعکس شد و آمار سقوط‌ هواپیماهاشون بالا رفت. دلیل؟ چون اونها داشتن هواپیماهایی رو‌ بررسی‌ می‌کردن که موفق‌ به بازگشت شده بودن نه هواپیماهای سقوط کرده رو. در واقع این هواپیماها چون‌ گلوله به نقاط بخصوصی‌ نخورده بود باعث شده بود سقوط ‌نکنن و‌ اون نقاطی که گلوله خورده بود باعث ‌سقوط ‌نمی‌شد. از اون مقطع، روش‌شون‌ رو‌ تغییر دادن.این پدیده مرتبط با یه نکته آماریه به اسم survivorship bias یا تعصب بقاء یا سوگیری براساس بقاء. از این‌ مفهوم در مورد مسائل زندگی هم استفاده می‌شه. مثلاً ما همیشه نمونه‌‌های موفق رو‌ می‌بینیم ‌مثل بیل گیتس‌ که ترک تحصیل کرده (حالا بماند که تحصیل در هاروارد رو‌ ول‌کرده، نه دبیرستان رو!) اما افراد خیلی بیشتری که ترک تحصیل کردن و به جایی نرسیدن رو‌ نمی‌بینیم چون کسی ‌زندگی ‌اونها رو ‌روایت نمی‌کنه.وقتی می‌خوایم از افراد موفق الگو برداری کنیم، کندوکاو در مورد نقاط قوتی که دارن، مسیری که رفتن یا کارهایی که کردن (مخصوصاً ریسک‌هایی که پذیرفتن یا شانس‌هایی که آوردن) می‌تونه ما رو‌ گمراه کنه. افراد موفق بمب‌افکن‌هایی هستن که تونستن برگردن و‌ اگه از خوان‌های زیادی عبور کردن دلیلش گلوله‌هایی بوده که بهشون اصابت نکرده و مسیرهایی که نرفتن و‌ کارهایی که نکردن؛ نقاط ضعفی که گلوله نخورده.گاهی‌ بد نیست برای موفقیت سراغ کسایی بریم که‌ موفق ‌نشدن: همکلاسی‌های قدیمی که توی‌ مقطعی از زندگی مسیرمون جدا شده اونها هنوز تقریباً همون‌جایی هستن که شروع کردن. ببینیم چه نقاط ضعفی دارن که گلوله خورده، و‌ همچنین: چه نقاط قوتی دارن که باعث‌ موفقیت‌شون نشده.البته موفقیت برای هر کس‌ می‌تونه معنی‌ متفا‌وتی داشته باشه: شهرت، محبوبیت، فالوور بالا، مفید بودن، درآمد ...این متن از فرزاد مهرداد در لیکندین منتشر شده.اینجا میتونین مطالب بیشتری بخونین </description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Mon, 22 Jun 2020 12:27:00 +0430</pubDate>
            </item>
                    <item>
                <title>کنترل فشار در پروژه های نرم افزاری</title>
                <link>https://virgool.io/@mohosyny/%DA%A9%D9%86%D8%AA%D8%B1%D9%84-%D9%81%D8%B4%D8%A7%D8%B1-%D8%AF%D8%B1-%D9%BE%D8%B1%D9%88%DA%98%D9%87-%D9%87%D8%A7%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1%DB%8C-ve4ysxokqhc3</link>
                <description>اسم ددلاین که میاد استرس می‌گیرین؟تصور کنید که مثل روح از بدن خودتون خارج شدین و خودتون رو روی تخت جراحی مشاهده می‌کنین در حالی که یک جراح ، جراحی قلب باز روی شما انجام میده. اون جراح در حال تلاش برای نجات زندگی شماست اما زمان محدوده پس جراح تحت یک ددلاین کار می‌کنه. یک ددلاین واقعی.می‌خواین دکتر چطوری رفتار کنه؟ میخواین آروم و خاطرجمع به نظر برسه؟ میخواین شفاف و دقیق ، مراتب کارِ پشتیبانی خودش رو انجام بده؟ میخواین دونسته های خودش رو دنبال کنه و به انضباط کاری وفادار باشه؟ یا میخواین عرق بریزه و فحش بده؟ میخواین تجهیزات رو بهم بکوبه و پرتاب کنه؟ میخواین مدیریت رو برای اینکه انتظارات غیر واقع بینانه از جراح دارن، سرزنش و مدام درباره زمان شکایت کنه؟ میخواین مانند یک حرفه ای رفتار کنه یا مثل یک توسعه دهنده معمولی؟ توسعه دهنده حرفه ای تحت فشار،  آروم و مصمم هست. با افزایش فشار به دونسته ها و روش هاش وفادار میمونه و میدونه که اونها، بهترین راه برای مواجه شدن با ددلاین‌ها و تعهداتی هستن که بهش فشار میارن.اجتناب از فشار بهترین راه برای آروم موندن هنگام فشار ، دوری کردن از موقعیت هاییه که موجب فشار میشن.(بهترین راه از جلوگیری طلاق ازدواج نکردنه :) ). این اجتناب ممکنه فشار رو کاملا حذف نکنه اما میتونه قدمی موثر برای حداقل کردن  و کوتاه کردن دوره های فشار بالا ، باشه.تعهداتاجتناب از متعهد شدن به ددلاین‌هایی که درباره کامل کردن اونا مطمئن نیستیم ، مهمه. کسب و کار همیشه چنین تعهداتی میخواد ، زیرا اونا میخوان ریسک رو حذف کنن. کاری که ما باید انجام بدیم ، مطمئن شدن از اینه که ریسک اندازه گیری شده و به کسب و کار ارائه بشه ، در نتیجه اونا میتونن درست مدیریت کنن. پذیرش تعهدات غیرواقع بینانه ، این هدف رو خدشه دار میکنه و باعث صدمه خوردن به کسب و کار و خودمون میشه. گاهی اوقات  تعهدات برای ما درست شدن. گاهی اوقات می‌فهمیم که بخش کسب و کار بدون مشورت کردن با ما ، قول هایی به مشتریان داده. زمانی که چنین اتفافی می افته ، وظیفه افتخاری ما اینه که به بخش کسب و کار کمک کنیم تا راهی برای برای انجام دادن اون تعهدات پیدا کنه. با این حال، مجبور نیستیم تعهدات رو بپذیریم. تفاوت این دو تا مهمه . حرفه ای ها همیشه به کسب وکار کمک میکنن تا راهی برای دست یابی به اهدافش پیدا کنه. اما حرفه ای ها  تعهداتی که توی بخش کسب و  کار برای اون‌ها ایجاد شده را قبول نمیکنن. در نهایت ، اگر نتونیم راهی برای براورده کردن وعده های داده شده توسط کسب وکار پیدا کنیم ، افرادی که اون وعده ها را دادن باید مسئولیت این کار رو بپذیرن. گفتنش ساده‌ست ، اما زمانی که کسب و کار شما در حال شکست خوردنه و چک حقوق کامندانتون به خاطر از دست رفتن تعهدات دچار تاخیر شده ، فشار رو  به سادگی احساس میکنین. اما اگر حرفه ای رفتار کرده باشین حداقل میتونین سرتون رو بالا بگیرین و به شکار شغلی جدید برین.تمیز ماندنراه سریع رفتن و مهار کردن ددلاین ها ، تمیز ماندن است. حرفه ای ها مغلوب این وسوسه نمیشن که یه توده آشفته درست کنن ، به این بهونه که میخوان سریع تر حرکت کنن. حرفه ای ها درک میکنن که &lt;&lt;سریع و  کثیف&gt;&gt;  یک ترکیب متناقض است. کثیف همیشه یعنی آهسته! میتونیم با تمیز نگه داشتن سیستم‌ ، طراحی و کدمون تا حد توان ، از فشار اجتناب کنیم. این به اون معنا نیست که ساعت های بی پایان رو مشغول صیغل دادن کد باشیم. در واقع به این معنی هست که ما آشفتگی ها رو تحمل نمی‌کنیم. میدونیم که این اشفتگی ها همواره از سرعت ما کم میکنن و منجر میشن که قرارها رو  ازدست بدیم و تعهدات رو زیر پا بذاریم. در نتیجه ما بهترین  کاری که میتونیم رو انجام میدیم و خروجی خودمون رو تا حد توان ، تمیز نگه می‌داریم.انضباط بحرانیزمانی که خودتون رو تو یه بحران ببینین ، چیزی رو انجام میدین که به اون اعتقاد داشته باشین. اگه تو یک بحران ، از روش های خودتون  پیروی میکنین ، پس واقعا به اون روش ها اعتقاد دارین. از طرف دیگه ، اگه رفتار خودتون رو توی یک بحران تغییر میدین ، پس واقعا به رفتار عادی خودتون اعتقاد ندارین. اگه از روش توسعه آزمون محور (TDD)  در زمان‌های غیر بحرانی پیروی میکنین اما در طی یک بحران ، اون رو ول می‌کنین ، پس واقعا اعتماد ندارین که TDD‌مفیده.اگه در زمان‌های عادی ، کد رو تمیز نگه میدارین اما در یک بحران ، باعث اشفتگی میشین ، پس واقعا باور ندارین که آشفتگی‌ها از سرعت شما کم میکنن. اگه در یک بحران با فردی جفت میشین اما در حالت عادی جفتی (دونفره) کار نمی‌کنین ، پس باور دارین که برنامه نویسی دونفره موثرتر از تک نفره هست. روش‌هایی رو انتخاب کنین که با پیروی از اونا در یک موقعیت بحرانی ، احساس راحتی میکنین. سپس در تموم زمان‌ها از اونا پیروی کنین. پیروی کردن از این روش‌ها ، بهترین راه برای جلوگیری از قرار گرفتن در موقعیت بحرانی است. زمانی که بحران فرا میرسه ، رفتار خودتون رو تغییر ندین. اگه روش های شما بهترین راه برای کارکردن هستن ، پس باید حتی در عمق یک بحران هم ادامه داشته باشن.مدیریت فشارپیشگویی ،تسکین دادن و حذف فشار، همگی خوبن. اما گاهی وقتا، فشار به رغم تمام پیشگیری و نیت‌های خوب شما ، رخ میده . گاهی اوقات پروژه بیشتر از چیزی که همه فکرش رو میکردن ، طول می‌کشه. گاهی اوقات طراحی اولیه اشتباهه و باید دوباره روی اون کار بشه. گاهی اوقات شما یک عضو ارزشمند از گروه یا مشتری رو از دست میدین. گاهی اوقات تعهدی میدین  که نمیتونین بهش عمل کنین . پس چیکار باید کرد؟وحشت نکنید اضطراب خودتون رو مدیریت کنین. بی خوابی های شبونه ، به شما کمک نمی‌کنه که کار رو سریع تر انجام بدین. نشستن  و کج خلقی کردن هم کمکی نخواهد کرد و بدترین کاری که میتونین انجام بدید عجله کردنه!به هر قیمتی ،در برابر این وسوسه مقاومت کنین. عجله کردن ،فقط شما رو به بخشی عمیق تر از گودال فشار هدایت می‌کنه .در عوض از سرعت خودتون کم کنین. کاملا در مورد مسئله فکر کنین . مسیری رو انتخاب کنین که بهترین نتیجه ممکن رو میده و سپس با سرعتی معقول و ثابت ،به طرف اون نتیجه حرکت کنین.ارتباط برقرار کنیداجازه بدین گروه و سرپرست‌تون بدونن که شما در معرض مشکل هستین. بهترین برنامه های خودتون ، برای خلاص شدن از مشکل رو بهشون بگید. از انها بخواین به مسئله ورود کرده و شما رو هدایت کنن. از ایجاد غافلگیری اجتناب کنید. هیچ چیزی ببیشتر از غافل گیری ، مردم رو عصبانی و غیرمنطقی نمی‌کنه . غافلگیری ، فشار رو ده برابر میکنه.به روش های خود اتکا کنیدوقتی شرایط دشوار بشه ، به روش های خودتون اعتماد کنید. علت اینکه شما روش هایی داریم ، اینه که در زمان هایی با فشار بالا ، شما رو هدایت کنن . این زمان‌ها، زمان هایی هستن که باید توجه خاصی به تموم روش هاتون ، داشته باشین. نه اینکه زمان هایی برای پرسش در مورد روش ها یا ترک کردن اونا باشن . به جای اینکه به دنبال ترس وحشت باشین ، دنبال هرچیزیب بگردین که به سریع تر انجام دادن شما کمک کنه، سنجیده تر عمل و خودتون رو وقف پیروی از روش های انتخابیتون کنین. اگر از TDD  پیروی می‌کنین ،حتی بیشتر از حالت عادی ، تست بنویسید. اگر پیرو ریفکتور بی رحمانه (Mericiless refactor) ، حتی بیشتر ریفکتور کنید. اگه توابع خودتون رو کوچیک نگه میدارین، در شرایط دشوار ، حتی اونا رو کوچیک‌تر کنید. تنها راه برای عبور از کوره فشار ، اتکا به چیزی هست که از قبل میدونین کار میکنه، یعنی روش هاتون.کمک بگیریدجفت بشین! زمانی که فشار زیاده ، یک شریک پیدا کنید که مشتاق برنامه نویسی دونفره(جفتی) با شما باشه. در این صورت ، کار رو سریع تر و با نقص های کمتر انجام میدید. یار شما کمک میکنه که به روش هاتون پایبند بمونین و شما رو از وحشت‌زدگی درمیاره. همچنین چیرهایی رو در نظر میگیره که شما فراموش می‌کنین. ایده های مفید به شما میده و زمانی که تمرکز خودتون رو ازدست دادین ، کسلی رو از شما دور میکنه.به همین ترتیب ، زمانی که کسی رو میبینین که تحت فشاره ، پیشنهاد جفت شدن رو به اون بدین. به دیگران کمک کنید از چاله ای که توش هستن ، خارج بشن.نتیجه گیریترفند مدیریت فشار اینه که تا زمانی که میتونین باید از ایجاد اون جلوگیری کنیم و زمانی که رخ داد باید اون رو تحمل کنیم . با مدیریت کردن تعهدات ، پیروی از روش‌هامون  و تمیز نگه داشتن ، از فشار دوری می‌کنیم.همچنین با آروم موندن ، ارتباط برقرار کردن ، پیروی از روش‌های خودمون و کمک گرفتن ، راحت تر تحملش می‌کنیم.این مطلب برگرفته از کتاب کدنویس تمیز از عموباب است.اینجا میتونین مطالب بیشتری بخونین در پایان اگه نظر یا پیشنهادی دارین خوشحال میشم در زیر این پست بخونم :)</description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Tue, 16 Jun 2020 16:30:48 +0430</pubDate>
            </item>
                    <item>
                <title>مفهوم مهاجرت در کتابخانه‌‌ی Room _ بخش دوم</title>
                <link>https://virgool.io/@mohosyny/%D9%85%D9%81%D9%87%D9%88%D9%85-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AA-%D8%AF%D8%B1-%DA%A9%D8%AA%D8%A7%D8%A8%D8%AE%D8%A7%D9%86%D9%87%DB%8C-room-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88%D9%85-btvlk4cnljae</link>
                <description>کلید رو فشار بدهبخش اول این مقاله رو میتونین اینجا بخونین مهاجرت با تغییرات کوچیک دیاگرام (schema) بیاین کلاس User رو تغییر بدیم و یه ستون دیگه به جدول  user اضافه کنیم به اسم : last_update  .    در کلاس UsersDatabaseنیاز داریم تا کارهای زیر رو انجام بدیم : ورژن رو به 3 افزایش بدیم :@Database(entities = {User.class}, version = 3)
public abstract class UsersDatabase extends RoomDatabase2. یک مهاجرت برای انتقال ورژن 2 به 3 اضافه کنیم :static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL(&amp;quotALTER TABLE users &amp;quot
                + &amp;quot ADD COLUMN last_update INTEGER&amp;quot);
    }
};3. مهاجرت رو به بیلدر دیتابیس روم اضافه کنیم :database = Room.databaseBuilder(context.getApplicationContext(),
        UsersDatabase.class, &amp;quotSample.db&amp;quot)
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
        .build(); وقتی اپ رو اجرا میکنیم مراحل زیر اتفاق می افتن:قدم اول : تلاش برای اپگریت از ورژن 2 (ورژنی که روی دستگاه هست) به ورژن 3راه اندازی مهاجرت و اصلاح جدول ٬ در نهایت حفظ داده‌های کاربر ✅اپدیت هش هویتی در جدول room_master_table ✅قدم دوم : تلاش برای باز کردن دیتابیسهش هویتی ورژن کنونی با هش هویتی که در  room_master_tableموجوده ٬ یکی هستن.✅مهاجرت با تغییرات پیچیده دیاگرام (schema) دستور  ALTER TABLE در SQLite  کاملا محدود است. برای مثال تغییر id کاربر از int به String نیازمند چند مرحله هست :ساخت یه جدول موقت با دیاگرام جدیدکپی دیتا از جدول users به جدول موقتپاک کردن جدول usersتغییر نام جدول موقت به usersبا Room  ٬ پیاده سازی مهاجرت به شکل زیر هست : static final Migration MIGRATION_3_4 = new Migration(3, 4) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        // Create the new table
        database.execSQL(
                &amp;quotCREATE TABLE users_new (userid TEXT, username TEXT, last_update INTEGER, PRIMARY KEY(userid))&amp;quot);// Copy the data
        database.execSQL(
                &amp;quotINSERT INTO users_new (userid, username, last_update) SELECT userid, username, last_update FROM users&amp;quot);// Remove the old table
        database.execSQL(&amp;quotDROP TABLE users&amp;quot);// Change the table name to the correct one
        database.execSQL(&amp;quotALTER TABLE users_new RENAME TO users&amp;quot);
    }
};افزایش چنتایی  ورژن دیتابیسچه حالتی پیش میاد ٬اگه کاربران شما یه نسخه قدیمی از اپ داشته باشن که در اون ورژن دیتابیس 1 باشه و شما بخواین ورژن اون رو به 4 افزایش بدین ؟تا الان ما مهاجرت های زیر رو تعریف کردیم :ورژن 1 به 2  ٬ ورژن 2 به 3 ٬ ورژن 3 به 4پس Room ‌همه مهاجرت ها رو یکی پس از دیگری اجرا میکنه.اما خبر خوب اینه که Room  میتونه افزایش چنتایی ورژن رو هندل کنه. ما میتونیم یه مهاجرت تعریف کنیم که در یک قدم از ورژن 1 مستقیم به 4 افزایش پیدا میکنه و طبیعتا روند کار سریع تر میشه.static final Migration MIGRATION_1_4 = new Migration(1, 4) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        // Create the new table
        database.execSQL(
                &amp;quotCREATE TABLE users_new (userid TEXT, username TEXT, last_update INTEGER, PRIMARY KEY(userid))&amp;quot);
        
        // Copy the data
        database.execSQL(
                &amp;quotINSERT INTO users_new (userid, username, last_update) SELECT userid, username, last_update FROM users&amp;quot);// Remove the old table
        database.execSQL(&amp;quotDROP TABLE users&amp;quot);// Change the table name to the correct one
        database.execSQL(&amp;quotALTER TABLE users_new RENAME TO users&amp;quot);
    }
}; در قدم بعدی فقط اون رو به لیست مهاجرت ها اضافه می‌کنیم :database = Room.databaseBuilder(context.getApplicationContext(),
        UsersDatabase.class, &amp;quotSample.db&amp;quot)
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_1_4)
        .build();حواستون باشه که برخلاف  کوئری‌های DAO ٬ کوئری‌هایی که توی پیاده سازی Migration.migrate  نوشتین ٬ در زمان اجرا کامپایل نمیشن. مطمئن بشین که که حتما برای مهاجرت هاتون تست نوشتین.کد رو نشون بدهشما میتونین پیاده سازی رو  اینجا ببینین. برای سهولت مقایسه هر ورژن دیتابیس در flavor ‌خودش پیاده سازی شده :1. پیاده سازی با sqlite _  با استفاده از SQLiteOpenHelper و اینترفیس های رایج sqlite2. پیاده سازی با Room _ پیاده سازی را با  Room  جایگزین کرده و مهاجرت برای ورژن 2 فراهم میکنه.3. پیاده سازی با Room 2 _   آپدیت دیتابیس به دیاگرام جدید ٬ ورژن 34. پیاده سازی با Room 3 _ آپدیت دیتابیس به ورژن 4. مسیر مهاجرت ها برای اپدیت از ورژن 2 به 3 ٬ ورژن 3 به 4  و  ورژن 1 به 4 پیاده سازی شده .خلاصهدیاگرامتون عوض شده؟ فقط کافیه ورژن دیتابیس رو افزایش بدین و یه مهاجرت(Migration) رو پیاده سازی کنین. در نتیجه مطمئن میشین که اپ کرش نمیکنه و دیتا های کاربران از بین نمیره. به راحتی فشار دادن یه دکمه!این مطلب ترجمه مقاله ای در مدیوم هست که اینجا میتونین بخونین.همچنین میتونین مطلب های بیشتر رو در سایت من بخونیندر پایان اگه نظر یا پیشنهادی دارین خوشحال میشم در زیر این پست بخونم :)</description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Thu, 11 Jun 2020 00:05:55 +0430</pubDate>
            </item>
                    <item>
                <title>مفهوم مهاجرت(migration) در کتابخانه Room</title>
                <link>https://virgool.io/@mohosyny/%D9%85%D9%81%D9%87%D9%88%D9%85-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AAmigration-%D8%AF%D8%B1-%DA%A9%D8%AA%D8%A7%D8%A8%D8%AE%D8%A7%D9%86%D9%87-room-fwavpyrqxtuq</link>
                <description>کلید رو فشار بدهقسمت اولمهاجرت (انتقال) دیتابیس همیشه باعث ترس من میشد جوری که انگار دارم بمب خنثی میکنم.با یه حرکت اشتباه انگار اپ من تو دستای کاربر منفجر می‌شد. اگه از کتابخونه Room برای کنترل عملیات دیتابیس‌تون استفاده میکنین مهاجرت به آسونی فشردن یک کلید میمونه.هنگام استفاده از Room اگر دیاگرامِ دیتابیس(database schema) رو عوض کنین ولی ورژن رو اپگرید نکنین اپ کرش میکنه اگرهم ورژن رو اپگریت کنین اما هیچ مهاجرتی رو فراهم نکنین یا اپ کرش میکنه یا جدول های دیتابیس پاک میشن و کاربرانتون تمام داده هاشون رو از دست میدن. با فکر کردن به اینکه چطوری مهاجرت روم رو پیاده سازی کنین وقتتون رو هدر ندین به جاش ساختار داخلی روم رو درک کنین تا با اعتماد به نفس دیتابیستون رو اپدیت کنین.مهاجرت دیتابیس بدون نقابآنچه SQLite API  انجام میدهدیتابیس های SQLite تغییرات دیاگرام رو با کمک ورژن بندی دیتایس کنترل میکنن. به طور خلاصه هربار که دیاگرام خودتون رو با اضافه کردن ٬ حذف یا تغییرات جدول ها ٬  تغییر میدین شما ورژن دیتابیس رو افزایش میدین و  متد SQLiteOpenHelper.onUpgrade رو اپدیت فراخونی می‌کنین. به این ترتیب به SQLite  میگین که برای رفتن از یه ورژن قدیمی به ورژن جدید به چه چیزی نیاز داره.همچنین این اولین فراخونی هست که اجرا میشه وقتی که اپ شما با دیتابیس شروع میکنه به تعاملاس کیو ابتدا سغی میکن که اپگریت های ورزن رو هندل کنه و تنها اون موقع است که دیتابیس رو اجرا میکنه.آنچه که روم انجام میده روم یه لایه انتزاعی(Abstrack) فراهم میکنه تا کار مهاجرت SQLite  رو در قالب کلاس Migrationآسون کنه.کلاس Migration کارهایی که برای مهاجرت از یک ورژن به ورژن دیگه لازمه رو مشخص میکنه.روم از پیاده سازی شخصی خودش از SQLiteOpenHelper استفاده میکنه و در متد onUpgrade مهاجرت هایی که شما مشخص کردین رو راه اندازی میکنه.این ها اتفاقاتی است که وقتی برای بار اول به دیتایس دسترسی پیدا میکنین :1. دیتابیس روم ساخته شده2. متد  SQLiteOpenHelper.onUpgrade فراخونی میشه و Room مهاجرت رو راه اندازی میکنه3. دیتابیس باز میشهاگه شما مهاجرتی تعریف نکرده باشین اما ورژن دیتابیس رو بالا ببرین بسته به موقعیت هایی که در زیر در نظر گرفتیم ممکنه اپ کرش کنه یا داده ها پاک بشه :یک نقش مهم در داخل مهاجرت رو یک  identity hash String بازی میکنه که Room از اون برای یکتا سازی هویت هر ورژن دیتابیس استفاده میکنه. این هش هویتی(identity hash) برای ورژن کنونی در جدول پیکربندی در دیتابیس شما نگهداری میشه که روم اون رو مدیریت میکنه. بنابراین تعجب نکنین اگه یه وقت جدول room_master_table توی دیتابیس دیدین.یه مثال ساده : ما یک جدول users داریم با دو ستون : یک id ازنوع int که کلید اصلی ما هم هست یک username از نوع Stringجدول  users بخشی از دیتابیس ما با ورژن 1 که با استفاده از SQLiteDatabase API پیاده سازی شده است.درنظر می‌گیریم که کاربران ما در حال حاضر از این ورژن استفاده میکنن و شما میخواین از Room استفاده کنید. بیاین ببینیم که Room چطوری چند سناریو رو هندل میکنه :مهاجرت از SQLite API به Room بیاین فرض کنیم که همه کلاس های Room رو ساختیم و تمرکزمون رو میذاریم روی کلاس UsersDatabaseکه از RoomDatabase اکستند میشه :@Database(entities = {User.class}, version = 1)
public abstract class UsersDatabase extends RoomDatabaseسناریو 1 : ورژن دیتابیس رو تغییر نمی‌دیم ــ اپ کرش می‌کنهاگر ورژن دیتابیس رو بدون تغییر نگه داشته باشیم Room در بک‌گراند کارهای زیر رو انجام میده :گام اول : تلاش برای باز کردن دیتابیسهویت دیتابیس رو با مقایسه هش هویت ورژن کنونی با ورژنی که درجدول room_master_table ذخیره شده چک میکنه. اما از اونجا که هیچ هش هویتی‌ای ذخیره نشده اپ با خطای زیر کرش میکنه :IllegalStateException ❌java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you’ve changed schema but forgot to update the version number. You can simply fix this by increasing the version number.اگر شما دیاگرام دیتابیس رو تغییر بدین اما ورژن رو اپدیت نکنین روم همیشه یه خطای IllegalStateException  نشون میده.بیاین خطا رو جدی بگیریم  و ورژن دیتابیس رو افزایش بدیم :@Database(entities = {User.class}, version = 2)
public abstract class UsersDatabase extends RoomDatabaseسناریو 2 : ورژن بالا میره اما هیج مهاجرتی فراهم نشده ــ اپ کرش می‌کنهتو این حالت اگه دوباره اپ رو اجرا کنیم روم کارهای زیر رو انجام میده :گام اول : تلاش برای اپگریت ورژن 1( که روی دستگاه نصب شده) به ورژن 2 از اونجایی که هیچ مهاجرتی وجود نداره اپ با خطای IllegalStateException کرش میکنه❌ java.lang.IllegalStateException: A migration from 1 to 2 is necessary. Please provide a Migration in the builder or call fallbackToDestructiveMigration in the builder in which case Room will re-create all of the tables.اگه مهاجرتی فراهم نکرده باشین روم خطای IllegalStateException رو نشون میده(پرتاپ می‌کنه).سناریو 3 : ورژن بالامیره و متد fallbackToDestructiveMigration فعال شده ـــ دیتابیس پاک میشهاگه نمیخواین هیچ مهاجرتی فراهم کنین و حتما میخواین که وقتی ورژن دیتابیس بالا میره دیتابیستون پاک بشه متد fallbackToDestructiveMigration رو در بیلدر دیتابیس فراخونی کنین :database = Room.databaseBuilder(context.getApplicationContext(),
                        UsersDatabase.class, &amp;quotSample.db&amp;quot)
                .fallbackToDestructiveMigration()
                .build();حالا وقتی شما برنامه رو دوباره اجرا میکنین روم کارهای زیر رو انجام میده :گام اول : تلاش برای اپگریت ورژن1 (که روی دستگاه نصب شده) به ورژن 2 از اونجایی که هیچ مهاجرتی وجود نداره و متد fallbackToDestructiveMigration رو فراخونی کردیم جدول ها پاک شدن و identity_hash  در جدول نوشته شد.گام دوم‌ : تلاش برای باز کردن دیتابیسهش هویتی ورژن کنونی و هش هویتی‌ای که در جدول room_master_table ذخیره شده یکی هستن✅الان دیگه اپ ما کرش نمیکنه اما همه داده ها رو ازدست دادیم. بنابراین از قبل مطمئن باشین که این روش رو میخواین انجام بدین.سناریو چهارم : ورژن بالا رفته و مهاجرت هم فراهم شده ـــ داده ها حفظ میشن.برای حفظ داده های کاربران ما باید یک مهاجرت پیاده سازی کنیم. از اونجایی که دیاگرام تغییری نمیکنه فقط نیاز داریم تا یک مهاجرت خالی رو پیاده سازی کنیم و به Room بگیم که ازش استفاده کنه.@Database(entities = {User.class}, version = 2)
public abstract class UsersDatabase extends RoomDatabase {…static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        // Since we didn&#039;t alter the table, there&#039;s nothing else to do here.
    }
};…database =  Room.databaseBuilder(context.getApplicationContext(),
        UsersDatabase.class, &amp;quotSample.db&amp;quot)
        .addMigrations(MIGRATION_1_2)
        .build();حالا وقتی اپ رو اجرا میکنیم روم کارهای زیر رو انجام میده :گام اول : تلاش برای اپگریت ورژن 1(که روی دستگاه نصب شده) به ورژن 2 راه اندازی مهاجرت خالی✅ اپدیت هش هویتی در جدول room_master_table ✅گام دوم : تلاش برای باز کردن دیتابیسهش هویتی ورژن کنونی با هش هویتی‌ای که در جدول room_master_table ذخیره شده یکی هستن✅بنابراین اپ ما باز میشه و داده های کاربر هم مهاجرت کردن(منتقل شدن) به ورژن جدید :) ?پایان بخش اولادامه دارد..اگه این مطلب رو دوست داشتین میتونین با دیگران به اشتراک بذارین :)</description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Sun, 10 May 2020 21:29:22 +0430</pubDate>
            </item>
                    <item>
                <title>کاهش سایز apk هنگام استفاده از کتابخانه های بومی(Native)</title>
                <link>https://virgool.io/MobileLab/%DA%A9%D8%A7%D9%87%D8%B4-%D8%B3%D8%A7%DB%8C%D8%B2-%D8%A7%D9%BE%D9%84%DB%8C%DA%A9%DB%8C%D8%B4%D9%86-wypeuqzxtmiu</link>
                <description>اگه تا حالا سعی کرده باشین که حجم apk ‌رو کاهش بدین حتما به تفکیک apk  بر اساس تراکم صفحه نمایش و واسط باینری اپلیکیشن (Application binary interface  به اختصار ABI ) فکر کردین.در این پست یاد می گیریم که ABI  چیه ‍‍‍‍‍‍‍‍‍٬ تفکیک ABI  چه مشکلاتی داره و راه‌های جایگزین برای جلوگیری از این مشکلات چیا هستن.اگه اولین باره که اسم تفکیک ABI  رو می‌شنوین ابتدا  این پست  رو بخونین (حواستون باشه سایتش فیلتره).   یک ABI ‌چیست  و چگونه کار می‌کند؟در واقع  ABI  کاملا دقیق و شفاف مشخص می‌کنه که چطور کد ماشین یک اپلیکیشن بتونه در زمان اجرا (runtime)  با سیستم تعامل کنه. در نتیجه باید برای معماری هر پردازنده ای که اپلیکیشن باید باهاش کار کنه یک ABI مشخص کنیم.برای نمونه اندروید از ABI  های زیر پشتیبانی می‌کنه :mips, mips64, X86, X86–64, arm64-v8a, armeabi, armeabi-v7a به طور راحت تر اینکه : دستگاه های اندرویدی چیست و پردازنده و cpu  های مختلفی دارن. اپلیکیشن ها بر اساس معماری cpu دستگاهی که روش نصب شدن از ورژن های مختلف کتابخونه‌ها استفاده می‌کنن.به عنوان مثال پیکسل گوگل از ورژن   arm64-v8a  کتابخونه ها و نکسوس 5 از ورژن  armeabi-v7a کتابخونه ها استفاده می‌کنه.درون هر کتابخونه ای که به اپلیکیشن‌تون اضافه می‌کنین یک فایل با پسوند  so. وجود داره که از همه معماری های cpu  پشتیبانی می‌کنه.این فایل باعث میشه که به صورت چشمگیری سایز apk ‌ زیاد بشه ٬ در حالی که  دستگاه مورد نظر (گوشی ٬ ساعت و.. اندرویدی)  فقط یک ورژن از کتابخونه رو لازم داره.یک مثال برای فهمیدن ABIیک اپ ساده شامل یک اکتیویتی و آیکون ها ایجاد کردیم.آنالیز apkحالا یک کتابخونه شامل ABI  های مختلف به پروژه اضافه می‌کنیم. در این مطلب از کتابخونه Realm ‌استفاده کردیم.این بحث مختص کتابخونه Realm  نیست و همه کتابخونه های نیتیو اندروید اینطوری رفتار می‌کنند.جزییات apk  بعد از اضافه کردن کتابخونه Realm               بهله! سایز apk از 74KB  رسید به 5MB  !    ببینیم چی اتفاقی افتاده!توزیع Realm برای معماری های مختلف CPU در واقع کتابخونه Realm  فایل so.  برای پشتیبانی از 5 معماری پردازنده اضافه کرده که شامل این ها هست : mips, X86, X86–64, armeabi-v7a, and arm64-v8a این باعث شده که سایز apk به  4.8MB برسه . حدود 130KB بقیه به سایز dex اضافه شده.اگه این اپ رو تو مارکت منتشر کنین پیکسل گوگل این apk  با  حجم 5MB رو نصب می‌کنه در صورتی که فقط به یک ورژن از کتابخونه Realm (arm64-v8a) نیاز داره که 947KB حجمشه! هزینه‌ی (سرریز) زیادیه! همچنین ممکنه که  با ورژن V7 کتابخونه Realm  هم به خوبی کار کنه که تنها 771KB حجم داره(این رو به زودی می‌فهمیم).تفکیک بر اساس ABI  چگونه از مشکل جلوگیری می‌کنه؟اساسا با تفکیک ABI  به بیلد سیستم گریدل می‌گیم که برای هر معماری متفاوت cpu  یک apk  جداگونه بسازه که داخلش ورژن کتابخونه مربوط به همون معماری باشه. خروجی فایل build.gradle مربوط به ماژول اپ با تفکیک ABI :android {
    splits {
        // Configures multiple APKs based on ABI.
        abi {
            // Enables building multiple APKs per ABI.
            enable true
            // By default all ABIs are included, so use reset() and include
            // to specify that we only want APKs for x86, armeabi-v7a, and mips.

            // Resets the list of ABIs that Gradle should create APKs for to none.
            reset()
            // Specifies a list of ABIs that Gradle should create APKs for.
            include &amp;quotmips&amp;quot, &amp;quotx86&amp;quot, &amp;quotx86_64&amp;quot, &amp;quotarm64-v8a&amp;quot, &amp;quotarmeabi-v7a&amp;quot
            // Specifies that we do not want to generate a universal APK
            // that includes all ABIs.
            universalApk false
        }
    }
}  اگه این تنظیمات رو به اپ اضافه کنید ورژن‌های مختلفی از apk ‌رو برای معماری های متفاوت خروجی می‌گیره:خروجی های مختلف apk  ‌بعد از فعال کردن تفکیک کننده ABI     عالیه! از 74KB رسیدیم به 5MB و دوباره برگشتیم به 1.3MB  اما...با اینکه الان یک ورژن مناسب از apk  (که فقط شامل فایل های ضروری است) داریم ٬ اما این 5 تا apk  همه خروجی یک اپلیکیشن هستن و هنوز بر اساس تراکم صفحه نمایش تفکیک نشدن.(خود تراکم بسته به کانفیگ دستگاه ٬ apk های مختلفی برای xhdpi ٬ xxhdpi و xxxhdpi  تولید می‌کنه در حالی که این نوع تفکیک کردن خیلی بهتر از بهینه کردن کتابخونه های بومیه).معمولا از فایل apk  حداقل سه نسخه‌ی hdpi و xhdpi و xxhdpi خروجی می‌گیریم. در نتیجه الان 15 نسخه از apk  برای انتشار در مارکت داریم. فرض کنیم هرماه یک اپدیت برای اپ منتشر میشه بنابراین باید 15 apk رو نگهداری کنیم و تصور کنین که مشتری/شرکت به شما بگه قبل از انتشار از درست کار کردن همه apk ها مطمئن بشین و همه رو تست کنین!!!      هنوز یک مشکل بزرگتر از این نگهداری طاقت فرسا وجود داره :(در بازارهای نوظهور مثل هند (ایران هم کاملا صدق میکنه) که اینترنت همراه یا وای فای مثل کشورهای توسعه یافته ارزون نیست ٬ کاربران اپ رو به وسیله بلوتوث یا برنامه های shareit , xender و ... برای هم میفرستن و به صورت دستی نصب میکنن.بحث درمورد اشتراک اپ هاحالا اگه تفکیک ABI  انجام داده باشین یک کاربر که گوشیش با معماری ARM کار می‌کنه اپ رو به یک کاربر دیگه با گوشی معماری x86 بفرسته به طور معمولی برنامه کرش می‌کنه. هیچکس نمیخواد که چپ و راست برنامش کرش کنه.                    وقتشه که راه حل رو پیدا کنیمیه راه وجود داره که میتونیم از مشکل بالا جلوگیری کنیم و اون استفاده از NDK abiFilters است.تنظیمات مربوط به تفکیک ABI ‌رو پاک کنید و کد زیر رو به فایل build.gradle ‌سطح اپ اضافه کنید :android {   
 defaultConfig {    
        applicationId &amp;quotcom.android.abi.myapplication&amp;quot      
         minSdkVersion 17  
            targetSdkVersion 25  
                                   ndk {
                                                 abiFilters &amp;quotarmeabi-v7a&amp;quot, &amp;quotx86&amp;quot   
                                            }   
                             }   
                 }کاری که این گزینه انجام میده  اینه که فقط کتابخونه‌ی  معماری های مختلف رو که توی abiFilters نام برده شده رو نگه میداره. حالا فایل 5مگابایتی ما رسید به 2MB (اصلا بد نیست)  با این کار میتونیم از از ساختن 5  apk یک مگابایتی یا یک apk پنج مگابایتی جلوگیری کنیم.فایل apk با کتابخونه های &#039;x86&#039; و &#039;armeabi-v7a&#039; چی شد؟!! من تازه گفتم که هرگونه تغییری در ABI  ممکنه  در سمت کاربر باعث نتایجی بشه که انتظار نداریم اما الان پیشنهاد میکنم که کاملا کورکورانه ABI هارو پاک کنید!برای فهم این موضوع باید وارد جزییات هر معماری بشیم.معماری هاجزییات مربوط به معماری های cpuاگه هنوز در مورد پاک کردن این کتتابخونه های مطمئن نیستین بذارین یه مثال بزنم که جرأت انجام این کارو رو میده. یه کنکاشی توی apk  یونیورسال گوگل مپ v9.55.1 میندازیم :MinSDK: Android 4.3 (Jelly Bean MR2, API 18)با اینکه گوگل مپ بر اساس ABI  و تراکم صفحه نمایش تفکیک میشه (گوگل مپ برای هر انتشار 17 apk  مختلف داره) هنوز apk ‌یونیورسالش فقط از معماری های arm64-v8a و armeabi-v7a و X86 و X86–64 پشتیبانی می‌کنه.بنابراین باید تصمیم بگیرید که یا  از کتابخونه های 64 بیتی پشتیبانی کنین که حجم برنامه زیاد میشه یا معیارتون کارآمد وبهینه بودن (performance) برنامتون باشه که در این صورت بدون هیچ درنگی باید mipsو  mips-64 و armeabi رو پاک کنید.جزییات مربوط به هر معماریarmeabi, armeabi-v7a, and arm64-v8aمعماری armeabi : یک معماری قدیمی  مبتنی بر معماری ARM است. از اندروید 4.4  CDD (تعیین سازگاری) اکیدا توصیه کرده که از ARMv7  استفاده بشه. ( خوندن مستندات CDD )اما CDD ویژگی هایی هستن که گوگل برای سازندگان دستگاه های اندرویدی (هر نسخه ای) مشخص کرده که هر دستگاه اندرویدی برای انتشار با مجوز گوگل باید حداقل نیازمندی هایی رو داشته باشه .بیشتر تولیدکنندگان دستگاه های اندرویدی قبل از اندروید 4.4 به معماری armV7  مهاجرت کردن. بنابراین الان با خیال راحت می‌تونیم از armeabi ‌چشم‌پوشی کنیم.معماری armeabi-v7a :این معماری ٬ رایج ترین معماری در درسترس است و بیشترین پشتیبانی رو برای همه اپلیکیشن ها دارد. 32 بیتی و پشتیبانی از :ARM Cortex-A5, ARM Cortex-A7, ARM Cortex-A8, ARM Cortex-A9, ARM Cortex-A12, ARM Cortex-A15, ARM Cortex-A17معماری  arm64-v8a :  نسل بعدی معماری 64 بیتی ARM ‌است و تقریبا همه گوشی های پرچم‌دار از این معماری استفاده می‌کنند.از نکسوس  5x تا نکسوس 6p و پیکسل گوگل از چیپست های 64 بیتی ARM استفاده می‌کنند.64 بیتی و پیشتیبانی از :ARM Cortex-A35, ARM Cortex-A53, ARM Cortex-A57, ARM Cortex-A72, ARM Cortex-A73استفاده از این ABI ‌اختیاری است چون دستگاه‌های اندرویدی به جاش میتونن از armeabi-v7a استفاده کنند.استفاده از ورژن 32 بیتی کتابخونه های بومی روی پردازنده 64 بیتی مقدار ناچیزی در کاهش کارایی تاثیر داره اما این موضوع رو باید درنظر بگیریم که با انجام این کار می‌تونیم حدود 1MB از سایز apk  کم کنیم.اگه کتابخونه ای که استفاده می‌کنید جزو بخش اصلی برنامتون باشه و میخواین کاربر در گوشی های پرچمدار بهترین تجربه استفاده رو داشته باشه در این صورت بهتره که از این  ABI (arm64-v8a ) استفاده کنید اما در بیشتر اپلیکیشن ها ٬ این ABI  می‌تونه حذف بشه( تا وقتی که متوجه بشیم بیشتر کاربرا گوشی گوشی پرچمدار دارن).معماری x86 :دستگاه های مبتنی بر پردازنده های اینتل ٬ asus zenphone2  معروف ترین تلفن به همراه تعدادی زیادی از  تلفن های لنوو از این معماری پشتیبانی می‌کنند.معماری x86-64 : هیچ دستگاه اندرویدی با پردازنده های 64بیتی اینتل در بازار نیست حتی اگه تعداد کمی هم وجود داشته باشن به خوبی از ورژن 32بیتی کتابخونه ها پشتیبانی می‌کنند پس میشه به حساب نیاورد.معماری های mips and mips64 : همچنین هیچ دستگاه اندرویدی با معماری MIPS   در بازار وجود نداره. فکر میکنم یک دستگاه در سال 2016 قرار بود ساخته بشه اما هیچ اطلاعات دیگه ای جز این مقاله  و این رشته پیدا نکردم.(حواستون به فیلتر باشه)اگه تصمیم گرفتین که از این روش ها و فیلتر های ABI استفاده کنین موقع انتشار اپلیکیشن در کنسول گوگل پلی (کافه بازار یا مارکت های اندرویدی رو نمیدونم ) مثل عکس زیر به هشدار برمی‌خورین که جای نگرانی نیست فقط اطلاعاتی  درباره تغییرات ایجاد شده است. کنسول گوگل پلی هنگام انتشار اپلیکیشن دارای فیلتر های ABIخب! منتظر چی هستین؟ امتحان کنین :) این مطلب ترجمه مقاله ای در مدیوم هست که در مستندات رسمی Realm به این مقاله ارجاع داده شده است.در پایان اگه نظر یا پیشنهادی دارین خوشحال میشم در زیر این پست بخونم :)برروزرسانی  :همونطور که آقای نجفی در کامنت ها گفتن : از آگوست 2019 ، گوگل پلی پشتیبانی از arm64-v8a رو اجباری کرده. این هم لینک توضیحات مربوطه: https://developer.android.com/distribute/best-practices/develop/64-bit ضمنا متاسفانه کافه بازار از همچین چیزی پشتیبانی نمی کنه. البته چون در  کافه بازار arm64-v8a اجباری نیست، میشه فقط دو معماری armeabi-v7a و x86  رو قرار داد. پس حجم اپ خیلی زیاد نخواهد بود.پس حواستون باشه :)</description>
                <category>محمد حسینی</category>
                <author>محمد حسینی</author>
                <pubDate>Sun, 04 Aug 2019 22:27:45 +0430</pubDate>
            </item>
            </channel>
</rss>