چرا می بایست اندروید Q را تارگت کنیم؟
اندروید 10 یا این که اندروید Q رسما در تاریخ 3 سپتامبر 2019 (12 شهریور 1398) منتشر شدهاست و ورژن بعداز اندروید 9 و جدیدترین ورژن اندروید به حساب میآید که طراحی اپلیکیشن در مشهد از سنت نامگذاری بر پایه ی اسم شیرینیها تقلید نمینماید.
کلیک فرمایید
اکثر زمان ها پیشنهاد میشود که هر یکسری برای آزمایش واپسین ورژن اندروید را تارگت کنیم و گوگل پلی استور نیز درین خصوص پیشنهادهایی به تفصیل ذیل داراست:
همان گونه که میبینید هر سال الزام گوگلی پلی به ورژن تازه افزایش می یابد. این بدان مضمون میباشد که از تاریخ 1 آگوست 2020 (11 مرداد 1399) نرم افزارهای تازه می بایست API سطح 29 را تارگت نمایند. به این ترتیب مجال متعددی برای آزمایش این که تمامی چیز روی ورژن تازه به صحت فعالیت مینماید ندارید.
پیش از هر چیز می بایست ورژن نو را تارگت کنیم تا ببینیم چه اتفاقاتی فیس میدهند. بهاین مراد کافی میباشد پاراگراف targetSdkVersion را در تنظیمات پیدا فرمایید و آن را روی 29 تهیه و تنظیم نمائید. آن گاه پروژه را کامپایل نمایید و هشدارها و خطاهای کامپایل را پژوهش فرمائید.
درپی مثالای از هشدارهایی را که ممکن میباشد بگیرید ارائه کردهایم. این هشدارها از پروژه حقیقی که سطح 28 به 29 افزایش یافته ناشی گردیدهاند:
Type mismatch: inferred type is MenuItem? but MenuItem was expected
Type mismatch: inferred type is Configuration? but Configuration was expected
Type mismatch: inferred type is String? but String was expected
\'setColorFilter(Int, PorterDuff.Mode): Unit\' is deprecated. Deprecated in Java
Type mismatch: inferred type is Date? but Date was expected
Unsafe use of a nullable receiver of type Any?
\'PreferenceManager\' is deprecated. Deprecated in Java
\'NetworkInfo\' is deprecated. Deprecated in Java
\'getter for activeNetworkInfo: NetworkInfo!\' is deprecated. Deprecated in Java
\'getter for isConnectedOrConnecting: Boolean\' is deprecated. Deprecated in Java
در لیست فوق به جز پژوهشهای null و اضافه شدن پکیج androidx.preference چیز متعددی نیست. تمامی این مورد ها در طول 20 دقیقه تماماً رفع می شوند. البته بهدنبال با نقص منسوخ شدن NetworkInfo مواجه میشویم.
NetworkInfo در سطح 29 منسوخ گردیدهاست:
فراخوانیکنندهها به مکان ConnectivityManager.NetworkCallback می بایست با تغییراتی که در مسئله اتصالپذیری واقع گردیده آشنا شوند و از ConnectivityManager#getNetworkCapabilities یا این که ConnectivityManager#getLinkProperties برای اخذ ناهمگام داده ها به کار گیری نمایند.
یک نحوه برای حل این ایراد این میباشد که به موعظههای ارتقای قانونی (+) روی اینترنتوبسایت اندروید نگاه کنیم. متأسفانه درین اینترنتوبسایت داده ها متعددی ارائه نشده میباشد و از این رو می بایست از توان ماهیچههای ذهن برای حل این خلل امداد بگیریم. تا قبل از این خبرهاِ بد در خصوص شرایط اتصالپذیری صرفا کاری که بایستی اجرا میدادیم به طور پایین بود:
1class NetworkUtils(private val context: Context) {
2 fun isConnected(): Boolean {
3 val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
4 val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
5 var result = false
6 if (activeNetwork != null) {
7 result = activeNetwork.isConnectedOrConnecting
8 }
9 return result
10 }
11}
این کد می بایست از هر جایی با فرض دسترسی به Context نرم افزار فراخوانی میشود و به راحتی می شد پژوهش کرد که آیا دستگاه اینک به کانال دسترسی داراست یا این که خیر. برای اخذ تغییرات در اتصال دستگاه به کانال نیز بایستی به طور پایین کار می شد:
پوشه BaseActivity.kt
1abstract class BaseActivity : AppCompatActivity() {
2 private var networkCallback: ConnectivityManager.NetworkCallback? = null
3 private val networkUtils by lazy { NetworkUtils(applicationContext) /*important to be applicationContext to prevent memoryLeak*/}
4 private val connectivityManager by lazy { getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager }
5
6 protected val NetworkStateReceiverListener.isConnected: Boolean // can be used by childs
7 get() {
8 this as BaseActivity // only accessible from child class, so cast i safe here
9 return networkUtils.isConnected()
10 }
11
12 private fun registerConnectivityMonitoring(listener: NetworkStateReceiverListener) {
13 val networkCallback = object : ConnectivityManager.NetworkCallback() {
14 override fun onAvailable(network: Network?) {
15 listener.networkConnectivityChanged()
16 }
17
18 override fun onLost(network: Network?) {
19 listener.networkConnectivityChanged()
20 }
21 }
22 this.networkCallback = networkCallback
23 connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), networkCallback)
24 }
25
26 private fun unregisterConnectivityMonitoring() {
27 val networkCallback = this.networkCallback ?: return
28 connectivityManager.unregisterNetworkCallback(networkCallback)
29 this.networkCallback = null
30 }
31
32 override fun onCreate(savedInstanceState: Bundle?) {
33 super.onCreate(savedInstanceState)
34 if (this is NetworkStateReceiverListener)
35 registerConnectivityMonitoring(this)
36 }
37
38 override fun onDestroy() {
39 super.onDestroy()
40 if (this is NetworkStateReceiverListener)
41 unregisterConnectivityMonitoring()
42 }
43
44 override fun onResume() {
45 super.onResume()
46 if (this is NetworkStateReceiverListener && !isConnected)
47 this.networkConnectivityChanged()// call to show no network banner on activity resume
48 }
49}
مشاهده بی نقص کدها
پوشه MyActivity.kt
1class MainActivity : BaseActivity(), NetworkStateReceiverListener {
2 override fun networkConnectivityChanged() {
3 if (isConnected) {
4 //show that that the network is back
5 } else {
6 //show that that the network was lost
7 }
8 }
9}
پوشه NetworkStateReceiverListener.kt
1interface NetworkStateReceiverListener {
2 fun networkConnectivityChanged() {}
3}
در حال حاضر که ConnectivityManager#getActiveNetworkInfo را از دست دادهایم صرفا نحوه برای پژوهش ناهمگام اتصال دستگاه به کانال به کارگیری از API تحت میباشد:
کلیک نمائید
NetworkCallback – این API میباشد که از گذشته می شناسیم و شاید حتی استعمال کردهایم. این یک اینترفیس برای پیادهسازی اخذ رویدادهای اتصالپذیری دستگاه میباشد.
ConnectivityManager#getNetworkCapabilities – با دقت به کانال، گنجایشهایی مانند نوع کانال (گوشی یا این که WIFI) پهنای باند و غیره را می گیرد.
ConnectivityManager#getLinkProperties – با دقت به کانال مشخصههای پیوند کانال مانند اینترفیس کانال را عرضه مینماید.
در لیست فوق مفاد 2 و 3 از API سطح 21 وجود داشتهاند، ولی تا به امروز زیاد با آن ها عمل نکردهایم و به لحاظ میرسد که فیضای شبیه کد قبل به دست نمیدهد.
هر دو آن ها به یک آرگومان Network نیاز دارا هستند که با ConnectivityManager#getActiveNetwork به دست میاید، البته در غایت هیچ کدام هم اندازه NetworkInfo#isConnected یا این که NetworkInfo#isConnectedOrConencting نیستند.
راه حل عمل این میباشد که موقعیت اتصال را جایی در اندروید ذخیره کنیم. بدین مراد می بایست بعضی مورد ها را در پیادهسازی NetworkCallback گزینه بازنگری در اختیار بگذاریم.
چرا می بایست اندروید Q را تارگت کنیم؟
اندروید 10 یا این که اندروید Q رسما در تاریخ 3 سپتامبر 2019 (12 شهریور 1398) منتشر شدهاست و ورژن بعداز اندروید 9 و جدیدترین ورژن اندروید به حساب میآید که طراحی اپلیکیشن در مشهد از سنت نامگذاری بر پایه ی اسم شیرینیها تقلید نمینماید.
کلیک فرمایید
اکثر زمان ها پیشنهاد میشود که هر یکسری برای آزمایش واپسین ورژن اندروید را تارگت کنیم و گوگل پلی استور نیز درین خصوص پیشنهادهایی به تفصیل ذیل داراست:
همان گونه که میبینید هر سال الزام گوگلی پلی به ورژن تازه افزایش می یابد. این بدان مضمون میباشد که از تاریخ 1 آگوست 2020 (11 مرداد 1399) نرم افزارهای تازه می بایست API سطح 29 را تارگت نمایند. به این ترتیب مجال متعددی برای آزمایش این که تمامی چیز روی ورژن تازه به صحت فعالیت مینماید ندارید.
پیش از هر چیز می بایست ورژن نو را تارگت کنیم تا ببینیم چه اتفاقاتی فیس میدهند. بهاین مراد کافی میباشد پاراگراف targetSdkVersion را در تنظیمات پیدا فرمایید و آن را روی 29 تهیه و تنظیم نمائید. آن گاه پروژه را کامپایل نمایید و هشدارها و خطاهای کامپایل را پژوهش فرمائید.
درپی مثالای از هشدارهایی را که ممکن میباشد بگیرید ارائه کردهایم. این هشدارها از پروژه حقیقی که سطح 28 به 29 افزایش یافته ناشی گردیدهاند:
Type mismatch: inferred type is MenuItem? but MenuItem was expected
Type mismatch: inferred type is Configuration? but Configuration was expected
Type mismatch: inferred type is String? but String was expected
\'setColorFilter(Int, PorterDuff.Mode): Unit\' is deprecated. Deprecated in Java
Type mismatch: inferred type is Date? but Date was expected
Unsafe use of a nullable receiver of type Any?
\'PreferenceManager\' is deprecated. Deprecated in Java
\'NetworkInfo\' is deprecated. Deprecated in Java
\'getter for activeNetworkInfo: NetworkInfo!\' is deprecated. Deprecated in Java
\'getter for isConnectedOrConnecting: Boolean\' is deprecated. Deprecated in Java
در لیست فوق به جز پژوهشهای null و اضافه شدن پکیج androidx.preference چیز متعددی نیست. تمامی این مورد ها در طول 20 دقیقه تماماً رفع می شوند. البته بهدنبال با نقص منسوخ شدن NetworkInfo مواجه میشویم.
NetworkInfo در سطح 29 منسوخ گردیدهاست:
فراخوانیکنندهها به مکان ConnectivityManager.NetworkCallback می بایست با تغییراتی که در مسئله اتصالپذیری واقع گردیده آشنا شوند و از ConnectivityManager#getNetworkCapabilities یا این که ConnectivityManager#getLinkProperties برای اخذ ناهمگام داده ها به کار گیری نمایند.
یک نحوه برای حل این ایراد این میباشد که به موعظههای ارتقای قانونی (+) روی اینترنتوبسایت اندروید نگاه کنیم. متأسفانه درین اینترنتوبسایت داده ها متعددی ارائه نشده میباشد و از این رو می بایست از توان ماهیچههای ذهن برای حل این خلل امداد بگیریم. تا قبل از این خبرهاِ بد در خصوص شرایط اتصالپذیری صرفا کاری که بایستی اجرا میدادیم به طور پایین بود:
1class NetworkUtils(private val context: Context) {
2 fun isConnected(): Boolean {
3 val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
4 val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
5 var result = false
6 if (activeNetwork != null) {
7 result = activeNetwork.isConnectedOrConnecting
8 }
9 return result
10 }
11}
این کد می بایست از هر جایی با فرض دسترسی به Context نرم افزار فراخوانی میشود و به راحتی می شد پژوهش کرد که آیا دستگاه اینک به کانال دسترسی داراست یا این که خیر. برای اخذ تغییرات در اتصال دستگاه به کانال نیز بایستی به طور پایین کار می شد:
پوشه BaseActivity.kt
1abstract class BaseActivity : AppCompatActivity() {
2 private var networkCallback: ConnectivityManager.NetworkCallback? = null
3 private val networkUtils by lazy { NetworkUtils(applicationContext) /*important to be applicationContext to prevent memoryLeak*/}
4 private val connectivityManager by lazy { getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager }
5
6 protected val NetworkStateReceiverListener.isConnected: Boolean // can be used by childs
7 get() {
8 this as BaseActivity // only accessible from child class, so cast i safe here
9 return networkUtils.isConnected()
10 }
11
12 private fun registerConnectivityMonitoring(listener: NetworkStateReceiverListener) {
13 val networkCallback = object : ConnectivityManager.NetworkCallback() {
14 override fun onAvailable(network: Network?) {
15 listener.networkConnectivityChanged()
16 }
17
18 override fun onLost(network: Network?) {
19 listener.networkConnectivityChanged()
20 }
21 }
22 this.networkCallback = networkCallback
23 connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), networkCallback)
24 }
25
26 private fun unregisterConnectivityMonitoring() {
27 val networkCallback = this.networkCallback ?: return
28 connectivityManager.unregisterNetworkCallback(networkCallback)
29 this.networkCallback = null
30 }
31
32 override fun onCreate(savedInstanceState: Bundle?) {
33 super.onCreate(savedInstanceState)
34 if (this is NetworkStateReceiverListener)
35 registerConnectivityMonitoring(this)
36 }
37
38 override fun onDestroy() {
39 super.onDestroy()
40 if (this is NetworkStateReceiverListener)
41 unregisterConnectivityMonitoring()
42 }
43
44 override fun onResume() {
45 super.onResume()
46 if (this is NetworkStateReceiverListener && !isConnected)
47 this.networkConnectivityChanged()// call to show no network banner on activity resume
48 }
49}
مشاهده بی نقص کدها
پوشه MyActivity.kt
1class MainActivity : BaseActivity(), NetworkStateReceiverListener {
2 override fun networkConnectivityChanged() {
3 if (isConnected) {
4 //show that that the network is back
5 } else {
6 //show that that the network was lost
7 }
8 }
9}
پوشه NetworkStateReceiverListener.kt
1interface NetworkStateReceiverListener {
2 fun networkConnectivityChanged() {}
3}
در حال حاضر که ConnectivityManager#getActiveNetworkInfo را از دست دادهایم صرفا نحوه برای پژوهش ناهمگام اتصال دستگاه به کانال به کارگیری از API تحت میباشد:
کلیک نمائید
NetworkCallback – این API میباشد که از گذشته می شناسیم و شاید حتی استعمال کردهایم. این یک اینترفیس برای پیادهسازی اخذ رویدادهای اتصالپذیری دستگاه میباشد.
ConnectivityManager#getNetworkCapabilities – با دقت به کانال، گنجایشهایی مانند نوع کانال (گوشی یا این که WIFI) پهنای باند و غیره را می گیرد.
ConnectivityManager#getLinkProperties – با دقت به کانال مشخصههای پیوند کانال مانند اینترفیس کانال را عرضه مینماید.
در لیست فوق مفاد 2 و 3 از API سطح 21 وجود داشتهاند، ولی تا به امروز زیاد با آن ها عمل نکردهایم و به لحاظ میرسد که فیضای شبیه کد قبل به دست نمیدهد.
هر دو آن ها به یک آرگومان Network نیاز دارا هستند که با ConnectivityManager#getActiveNetwork به دست میاید، البته در غایت هیچ کدام هم اندازه NetworkInfo#isConnected یا این که NetworkInfo#isConnectedOrConencting نیستند.
راه حل عمل این میباشد که موقعیت اتصال را جایی در اندروید ذخیره کنیم. بدین مراد می بایست بعضی مورد ها را در پیادهسازی NetworkCallback گزینه بازنگری در اختیار بگذاریم.

راهکارهای کاهش CPC در کمپینها