android - RxJava - Is an operator a task or the whole chain a task? -


i'm writing code insert record sqlite database (if table empty). before inserts data, makes web service call lovetodo.basecampclient().fetchme() return data.

i'm using sqlbrite database access , retrofit web access. here code:

    observable.just(lovetodo.britedatabase())         .map(new func1<britedatabase, integer>() {             @override             public integer call(britedatabase britedatabase) {                 cursor cursor = britedatabase.query("select * accounts");                  try {                     return cursor.getcount();                  } {                     cursor.close();                 }             }         })         .flatmap(new func1<integer, observable<person>>() {             @override             public observable<person> call(integer count) {                 if ( count == 0 ) {                     return lovetodo.basecampclient().fetchme();                 }                  return null;             }         })         .map(new func1<person, boolean>() {             @override             public boolean call(person person) {                 if ( person == null ) return false;                  britedatabase database = lovetodo.britedatabase();                  long count = database.insert(account.table, new account.builder()                     .accountid(settings.accountid)                     .username(settings.username)                     .password(settings.password)                     .agent(settings.agent)                     .personid(person.id)                     .build()                 );                  return count > 0;             }         })          .subscribeon(schedulers.io())         .observeon( schedulers.io() )          .subscribe(); 

needless say, don't think fantastic code. do, find out how transform code good. let's use , pick @ horribleness.

first, should combine database , web service call operations in 1 operator. example:

    observable.just(lovetodo.britedatabase())         .flatmap(new func1<britedatabase, observable<person>>() {             @override             public observable<person> call(britedatabase britedatabase) {                 cursor cursor = britedatabase.query("select * accounts");                  int count;                 try {                     count = cursor.getcount();                  } {                     cursor.close();                 }                  if ( count == 0 ) {                     return lovetodo.basecampclient().fetchme();                 }                  return null;             }         })         .map(new func1<person, boolean>() {             @override             public boolean call(person person) {                 if ( person == null ) return false;                  britedatabase database = lovetodo.britedatabase();                  long count = database.insert(account.table, new account.builder()                         .accountid(settings.accountid)                         .username(settings.username)                         .password(settings.password)                         .agent(settings.agent)                         .personid(person.id)                         .build()                 );                  return count > 0;             }         })          .subscribeon(schedulers.io())         .observeon(schedulers.io())          .subscribe(); 

or there reason keep such operations isolated in chain?

the second thing bugs me background operation - no user interface updated directly result of code. that's why there's parameterless subscribe() function call. happens when there's exception? mean i'd have following?

        .subscribe(new action1<boolean>() {             @override             public void call(boolean aboolean) {                 // nothing             }         }, new action1<throwable>() {             @override             public void call(throwable throwable) {                 // exception             }         }); 

by way, need subscribeon when observeon set background thread?

thirdly, chain started sqlbrite observer. later in chain need sqlbrite again, access using singleton lovetodo.britedatabase(). bad idea? there better way this?

finally, there way break; chain? it'd nice if drop i'm doing rather checking missing data @ each step

i see lot of questions.

  1. each method/operator "task" run based on previous items , emit items next operators.
  2. to reduce code verbocity use retrolambda or gradle retrolamda rxjava. if don't want use retolambda can create class namemodel contains logic observable creation before subscribe(). in there have needed logic, isolated.
  3. it's great idea have onerror func in subscribe if have network call, unless catch possible errors somewhere before e.g. onerrorreturn. onerror there if goes wrong e.g. notify user. it's practise update in subscribe , not inside chain, isolate operator's content.
  4. the subscribeon makes process on background, not observeon. no, observeon not needed if don't change thread, example here.
  5. the best way "break" chain throw error or more complex unsubscribe chain inside using custom .lift() operator custom subscriber.

update based on comment:

from 2 above second prefer that:

observable.just(lovetodo.britedatabase())         .flatmap(britedatabase -> {             cursor cursor = britedatabase.query("select * accounts");              int count;             try {                 count = cursor.getcount();              } {                 cursor.close();             }              if (count == 0) {                 return lovetodo.basecampclient().fetchme()                         .map(person -> insertperson(person, britedatabase));             }              // if want track account creation             return just(false);         })         .subscribeon(schedulers.io())         .subscribe(personinserted -> {             // if person created or not         }, e -> {         });   private boolean insertperson(person person, britedatabase britedatabase) {     long count = britedatabase.insert(account.table, new account.builder()             .accountid(settings.accountid)             .username(settings.username)             .password(settings.password)             .agent(settings.agent)             .personid(person.id)             .build());      return count > 0; } 

Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -