Androidã¯ã»ãŒ10æ³ã§ãã
2åç®ã®Android Paranoid mitapã§Yandexã®ãµã³ã¯ãããã«ãã«ã¯ãªãã£ã¹ã«æ¥ããã¹ãŠã®äººãšãç¥ãã®ãè¶äŒã§ãããç¥ãããšã«ããŸããã ããã«èšã£ãŠãã£ãã æ®å¿µãªããããã·ã¥ããããã§ã³ã¬ãŒããããã¯ãããŒããžã§ãªãŒããŒã³ãºã¯3æ28æ¥ã«çµäºããŸããã

代ããã«ããããªã«èšé²ãããã¬ããŒããšãAndroidéçºè
åãã®æçšãªæ
å ±ã®çãçµã蟌ã¿ããããŸãã ã«ããã®äžã§
- ã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãã¯ãªãã¯ããåŸã®åäœã
- ã¢ããªã±ãŒã·ã§ã³ãKotlinã«å€æãã300è¡ã®ã³ãŒãã«åããæ¹æ³ã
- Androidããã¯ã°ã©ãŠã³ãããŒã«ã®å€æŽæ¹æ³
- RecyclerViewã§ã¢ãã¡ãŒã·ã§ã³ããã°ããååŸããæ¹æ³ã
RecyclerViewã®ã¢ãã¡ãŒã·ã§ã³ã«ã€ããŠ
Yandex.Moneyã®Danil TernovããRecyclerViewã§ã¢ãã¡ãŒã·ã§ã³ãè¿
éãã€ã³ã¹ãå¹çããååŸããæ¹æ³ã«ã€ããŠèª¬æããŸããã
ä»äºã§è©ŠããŠã¿ãã人ã®ãã
ã«-GitHubã®ãã¢ã å®è£
ã®è©³çŽ°ã¯ãããªã«ãããŸãã
ãã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãã¿ãããããšã©ããªããã
ããã«å°ãåã«ïŒããšãSberbank Technologiesã®Vladimir Tebloevæ°ã¯èšããŸãã Androidã®ãã¹ãŠã®ç掻ããã¥ãŒãšã¢ã¯ãã£ããã£ã«å¶éãããŠãããšèããŠãããã«ãŒãã«ãããŒãããŒããŒããã«ãŠã£ãã¯ã«ã€ããŠäœãç¥ãããAndroidãæ¥ååãå¿
èŠãšããçç±ãåžžã«çåã«æã£ãŠããå Žåã¯ããããªãèŠãããšããå§ãããŸãã èå³ã®ãã人ã®ããã«-3ã€ã®ãšããœãŒãã§çµããŸãã
ãšããœãŒã1-ã·ã¹ãã ã¬ãã«ãšæ¥ååãããããããè¥ãã¢ãã€ã«OSã®ãšã³ãžãã¢ã¯ã4ã€ã®ã¬ãã«ã®ã·ã¹ãã æäœãèšèšããŸããã
- ãã©ã€ããŒãšãã€ã³ããŒãåããã«ãŒãã«ã
- ã«ãŒãã©ã€ãã©ãªãOSã©ã€ãã©ãªãããã³Dalvikã
- ã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ãäžå€ã®ã·ã¹ãã ã³ã³ããŒãã³ã-ã³ã³ãã³ããããã€ããŒãã¢ã¯ãã£ããã£ãããŒãžã£ãŒãªã©ã
- ã«ã¹ã¿ã ã¢ããªã±ãŒã·ã§ã³ã

å°ãåã«ãDalvikã¯Androidã©ã³ã¿ã€ã ã«å€ãããŸããããããã¯ããã»ã¹ã®æ¬è³ªãå€ããŸããã§ãã-ã©ã³ãã£ãŒã¢ã€ã³ã³ãã¿ããããåŸãä¿¡å·ãåä¿¡ããã¢ã¯ãã£ããã£ãããŒãžã£ãŒã«æž¡ããZygoteã«è»¢éãããæ°ããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
Zygoteã¯ãã·ã¹ãã ã®èµ·åæã«èµ·åãããã©ã€ããªä»®æ³ãã·ã³ãåæåããããŒã¢ã³ã§ãã Zygoteã䜿çšãããšãAndroidã¢ããªã±ãŒã·ã§ã³ã®ããã»ã¹ãäœæããŠããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããããã«å¿
èŠãªèªåãšã«ãŒãã©ã€ãã©ãªã®ã¯ããŒã³ãäœæã§ããŸãã å¿
èŠãªã©ã€ãã©ãªã¯ãã¹ãŠãã©ã€ããªZygoteã€ã³ã¹ã¿ã³ã¹ã§ãã§ã«åæåãããŠãããããããã«ããæéãšã¡ã¢ãªãç¯çŽãããŸãã ããšã¯ãCopy-on-Writeã䜿çšããŠProcessIDãå€æŽããã ãã§ãã

