Instead of the verbose setOnClickListener:
RxView.clicks(submitButton).subscribe(o -> log("submit button clicked!"));Observable
.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)| Не подписано на FCM-пуши* | |
| каждый запуск -> Получение данных центром нотификаций | |
| Не получило FCM-токен* | |
| первый вход в приложение -> Ждет FCM-токен | |
| переустановка приложения -> Ждет FCM-токен | |
| при некоторых обновлениях приложения -> Не получило FCM-токен | |
| FCM-токен инвалидировался -> Ждет FCM-токен | |
| не первый вход в приложение -> Отправляет FCM-токен на сервер | |
| Ждет FCM-токен | |
| получен FCM-токен -> Отправляет FCM-токен на сервер |
| class TimerRxJobService : JobService() { | |
| companion object { | |
| private const val TAG = "TimerRxJobService" | |
| private const val TOP_PERIOD = 2L | |
| fun newJobInfo(context: Context): JobInfo { | |
| return JobInfo.Builder(1, ComponentName(context, TimerRxJobService::class.java)) | |
| .setMinimumLatency(1000) // Wait at least 1 second | |
| .setOverrideDeadline(5000) // But no longer than 5 seconds | |
| .setRequiredNetworkType(NETWORK_TYPE_NONE) |
| class TimerHandlerService : IntentService(TAG) { | |
| companion object { | |
| private const val TAG = "TimerHandlerService" | |
| private const val EXTRA_WITH_LOOP = "$TAG.with_loop" | |
| fun newIntent(context: Context, withLoop: Boolean): Intent { | |
| return Intent(context, TimerHandlerService::class.java).apply { | |
| putExtra(EXTRA_WITH_LOOP, withLoop) | |
| } | |
| } |
| class BoundService : Service() { | |
| companion object { | |
| private const val TAG = "BoundService" | |
| fun newIntent(context: Context) = Intent(context, BoundService::class.java) | |
| } | |
| var message: String = "Message from bound service" | |
| private val binder: BoundServiceBinder = BoundServiceBinder() |
| class ForegroundRxService : Service() { | |
| companion object { | |
| private const val TAG = "ForegroundRxService" | |
| private const val TOP_PERIOD = 2L | |
| private const val FOREGROUND_NOTIFICATION_ID = 1 | |
| private const val EXTRA_START_BACKGROUND_SERVICE = "$TAG.start_background_service" | |
| fun newIntent(context: Context, startBackgroundService: Boolean = false): Intent { | |
| return Intent(context, ForegroundRxService::class.java).apply { | |
| putExtra(EXTRA_START_BACKGROUND_SERVICE, startBackgroundService) |
| class TimerRxService : Service() { | |
| companion object { | |
| private const val TAG = "TimerRxService" | |
| private const val TOP_PERIOD = 2L | |
| private const val EXTRA_START_HANDLER_SERVICE = "$TAG.start_handler_service" | |
| fun newIntent(context: Context, startHandlerService: Boolean = false): Intent { | |
| return Intent(context, TimerRxService::class.java).apply { | |
| putExtra(EXTRA_START_HANDLER_SERVICE, startHandlerService) | |
| } |
| apply from: rootProject.file('tools/changelog-task.gradle') |
| package be.brol | |
| import android.os.Binder | |
| import android.os.Bundle | |
| import android.support.v4.app.BundleCompat | |
| import android.support.v4.app.Fragment | |
| /** | |
| * Eases the Fragment.newInstance ceremony by marking the fragment's args with this delegate | |
| * Just write the property in newInstance and read it like any other property after the fragment has been created |
| import android.text.SpannableStringBuilder; | |
| import java.util.ArrayDeque; | |
| import java.util.Deque; | |
| import static android.text.Spanned.SPAN_INCLUSIVE_EXCLUSIVE; | |
| /** A {@link SpannableStringBuilder} wrapper whose API doesn't make me want to stab my eyes out. */ | |
| public class Truss { | |
| private final SpannableStringBuilder builder; | |
| private final Deque<Span> stack; |