私はネットワーク操作を含む次のようなコードを用意しています。私はよく知られているエラー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
を使用しました。しかし、今私はネットワークコードを実行することはできません。
私は、このエラーにつながった何かが禁止されていると仮定します。
登録はUIスレッドで行われますか? –
@ cricket_007私が正しく理解しているかどうかはよくわかりませんが、上記のコードをスニップしたスクリプトを意味する場合は、いいえ。これは 'Schedulers.io'でも呼ばれたオブザーバブルの一部です。 – Lukasz
'this.postPing(pingResponse);はメインスレッドで起こっているようですが、そうですか?それ以外の場合は、なぜエラーが発生していますか? –