2016-06-17 3 views
0

私はネットワーク操作を含む次のようなコードを用意しています。私はよく知られているエラーError in http connectionandroid.os.NetworkOnMainThreadExceptionを得て、それはかなり説明的で、例えばhereと説明されています。RxAndroid - http connectionandroid.os.NetworkOnMainThreadExceptionのエラー

私が理解できないことは、Scheduler.io()を明確に購読すると、ここでどのようにエラーが発生するかです。何が間違っていますか?

ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(mContext); 
locationProvider.getLastKnownLocation().subscribeOn(Schedulers.io()).subscribe((location -> { 
    // ... unrelated code 
    try { 
     this.postPing(pingResponse); // <<< this is an http post causing the error 
     Log.d(LOG_TAG, "trying to post response"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    cursor.close(); 

編集:これは全く些細なことではないようです。だから私は追加の文脈を提供している。

このように見えるとReactiveLocationProviderを使用していないが、むしろFusedLocationApi

Location location = LocationServices.FusedLocationApi.getLastLocation(MainActivity.mGoogleApiClient); 
        // ... unrelated code 
        try { 
         this.postPing(pingResponse); 
         Log.d(LOG_TAG, "trying to post response"); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
        cursor.close(); 

そしてGcmListenerService内から実行された使用コードの上:

@Override 
    public void onMessageReceived(String from, Bundle data) { 
     Log.d("GCMListener", "onMessageReceived"); 
     String action = data.getString("action"); 
     switch (action) { 
      case "getPing": 
       requests.getPingObservable() 
         .subscribeOn(Schedulers.io()).retryWhen(
         errors -> 
           errors 
             .zipWith(Observable.range(1, 3), (n, i) -> i) 
             .flatMap(retryCount -> Observable.timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS)) 
         ).subscribe((pingsJsonObjectString) -> { 
       }, (error) -> error.printStackTrace()); 
       break; 
      default: 
       break; 
     } 
    } 

残念ながらGcmListenerService」はdoesnのアプリが終了したときに通知を受け取ります。だから私はちょっと騙して警報を発し、受信機を警報で作動させることにした。 AndroidMainfest.xml

私はラインに<category android:name="com.smilingkoala.ping.periodic_wakeup"/>

<!-- The Google Cloud Messaging receiver and services --> 
     <receiver 
      android:name="com.google.android.gms.gcm.GcmReceiver" 
      android:exported="true" 
      android:permission="com.google.android.c2dm.permission.SEND"> 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
       <category android:name="com.smilingkoala.ping" /> 
       <category android:name="com.smilingkoala.ping.periodic_wakeup"/> 
      </intent-filter> 
     </receiver> 

を追加し、MainActivity.javaに私が呼ばれる:

public void startAlarm(Context context) { 
    Intent intent = new Intent("com.smilingkoala.ping.periodic_wakeup"); 
    PendingIntent sender = PendingIntent.getService(context, 0, intent, 0); 
    AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
    am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
      AlarmManager.INTERVAL_FIFTEEN_MINUTES/3, AlarmManager.INTERVAL_FIFTEEN_MINUTES, sender); 
} 

アプリケーションが閉じられた後にリスナーを再起動するには。 これは実際に働いた。私はメッセージを受け取りました。しかし、私は古いコードで使用したMainActivity.mGoogleApiClientにアクセスできませんでした。だから、私は強制的にReactiveLocationProviderを使用しました。しかし、今私はネットワークコードを実行することはできません。

私は、このエラーにつながった何かが禁止されていると仮定します。

+0

登録はUIスレッドで行われますか? –

+0

@ cricket_007私が正しく理解しているかどうかはよくわかりませんが、上記のコードをスニップしたスクリプトを意味する場合は、いいえ。これは 'Schedulers.io'でも呼ばれたオブザーバブルの一部です。 – Lukasz

+0

'this.postPing(pingResponse);はメインスレッドで起こっているようですが、そうですか?それ以外の場合は、なぜエラーが発生していますか? –

答えて

2

[OK]を、私は100%確実ではないですが、のは、この(説明してみましょう:あなたは.subscribeOnオペレータにdocumentationを読めば、あなたはそれが上で観察スケジューラ自体(ない定義されていることがわかります

を!。加入者)が実行されますあなたは、明示的に.observeOnオペレータと加入者のためのスケジューラを定義する必要があり、あるいはそれが上のサブスクライブされた場所のスレッド上で実行されます

より詳細な情報と例については、あなたがこれらのリンクをチェックする必要があります。 http://www.grahamlea.com/2014/07/rxjava-threading-examples/ http://www.introtorx.com/Content/v1.0.10621.0/15_SchedulingAndThreading.html#SubscribeOnObserveOn

また、Thread.currentThread()を呼び出して、実行しているコードがどこかを確認することで、スレッド化をデバッグして試すことができます。

+0

私がsubscribeOnとobserveOnを混ぜて言ったように。それを解決した人たちを変える。ありがとう。 – Lukasz

+0

あなたは大歓迎です! – aleien

関連する問題