maeglor: (Робот. Книжку вот чтает...)
[personal profile] maeglor

Я сейчас занят пинанием хуев в рабочее время повышением квалификации и исследовательской работой.

Набрел на ряд решений которые мне кажутся очень удачными.

Вот например интересный вариант реализации boundService на RX для Андроид.

Решение из этого широко известного гайда обладает одним большим и рядом мелких недостатков. Большой в том, что в ходе работы активности мы ничего не можем сказать о подключении сервиса. И нам приходится использовать безумное количество хендлеров, либо ставить проверку перед каждым вызовом. Кроме того это решение весьма тяжеловесно и негибко.

Вот более интересный способ:


public abstract class BoundService extends Service {

  private IBinder binder = new ServiceBinder(this);

  @Override
  public IBinder onBind(Intent intent) {
    return binder;
  }
}



public class ServiceBinder extends Binder {

  private BoundService service;

  public ServiceBinder(BoundService service) {
    this.service = service;
  }

  public BoundService getService() {
    return service;
  }
}



public class ServiceConnector <T extends BoundService> {

  public abstract class LocalBinder extends Binder {
    public abstract Service getService();
  }

  private BehaviorSubject<T> serviceSubject = BehaviorSubject.create();
  private BoundServiceConnection boundServiceConnection = new BoundServiceConnection();

  public ServiceConnector(Context context, Class<T> tClass) {

    Intent orderServiceIntent = new Intent(context, tClass);
    context.bindService(orderServiceIntent,
        boundServiceConnection, Context.BIND_AUTO_CREATE);

    serviceSubject.subscribe(s -> {
    }, t -> {
    }, () -> context.unbindService(boundServiceConnection));
  }



  private class BoundServiceConnection implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
      Service service = ((ServiceBinder) binder).getService();
      serviceSubject.onNext((T) service); // May produce Class cast Exception
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
      serviceSubject.onCompleted();
    }
  }

  public Observable<T> getService() {
    return serviceSubject.first();
  }

  public BehaviorSubject<T> getBehavior() {
    return serviceSubject;
  }
}


Чтобы все собралось добавляем в Градл скрипт лямбды и саму RX
apply plugin: 'me.tatarka.retrolambda'

buildscript {
    dependencies {
        classpath 'me.tatarka:gradle-retrolambda:3.2.3'
    }
}

android {

dependencies {

    compile 'io.reactivex:rxjava:1.1.6'
    compile group: 'io.reactivex', name: 'rxandroid', version: '1.2.1'
  }
}

В первых 2 классах нет ничего необычного. Они цельнотянуты со стека. Третий класс реализует подключение к сервису на RX. Идея проста: Вместо лисенеров "onServiceConnected" мы используем бехевиор, который выполняет за нас всю нудную работу отслеживания состояний.

Как это использовать?


Создадим новый сервис:


public class SimpleService extends BoundService {

  public static class Connector extends ServiceConnector<SimpleService> {
    public Connector(Context context) {
      super(context, SimpleService.class);
    }
  }

}



В активности подключаем его:


  private Observable<SimpleService> simpleService;
  public void onCreate(Bundle savedInstanceState) {
...
    simpleService = new SimpleService.Connector(this).getService();
 }



И все. Можно работать с сервисом:


 simpleService.subscribe(service -> {
      Log.v(TAG, service.getPackageCodePath()); // например
    });



Все RX фишки здесь прекрасно работают. Например:


simpleService.map(SimpleService::getCloningDataType).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        .subscribe(data -> Log.v(TAG,data));




Как видно это гораздо проще чем создавать ServiceConnection а потом отслеживать все его состояния.
From:
Anonymous( )Anonymous This account has disabled anonymous posting.
OpenID( )OpenID You can comment on this post while signed in with an account from many other sites, once you have confirmed your email address. Sign in using OpenID.
User
Account name:
Password:
If you don't have an account you can create one now.
Subject:
HTML doesn't work in the subject.

Message:

 
Notice: This account is set to log the IP addresses of everyone who comments.
Links will be displayed as unclickable URLs to help prevent spam.

March 2017

S M T W T F S
   1234
5678 91011
12131415161718
19202122232425
262728293031 

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 27th, 2017 04:51 am
Powered by Dreamwidth Studios