å·ŠåŽã¯ãã©ã€ããªã€ã³ã¹ã¿ã³ã¹ãäžå€®ã¯Androidã³ã³ããŒãã³ããæ
åœããZygoteãå³åŽã¯ã¢ããªã±ãŒã·ã§ã³ã§ãã
ãšããœãŒã2-ã©ã€ããµã€ã¯ã«ãšããã»ã¹ã®çžäºäœçšAndroidã«ã¯ã5çš®é¡ã®ããã»ã¹ãš3ã€ã®åªå
床ãå²ãåœãŠãããŠããŸãã
éèŠãªåªå
床ã¯ãã¢ã¯ãã£ããªããã»ã¹ïŒãŠãŒã¶ãŒãçŸåšå¯Ÿè©±ããŠããããã»ã¹ïŒã«å²ãåœãŠãããŸãã ããã¯ããªãŒãã³ã¢ã¯ãã£ããã£ã§ããUIã®é³æ¥œãã¬ãŒã€ãŒã§ãããŸããŸããã
éåžžãç®ã«èŠããããã»ã¹ãããšãã°ä»è
ã«ãã£ãŠãããã¯ãããã¢ã¯ãã£ããã£ã«
é«ãåªå
床ãäžããããŸãã ã¢ã¯ãã£ããªããã»ã¹ã«ååãªã¡ã¢ãªããªãå Žåãå¯èŠããã»ã¹ã¯çµäºããŸãã åãåªå
é äœã«ã¯ããŠãŒã¶ãŒã察話ããªããµãŒãã¹ããã»ã¹ãå«ãŸããŸããããŒã¿ããã»ã¹ã®ããŠã³ããŒããåæãªã©ãæ
åœããŸãã
åªå
床ã®äœãããã»ã¹ã¯ããã§ã«åæ¢ããŠããã¢ã¯ãã£ããã£ã«é¢é£ããŠããŸãã Androidã¯ããããã®ããã»ã¹ãèµ·åé ã«äžŠã¹æ¿ããã¡ã¢ãªã«ä¿åããŠãå€ããã®ããæ°ãããã®ã®é ã«å®äºããŸãã æåŸã®ã«ããŽãª-ããŸã³ãããã»ã¹ã-äžéšã®ã¹ããªãŒã ãåæåã§ããŸãããã©ã€ããµã€ã¯ã«ã®ãã¹ãŠã®ã³ã³ããŒãã³ãã¯æ¢ã«ç Žæ£ãããŠããŸãã
ããã»ã¹ãçžäºäœçšããäž»ãªæ¹æ³ã¯ããã€ã³ããŒãä»ããIPCã§ãã ããã¯ããã¹ãŠã®Androidã«ãŒãæ§é ãæ©èœãããã©ã€ããŒã§ãã çžäºäœçšã¢ãã«ã次ã®å³ã«ç€ºããŸãã

