- Последний пост
- 1 авг.
- Последнее чтение
- 13 авг.
- Постов за неделю
- 0
- Всего постов
- 20
- Тип
- открытый
- Язык
- персидский
- В каталоге с
- 13 авг.
- 1/24сутки в ленте
- 150
- 1/48двое суток
- 171
- 1/72трое суток
- 185
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
یکی از رو مخ ترین قوانین گوگل پلی برای اکانت های شخصی (نه سازمانی) اینه که باید ۱۲ تا تستر معرفی کنید و تستر ها ۱۴ روز اپ رو روی گوشیشون نصب داشته باشن تا گوگل مجوز پابلیش رو بهتون بده. من خودم چون ۱۲ نفر نتونستم پیدا کنم (چون ماشالا اکثرا آیفون دارن) از یه راه حل دیگه استفاده کردم. اپ swap-test تو گوگل پلی رو نصب کردم و داخلش اپم رو تعریف کردم https://play.google.com/store/apps/details?id=com.swaptest.swaptest_app&hl=en-US&v3=true مدل کارش اینه که با ۱۲ نفر دیگه پارتنر میشید و اون ها اپ شما رو به عنوان تستر نصب میکنن و شما هم اپ اون هارو بعد برای اثبات کار هر روز یه اسکرین شات از گوشیتون میگیرید و برای هم دیگه میفرستید تا اثبات کنید اپ رو پاک نکردید.(خود اپ اینو به عنوان daily task بهتون نشون میده)
من دارم اپ iOS مون رو که با cmp نوشته شده رو توی اپ استور منتشر میکنم. به مرور تجربههایی که باهاش دارم مواجه میشم رو براتون میگم حالا امروز درگیر یه تسک جالب شدم همونطور که میدونید اپ استور قبل از اینکه اپ رو اصلا بخواد دست عامل انسانی برای تست برسونه یه سری ربات دارن که دو تا تست رو انجام میده static-analyze و dynamic-analyze تو استاتیک، ربات توی میزان سورس کدی که از اپتون در دسترسشه میگرده و یه سری موارد رو که برخلاف قوانینش هست پیدا میکنه. مثلاً اینکه تو کدتون اگر داشته باشه Persian یا Iran (برای نام توابع. متغیر ها و ...) ربات حساس میشه. توی داینامیک یه سری تست های دیگه انجام میشه مثل اینکه وقتی اپ ران هست داره به کجاها ریکوست میزنه چه چیزهایی میفرسته و چه چیزهایی لود میکنه خب این جا هم مثلا اگر ریکوست بره به سمت .ir ریجکت میشین. اما حالا تسک جالبم امروز این بود که حتی متادیتای فونتهای اپ رو هم از هر چیزی که مرتبط با ایران بود پاک کردم چون رباتشون این موارد رو هم ممکنه چک کنه.😕 هر چی فونت تو اپ داشتم رو با نرمافزار FontFrog باز کردم و دیدم که بلللله پر از موارد مربوط به ایرانه و اون جا دیدم که یه فونت چه قدر متادیتا داره (چون پاک کردن تکتکشون واقعا حوصله سربر بود😁) از اسم سازنده فونت تا لایسنس و سایتی که توش فونت اپلود شده بود و ...
видео или голосовое, без подписи
پیشنهاد میکنم اگر android adk رو تست نکردید یه نگاهی بهش بندازید. فوق العاده است . تو اپتون یه ایجنت تعریف میکنید و با یه پرامپت اهدافش رو براش مشخص میکنید مثلا You are a helpful assistant that tells the current time in a city اون وقت خواسته کاربرتون…
طبق گفته داکش میتونید از مدل gemini-nano هم به صورت on-device و بدون اینترنت هم استفاده کنید (من تستش نکردم هنوز) https://developer.android.com/ai/adk حتما سمپل هاشو هم چک کنید از داکش بیش تر کمک میکنه https://github.com/google/adk-kotlin/tree/main/examples
حالا نکته اعجاب انگیزش اینه شما میتونید برای agent یه سری تولز تعریف کنید تولز ها یه سری فانکشن هستن که ما داخلشون یه کاری رو تعریف میکینم و خود ایجنت بر اساس خواسته کاربر میدونه که کدوم فانکشن رو الان باید کال کنه مثلا توی عکس من یه تولز ایجاد کردم برای گرفتن live price طلا از ای پی ای (البته من ماکش کردم که فعلا واضح باشه و همیشه قیمت 4,550,000 بده ) حالا کاربر هر وقت که از ایجنت من قیمت طلا رو بخواد خود ایجنت بر اساس توضیح هر تولز میفهمه که باید بره کدوم فانکشن رو کال کنه و نتیجه اش رو به کاربر برگدونه یا مثلا شما میتونید یه تولز دیگه تعریف کنید که بره یه سایت رو بخونه و داخلش مثلا فیلد قیمت رو استخراج کنه و به کاربر ارایه کنه و ...
مثلا من این جا یه ایجنت ساختم و دستورالعمل هامو بهش دادم
پیشنهاد میکنم اگر android adk رو تست نکردید یه نگاهی بهش بندازید. فوق العاده است . تو اپتون یه ایجنت تعریف میکنید و با یه پرامپت اهدافش رو براش مشخص میکنید مثلا You are a helpful assistant that tells the current time in a city اون وقت خواسته کاربرتون رو مثلا پرامپتی که داده رو ارسال میکنید به این agent ایجنت هم با توجه به هویتی که قبلا براش تعیین کردید شروع میکنه به تعامل کردن با یوزر
اگر رام (RAM) گوشی کاربر پر باشد، اندروید بدون تعارف اپلیکیشن را میبندد (Crash). این کد وظیفهاش این است که قبل از انجام کارهای سنگین، وضعیت جیبِ حافظهٔ گوشی را بسنجد و بر اساس آن تصمیم بگیرد. class MemoryGovernor(private val context: Context) { private…
خب ما تا این جا تونستیم یه ارتباط دو طرفه با سیستم عامل برقرار کنیم تا بتونیم از پردازنده مطابق نیازمون بهینه استفاده کنیم. اما همه چیز به cpu ختم نمیشه پردازش های ما داره مموری رو هم تحت استرس میگذاره پس باید با مموری هم جوری رفتار کنیم تا سیستم عامل اپمون…
خب ما تا این جا تونستیم یه ارتباط دو طرفه با سیستم عامل برقرار کنیم تا بتونیم از پردازنده مطابق نیازمون بهینه استفاده کنیم. اما همه چیز به cpu ختم نمیشه پردازش های ما داره مموری رو هم تحت استرس میگذاره پس باید با مموری هم جوری رفتار کنیم تا سیستم عامل اپمون رو بلاک نکنه (Out Of Memory) پس من یه کلاس طراحی کردم با نام MemoryGovernor
currentThermalStatus
رادار حرارتی و جلوگیری از داغ شدن (shouldSlowDown) وقتی پردازنده با تمام سرعت کار کند، گوشی داغ میشود. اگر گوشی بیش از حد داغ شود، خود اندروید به صورت ناگهانی و بیرحمانه فرکانس پردازنده را به شدت پایین میآورد (Thermal Throttling) که باعث قفل کردن اپلیکیشن میشود. این متد از این اتفاق جلوگیری میکنند. return status >= PowerManager.THERMAL_STATUS_MODERATE این متد بررسی میکند که آیا وضعیت دمای گوشی به حالت MODERATE متوسط/رو به داغ رسیده است یا خیر. کاربرد عملی: برنامهنویس در جریان پردازش مثلا در یک حلقه for بزرگ مرتباً متد shouldSlowDown() را چک میکند. اگر خروجی true شد، برنامه به جای ادامه دادن با حداکثر سرعت، کمی مکث میکند (مثلاً کارها را با تاخیر یا کیفیت پایینتر انجام میدهد) تا گوشی خنک شود، قبل از اینکه اندروید مجبور شود کل سیستم را کند کند. این جاست که وقتی این متد بهمون true برمیگردونه بین پردازش ها یه delay دو تا سه ثانیه ایجاد میکنیم این جوری هیچ وقت cpu رو به حد آستانه نمیرسونیم
چرا این کار مفید است؟ فرض کنید تو پردازش بدون سشن: CPU ↓ 1.8GHz ↓ 2.0GHz ↓ 1.6GHz ↓ 2.2GHz سیستم نمیداند پردازش چقدر مهم است. ولی با این Session: CPU ↓ 2.8GHz ↓ 2.9GHz ↓ 2.8GHz اگر دستگاه اجازه بدهد. در نتیجه پردازش سریعتر تمام میشود. البته…
خب هنوز کارمون تموم نشده یه پارت مهم دیگه این جاست: بازخورد دادن به سیستمعامل (reportActualWorkDuration )این متد جادوی اصلی ADPF است! بعد از اینکه کار سنگین تموم شد، ما زمان واقعی ای که کارمون طول کشید رو به سیستمعامل گزارش میدیم hintSession?.report…
خب هنوز کارمون تموم نشده یه پارت مهم دیگه این جاست: بازخورد دادن به سیستمعامل (reportActualWorkDuration )این متد جادوی اصلی ADPF است! بعد از اینکه کار سنگین تموم شد، ما زمان واقعی ای که کارمون طول کشید رو به سیستمعامل گزارش میدیم hintSession?.reportActualWorkDuration(actualDurationMillis * 1_000_000L) سیستم یادگیری سختافزار: اگر شما پیشبینی کرده بودید کار ۱ ثانیه طول میکشد، اما در واقعیت ۱.۵ ثانیه طول کشید، اندروید میفهمد که پردازنده ضعیف عمل کرده است. در نتیجه، برای چرخه بعدی پردازش، فرکانس CPU را بالاتر میبرد تا اپلیکیشن شما لگ نزند اصطلاحاً دچار افت فریم یا Stutter نشود.
پس قبل از اینکه کارمون رو شروع کنیم این متد رو صدا میزنیم☝ val hintManager = context.getSystemService(Context.PERFORMANCE_HINT_SERVICE) اینجا سرویس PerformanceHintManager از سیستم گرفته میشود. این سرویس مخصوص ADPF است. val tids = intArrayOf(Process.myTid())…
پس قبل از اینکه کارمون رو شروع کنیم این متد رو صدا میزنیم☝ val hintManager = context.getSystemService(Context.PERFORMANCE_HINT_SERVICE) اینجا سرویس PerformanceHintManager از سیستم گرفته میشود. این سرویس مخصوص ADPF است. val tids = intArrayOf(Process.myTid()) این قسمت بسیار مهم است. اندروید باید بداند: کدام Thread قرار است پردازش سنگین انجام دهد؟ نه کل برنامه. فقط همان Thread.
خب وقتی اپ من کارش رو شروع میکرد عملا تبدیل به یه اپ زامبی میشد . در مدت کوتاهی گوشی به شدت داغ میکرد کند میشد و در نهایت سیستم عامل یا اپ رو یا کلا هر چیزی که ران بود رو terminate میکرد. بنابراین من باید سرعت رو فدای عملکرد درست برنامه میکردم. باید سرعت کارهامو پایین تر میاوردم تا cpu داغ نکنه و برنامه دچار مشکل نشه خب اما چه قدر باید سرعت رو کم میکردم ؟ ایا این رفتار باید روی همه گوشی های یکسان میبود ؟مثلا اون دیوایس قوی تر هم باید معطل وقفه های من میشد ؟ ایا راهی وجود نداشت که من بتونم از سیستم عامل توجه بیشتری رو بگیرم و ... ؟ این جا بود که یه سرچ کلی زدم و با یه چیز خفن تر مواجه شدم ! ADPF کلید قفل ها بود. در واقع ADPF (Android Dynamic Performance Framework) که از اندروید ۱۲ اضافه شده کارش اینه که به جای اینکه اجازه بده سیستمعامل اندروید به صورت کورکورانه درباره سرعت پردازنده تصمیم بگیره، وارد یک گفتگوی دوطرفه با سیستمعامل میشه: «هی اندروید! من دارم یک کار سنگین انجام میدم، هوامو داشته باش و سیپیو رو قوی کن؛ اما اگه گوشی داره داغ میکنه بهم بگو تا خودم فتیله رو بکشم پایین!» private var hintSession: PerformanceHintManager.Session? = null در واقع کد بالا قلب تپنده این سیستمه ما با ایجاد یه سشن جدید به سیستم عامل اطلاع میدیم که قراره تا پایان این سشن یه کار پردازشی سنگین انجام بدیم بعد از مقدار دهی سشن باید استارتش رو بزنیم و بهش یه استیمیشن حدودی از مدتی که کارمون طول میکشه بدیم (نمیتونیم یه سشن رو نامحدود اجرا کنیم بالاخره باید یه جایی تموم شه) همچنین باید تردی که قصد داریم کارمون رو باهاش انجام بدیم رو هم به سیستم عامل معرفی کنیم تا مدیریتش رو برامون به عهده بگیره
اما تا این جا فقط اینو بگم که من تازه متوجه شدم که وقفه زمانی چه تاثیر وحشتناکی روی بهبود عملکرد cpu داره