2017-10-10 6 views
0

J'apprends à la fois Kotlin et RxJava. Je Hava tel code en Java:Convertir correctement le code RxJava à Kotlin

public class MainActivity extends AppCompatActivity { 

private HashMap<String, Object> cacheToInsertToDb; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    cacheToInsertToDb = new HashMap<>(); 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(30) // up to 30 items 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Consumer<Long>() { 
       @Override 
       public void accept(Long aLong) throws Exception { 
        cacheToInsertToDb.put(aLong+"", aLong); 
        Log.d("Observable", cacheToInsertToDb.values().toString()); 
       } 
      }, new Consumer<Throwable>() { 
       @Override 
       public void accept(Throwable throwable) throws Exception { 

       } 
      }, new Action() { 
       @Override 
       public void run() throws Exception { 

       } 
      }); 

    Observable.interval(10, TimeUnit.SECONDS) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Consumer<Long>() { 
       @Override 
       public void accept(Long aLong) throws Exception { 
        proceedVlues(cacheToInsertToDb.values()); 
        cacheToInsertToDb.clear(); 
        Log.d("CLEARED", cacheToInsertToDb.values().toString()); 
       } 
      }, new Consumer<Throwable>() { 
       @Override 
       public void accept(Throwable throwable) throws Exception { 

       } 
      }, new Action() { 
       @Override 
       public void run() throws Exception { 

       } 
      }); 

} 

private void proceedVlues(Collection<Object> values) { 
     for(Object v: values){ 
      if(v instanceof Long){ 
       Log.d("proceedVlues", v+""); 
      } 
     } 
    } 
} 

Cependant, quand je convertir en tas il y a Android Studio d'erreurs dans l'IDE.

Ici, il est dans ce code Kotlin, converti dans Android Studio:

class MainActivity : AppCompatActivity() { 

private var cacheToInsertToDb: HashMap<String, Any>? = null 


override fun onCreate(savedInstanceState: Bundle?) { 
    super.onCreate(savedInstanceState) 
    setContentView(R.layout.activity_main) 

    cacheToInsertToDb = HashMap() 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(30) // up to 30 items 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(object : Consumer<Long> { 
       @Throws(Exception::class) 
       override fun accept(aLong: Long?) { 
        cacheToInsertToDb!!.put(aLong!!.toString() + "", aLong) 
        Log.d("Observable", cacheToInsertToDb!!.values.toString()) 
       } 
      }, Consumer { }, Action { }) 

    Observable.interval(10, TimeUnit.SECONDS) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(object : Consumer<Long> { 
       @Throws(Exception::class) 
       override fun accept(aLong: Long?) { 
        proceedVlues(cacheToInsertToDb!!.values) 
        cacheToInsertToDb!!.clear() 
        Log.d("CLEARED", cacheToInsertToDb!!.values.toString()) 
       } 
      }, Consumer { }, Action { }) 

} 

private fun proceedVlues(values: Collection<Any>) { 
    for (v in values) { 
     if (v is Long) { 
      Log.d("proceedVlues", v.toString() + "") 
     } 
     } 
    } 
} 

Il me donne l'erreur en soulignant "référence non résolue à @throws" et "accepter» l'emporte sur nothig". Comment puis-je convertir ce code Java correctement à Kotlin?

Répondre

1

En Kotlin vous pouvez remplacer les implémentations d'interfaces, ayant une seule méthode, pour une expression lambda (doc).

Tout comme Java 8, Kotlin prend en charge les conversions SAM. Cela signifie que les littéraux de fonction Kotlin peuvent être automatiquement convertis en implémentations d'interfaces Java avec une seule méthode par défaut, à condition que les types de paramètres de la méthode interface correspondent aux types de paramètres de la fonction Kotlin.

Cela vous donne:

.subscribe(
     { item: Long? -> 

     }, 
     { t: Throwable -> 

     }, 
     {//onComplete 

     }) 

également, selon si vous utilisez RxJava2 (doc):

RxJava 2.x n'accepte plus les valeurs nulles et ce qui suit donnera NullPointerException immédiatement ou comme un signal

À cause de cela, vous êtes sûr que vous ne recevez pas de null dans votre onNext et vous pouvez supprimer le contrôle de nullité

.subscribe(
     { item: Long -> 

     }, 
     { t: Throwable -> 

     }, 
     {//onComplete 

     }) 
1

Vous pouvez mettre à jour votre code en utilisant safe npe et lambdas. Parfois, le code converti de java en kotlin nécessite quelques retouches cosmétiques.

.subscribe(object : Consumer<Long> { 
        @Throws(Exception::class) 
        override fun accept(aLong: Long?) { 
         cacheToInsertToDb!!.put(aLong!!.toString() + "", aLong) 
         Log.d("Observable", cacheToInsertToDb!!.values.toString()) 
        } 
       }, Consumer { }, Action { }) 

à

.subscribe(Consumer<Long?>{ aLong -> 
        cacheToInsertToDb?.put(aLong?.toString() ?: "", aLong) 
        Log.d("Observable", cacheToInsertToDb?.values.toString()) 

      }, Consumer { }, Action { })