ããã»ã¹Aã®ã¢ã¯ãã£ããã£ãå¥ã®ããã»ã¹ããããŒã¿ãåä¿¡ãããšããŸãã FooïŒïŒã¡ãœããã¯ãã€ã³ããŒã«ã¢ã¯ã»ã¹ããŸãããã€ã³ããŒã¯ãå
¥åããŒã¿ãé çªã«ã·ãªã¢ã©ã€ãºããã³ããã¯ããåŠçã®ããã«ã¿ãŒã²ããããã»ã¹ã«æž¡ããŸãã 次ã«ãå¿
èŠãªããŒã¿ãéã·ãªã¢ã«åãããããã»ã¹Bãããã䜿çšããŠãéã®é åºã§æäœãå®è¡ããŸãã
ãããšã¯å¥ã«ããŠã©ãžããŒã«ã¯Androidã§ã¢ã¯ãã£ããã£ãäœæãããã¹ãŠã®æ®µéã«ã€ããŠè©±ããŸããã 詳现ã¯ãã¹ãŠãããªã«èšèŒãããŠããŸãã
ããŠãŒã¶ãŒã¯60 FPSãæãã§ããã
ãããããã¯ã°ã©ãŠã³ãäœæ¥ã®ç®çã§ããã
EPAM Vladimir Ivanovã¯7幎éAndroidãšiOSåãã«å·çããŠãããWindows Phoneãåããããšã«æåããŸããã ãŠã©ãžããŒã«ã¯ãã¡ã€ã³ã®Androidã¹ã¬ãã以å€ã®ã¿ã¹ã¯ãå®äºããããã®ããŒã«ã®é²åã«ã€ããŠèªããŸããã ãã§ãŒã³äžã®ã¹ããŒã-AsyncTaskãããŒããŒããšã°ãŒãã¥ãŒã¿ãŒãEventBusãRxJavaãKotlinã®ã³ã«ãŒãã³ã
ã¬ããŒãã«ã¯å€ãã®äŸããããŸãããããã«å°ããªéšåããããŸãã
å埩1-AsyncTask倩æ°äºå ±ã衚瀺ããã¢ããªã±ãŒã·ã§ã³ãäœæããŠãããšããŸãã ã¢ã¯ã·ã§ã³ã®ã·ãŒã±ã³ã¹ã¯ããã次ã®ãšããã§ãã
- DoInBackgroundïŒïŒã¡ãœãããå®çŸ©ããŸãã
- httpã¯ã©ã€ã¢ã³ãã䜿çšããŠããµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ããŸãã
- å¿çãååŸããŸãã
- ãŠãŒã¶ãŒã衚瀺ããŸãã
æåŸã®æ®µéã§ã¯ãè€éããçããŸããããã¯ã°ã©ãŠã³ãããUIã¹ããªãŒã ã«çããååŸããŠè¿ãã ãã§ã¯ã§ããŸããã UIãåæã«ä»ã®ã¹ã¬ããã䜿çšããå ŽåãæŸèæãšè€éãªããã¯ãèããå¿
èŠããããŸãã ãããé¿ããããã«ãã€ã³ã¿ãŒãã§ãŒã¹éçºè
ã¯UIã¹ããªãŒã ããã®ã¿æŽæ°ããããšããå§ãããŸãã
ãããã£ãŠãUIã§äœããããæ¹æ³ãå¿
èŠã§ãã AsyncTaskã¯ããã®ããã«onPostExecuteã¡ãœããã䜿çšããŸãã
public class LoadWeatherForecastTask extends AsyncTask < String, Integer, Forecast > { public void onPostExecute(Forecast forecast) { mTemperatureView.setText(forecast.getTemp()); } }
ãã®ã¢ãããŒãã«ã¯1ã€ã®å€§ããªåé¡ãšããã€ãã®æ¬ ç¹ããããŸãã5幎以äžåã®å®åãããžã§ã¯ããé€ããAsyncTaskã¯åæ¢ããŸããã
æ¬ ç¹ã¯æ¬¡ã®ãšããã§ãã
1ïŒãããã¯ãŒã¯èŠæ±ã®ããã®å€ãã®ã³ãŒãã
2ïŒAsyncTaskã¯ã¢ã¯ãã£ããã£ã®ã©ã€ããµã€ã¯ã«ã«ã€ããŠäœãç¥ããªããããã¡ã¢ãªãªãŒã¯ãåŒãèµ·ããå¯èœæ§ããããŸãã
3ïŒèšå®ããªã³ã¶ãã©ã€ã§å€æŽããå ŽåïŒããšãã°ãç»é¢ãäžäžéã«ãªãïŒããªã¯ãšã¹ããéå°ã«å®è¡ããå¿
èŠããããŸãã
å埩2-ããŒããŒããŒããŒã«ã¯Android 3.0ãä»å±ããŠããŸã-AndroidããŒã ã¯AsyncTaskã®åé¡ã解決ããããã«ããããèæ¡ããŸããã
class WeatherForecastLoader(context: Context) : AsyncTaskLoader < WeatherForecast > (context) { override fun loadInBackground() : WeatherForecast { try { Thread.sleep(5000) } catch(e: InterruptedException) { return WeatherForecast("", 0F, "") } return WeatherForecast("Saint-Petersburg", 20F, "Sunny") } }
ç¹ã«ãæ§æãå€æŽãããšãã«çµæãåå©çšããããšã«ã€ããŠè©±ããŸãã åé¡ã¯æ¬¡ã®ããã«è§£æ±ºãããŸãã
1ïŒã¢ã¯ãã£ããã£ã«é¢é£ä»ããããLoaderManagerã¯ãããã€ãã®ããŒããŒãžã®ãªã³ã¯ãç¹å¥ãªæ§é ã§ä¿åããŸãã
2ïŒã¢ã¯ãã£ããã£ã«ããããã¹ãŠã®LoaderManagerãNonConfigurationInstanceså
ã«ä¿åãããŸãã
3ïŒæ°ããã¢ã¯ãã£ããã£ãäœæããå Žåãã·ã¹ãã ã¯NonConfigurationInstancesããããŒã¿ã転éããŸãã
4ïŒã¢ã¯ãã£ããã£ã¯ããã¹ãŠã®ããŒããŒã§LoaderManagerã埩å
ããŸãã
çæïŒ
1ïŒãŸã å€ãã®ã³ãŒãããããŸãã
2ïŒã€ã³ã¿ãŒãã§ã€ã¹ã¯äŸç¶ãšããŠè€éã§ãããã¯ã©ã¹ã¯äŸç¶ãšããŠæœè±¡çã§ãã
3ïŒããŒããŒã¯Androidã®ãã©ãããã©ãŒã APIã§ãããçŽç²ãªJavaã§åå©çšã§ããªãããšãæå³ããŸãã
å埩3-EventBusããã³ThreadPoolExecutorsThreadPoolExecutorsã®åºçŸã«ãããããã¯ã°ã©ãŠã³ãããUIãžã®ããŒã¿è»¢éã¯æ¬¡ã®ããã«ãªãå§ããŸããã
1ïŒBackgroundã¯ã©ã¹ãéå§ãããã®äžã§-Serviceå€æ°ã
2ïŒScheduledThreadPoolExecutorã§ãã®ã¯ã©ã¹ãå¿
èŠãªãµã€ãºã§åæåããŸãã
3ïŒã¯ã©ã¹ãå®è¡å¯èœãŸãã¯åŒã³åºãå¯èœã«ãããã«ããŒã¡ãœãããäœæããŸãã
public class Background { private val mService = ScheduledThreadPoolExecutor(5) fun execute(runnable: Runnable) : Future < *>{ return mService.submit(runnable) } fun < T > submit(runnable: Callable < T > ) : Future < T > { return mService.submit(runnable) } }
ããã¯ã°ã©ãŠã³ãã§å®è¡ããããšã«å ããŠãçµæãUIã«è¿ãå¿
èŠããããŸãã ãããè¡ãããã«ãUIã¹ã¬ããã«äœãããã¹ããããã³ãã©ãŒãšã¡ãœãããäœæããŸãã
public class Background {âŠprivate lateinit var mUiHandler: Handler public fun postOnUiThread(runnable: Runnable) { mUiHandler.post(runnable) } }
ãã¹ãŠã®UIãç¹å®ã®ã¡ãœãããå®äºããããšãç¥ãå¿
èŠã¯ãããŸããã 責任ãå
±æããããã«ãEventBusãæãã€ããŸããã ããã¯ãããã¯ã°ã©ãŠã³ãã¹ã¬ããããUIã«ã€ãã³ããéä¿¡ããæ¹æ³ã§ããUIã§ã¯ãè€æ°ã®ãªã¹ããŒãå
±æãã¹ã«æ¥ç¶ããããããã®ã€ãã³ãããããã®ã€ãã³ããåŠçããŸãã

EventBusã®æ¢è£œã®å®è£
ãããã€ããããŸãã ãããã®ããã€ãã¯ãGoogle GuavaãOttoãGreenBot Eventbusã§ãã
ãã€ãã¹ã®ãã¡ïŒ
- ã€ãã³ãããŒã¿ãœãŒã¹ã¯ããã®åŠçæ¹æ³ã«ã€ããŠäœãç¥ããŸããã
- ã¹ããŒã«ãŒã®çµéšã«ãããšããã°ãããããšãEventBusã®ã³ãŒãããµããŒãã§ããªããªããŸãã
4çªç®ã®å埩-RxJavaããŸãã¯ãããã§ååïŒã誰ããããã¯ã°ã©ãŠã³ãäœæ¥ã®ããã®äŸ¿å©ãªããŒã«ãèãåºãå¿
èŠããããŸããã ãã®çµæãã€ãã³ãã¹ããªãŒã ãæäœããããã®å€§ããªãã¬ãŒã ã¯ãŒã¯ã§ããRxJavaãã§ããŸããã
GitHubã§æ¿èªãããå¿
èŠãããã³ãŒããæžããŠãããšããŸãã å¿
èŠãªæäœããšã«ã¡ãœããã§éå§ããå¿
èŠããããŸãïŒãã®å Žåããã°ã€ã³ããŠãªããžããªã®ãªã¹ããååŸããŸãïŒã
interface ApiClientRx { fun login(auth: Authorization) : Single < GithubUser > fun getRepositories(reposUrl: String, auth: Authorization) : Single < List < GithubRepository >> }
å®è¡ã®çµæã¯SingleïŒãŒããŸãã¯1ã€ã®ã€ãã³ãããã®ã¹ããªãŒã ïŒã«ãªããŸãã äœæ¥ã®çµæã¯ããŠãŒã¶ãŒãå¿
èŠãšãããã¹ãŠãè¿ã2ã€ã®ã¡ãœããã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ãã
çæïŒ- æ¥ãªåŠç¿æ²ç·ãåŠç¿ã¯é·ããŠé£ããã
- å€ãã®æŒç®åããã®éããç解ããããšã¯å°é£ã§ãã
- 2ã€ã®ã¯ãšãªãš2ã€ã®æŒç®åããã®åçŽãªã³ãŒãçšã«çŽ20åã®ãªããžã§ã¯ããäœæãããŸãã
- ç¡é¢ä¿ãªã¹ã¿ãã¯ãã¬ãŒã¹ã30è¡ã®ãã¡ãã³ãŒãã«é¢é£ä»ããããšãã§ããã®ã¯1è¡ã®ã¿ã§ãã
é·æïŒ- RxJavaã¯äºå®äžã®æšæºã§ãã Vladimirã¯Twitterã§èª¿æ»ãå®æœããæ°ãããããžã§ã¯ãã®éçºè
ã®65ïŒ
ãRxJavaã䜿çšããããšãçºèŠããŸããã
- 匷åãªAPI
- RxJavaã¯ã倧èŠæš¡ãªã³ãã¥ããã£ãæã€ãªãŒãã³ãœãŒã¹ãã¬ãŒã ã¯ãŒã¯ã§ãã
- RxJavaã³ãŒãã¯ãåäœãã¹ãã§ç°¡åã«ã«ããŒãããŸãã
å埩5-ã³ã«ãŒãã³ã³ã«ãŒãã³ã¯ãKotlinèšèªå
ã§ãµããŒããããŠããããã¯ã°ã©ãŠã³ãã©ã€ãã©ãªã§ãã
ãã®å©ç¹ïŒ1.ãã³ããããã³ã°ã¢ãããŒã-ããã¯ã°ã©ãŠã³ãäœæ¥äžã«ã¡ã€ã³ã¹ã¬ãããå®è¡ãããé²è¡äžã«çµæãåã蟌ãŸããŸãã
2.åæã¹ã¿ã€ã«ã®éåæã³ãŒã
private fun attemptLogin() { launch(UI) { val auth = BasicAuthorization(login, pass) try { showProgress(true) val userInfo = login(auth).await() val repoUrl = userInfo.repos_url val list = getRepositories(repoUrl, auth).await() showRepositories(this@LoginActivity, list.map { it - >it.full_name }) } catch(e: RuntimeException) { Toast.makeText(this@LoginActivity, e.message, LENGTH_LONG).show() } finally { showProgress(false) } } }
3ïŒæŒç®åã§ã¯ãªãèšèªã®æ段ã
4ïŒå匷ããã ã-åŠç¿æ²ç·ã¯ã»ãšãã©æ²ç·ã§ã¯ãããŸããã
5ïŒå°ãæ€èšããåŸããŠããããã¹ãã¯åæã³ãŒãã®å Žåãšã»ãŒåãã«ãªããŸãã
çæïŒ1ïŒæè¿ãå®éšç¶æ
ããå€ããŸããã
2ïŒããã¯èšèªã®äžéšã§ã¯ãªããã©ã€ãã©ãªã§ãã
3ïŒãã¹ãŠã«ã¢ããã¿ãŒãããããã§ã¯ãããŸããã
4ïŒã³ã«ãŒãã³ã¯RxJavaã®ä»£æ¿ã§ã¯ãããŸããã è€éãªã€ãã³ãã¹ããªãŒã ãããå°é£ãªã±ãŒã¹ã§ã¯ãããŸã圹ã«ç«ã¡ãŸããã
ã³ã«ãŒãã³ã«é¢ããæ®ãã®äŸïŒäŸãå«ãïŒã¯ãã¬ããŒãã§ç¢ºèªããããšããå§ãããŸãã
Kotlinã§300è¡ããã°ã©ãã³ã°ã«ã³ãŒããé©åãããæ¹æ³
1幎åãGoogle IO 2017ã§ãKotlinãå
¬åŒã®Androidèšèªã«ãªã£ãããšãçºè¡šãããŸããã Alfa Bankã®Yuri Chechetkinã«ãããæ°ããèšèªãžã®ç§»è¡ãéå§ããã¯ã©ã¹ã300è¡ã«æžãããŠãçããªãããã«ããæ¹æ³ã«é¢ããã¬ããŒãã
ãã®ã¬ããŒãã¯ãã³ã³ãã¯ãã§çŸããæç« ãæžãæ¹æ³ã«é¢ããå®è·µçãªæè²ããã°ã©ã ã§ãã Kotlinã®äž»ãªæ©èœãçç¥ããŠããäžçŽãŠãŒã¶ãŒã察象ãšããŠããŸãã
ã¬ããŒãã«ã¯ã2ã€ã®èšèªã§ã®ã³ãŒãã®äœ¿çšäŸãšæ¯èŒäŸããããããããããããã§ã¯èå³æ·±ãäºå®ãšçµè«ã®ã¿ã瀺ããŸãã
Kotlinãžã®äž»èŠãªç§»è¡ã®åé¡ïŒ- ã¬ã¬ã·ãŒJavaã³ãŒãã æ°åè¡ã®ã³ãŒãã®å€§èŠæš¡ãªã¯ã©ã¹ã¯ãéçºç°å¢ã䜿çšããŠå€æããã®ãéåžžã«å°é£ã§ãã
- äŸåé¢ä¿-ãã³ãã¯ãã¹ããªãŒã APIãªã©ã
- ããŒã å
ã®éå°ãªã³ãŒãèŠä»¶ã 300è¡ã®å¶éã®ã³ãŒãã®å®æçãªèªåãã§ãã¯ãšã³ãŒãã¬ãã¥ãŒãå®è¡ãããŸãã
- Kotlinã¯æ°ããèšèªã§ãããçµ±äžãããèŠåããªããªããŸã§èŠä»¶ãçå®ããããšã¯å°é£ã§ãã
- Kotlinã¯ããé·ãæéã³ã³ãã€ã«ããŸãã
- æ§æç³ã¯ã倧ããªåã§ããã倧ããªè²¬ä»»ãã§ãã
çµè«ïŒ- Kotlinã䜿çšããŠ1幎ãçµã€ãšãã³ãŒããå°ãªããªããŸãããã³ãŒãããããã«ãªããã³ãŒãã®ã¬ãã¥ãŒããã䟿å©ã«ãªããŸããã
- å€ãJavaã¡ãœãããè¿œå ã®äŸåé¢ä¿ãæšæºèšèªæ©èœã®ã¿ã¯ãããŸããã
- æŸèæãšãã°ãå°ãªãã
- ããå€ãã®æ©èœ-Kotlinã§å®è£
ãããããã€ãã®ãã®ã¯Javaã§æžãããšãã§ããŸããã
æ®ãã¯ãããªã«ãããŸãã
YK MoneyããŒã ã®ã€ãã³ããæ¥åžžç掻ãVK ã Facebook ã Instagramã§ãã©ããŒããŠãã ããã
ãã¹ãŠã®Yandexã®äŒè°ãšäŒè°ã¯Y. Vstrechahã§è¡ãããŸãã