2017-05-24 2 views
1

전체 공개, RxJava를 배우고 있습니다. 사용할 수있는 자습서가 많지 않다면 아이디어를 이해하기가 약간 어렵습니다. 초보자 친화적 인.RxJava - Looper.prepare()를 호출하지 않은 스레드에서 핸들러를 생성 할 수 없음 - API 16

이 오류는 API 16에서 발생하며 위의 API 23 & (아래 테스트 됨)에서 정상적으로 작동합니다.

알 수 있듯이 비동기 작업을 RxJava로 대체하려고합니다.

private void getGps() { 
    TrackGPS gps = new TrackGPS(this); 
    Single.fromCallable(() -> { 
     if (gps.canGetLocation()) { 
      mMainVariables.setLongitude(gps.getLongitude()); 
      mMainVariables.setLatitude(gps.getLatitude()); 

      if (mMainVariables.getLongitude() != 0.0) { 
       Geocoder geocoder; 
       List<Address> addresses = null; 

       geocoder = new Geocoder(this, Locale.getDefault()); 
       addresses = geocoder.getFromLocation(mMainVariables.getLatitude(), mMainVariables.getLongitude(), 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5 
       Log.e("Address:", addresses.get(0).getAddressLine(0)); 
       mMainVariables.setAddress(addresses.get(0).getAddressLine(0)); 
       mMainVariables.setCity(addresses.get(0).getLocality()); 
       mMainVariables.setState(addresses.get(0).getAdminArea()); 
       mMainVariables.setCountry(addresses.get(0).getCountryName()); 
       mMainVariables.setPostalCode(addresses.get(0).getPostalCode()); 
       mMainVariables.setKnownName(addresses.get(0).getFeatureName()); 
       Log.d("Lat Long:", "Lat: " + Double.toString(mMainVariables.getLatitude()) + " Long: " + Double.toString(mMainVariables.getLongitude())); 
       return addresses.get(0).getAddressLine(0); 
      } else { 
       gps.showSettingsAlert(); 
      } 

     } else { 
      Toasty.error(this, "Can't locate GPS", Toast.LENGTH_SHORT, true).show(); 
     } 
     return ""; 
    }).subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe((result) -> { 
       mTxtResult.setText(result); 
      }); 
} 

편집 : : 아래 스택 : 당신은 당신의 Scheduler 스레드에서 UI 관련 물건을 표시 할 수 없습니다

05-23 20:26:58.936 3420-3420/com.example.ga.realm3 E/AndroidRuntime: FATAL EXCEPTION: main 
                   io.reactivex.exceptions.OnErrorNotImplementedException: Can't create handler inside thread that has not called Looper.prepare() 
                    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) 
                    at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) 
                    at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:45) 
                    at io.reactivex.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:79) 
                    at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) 
                    at android.os.Handler.handleCallback(Handler.java:730) 

답변

1

내 코드입니다. Toast을 표시하려고하고 있으며 또한 showSettingsAlert()도 대화 상자를 표시하려고한다고 가정합니다.

이것은 스레딩 정책에 위배됩니다. 그 오류, 그래서

Can't create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog

+0

매우 유사. 이전 및 이후에는 표시 할 수 있지만 백그라운드 스레드에서는 표시 할 수 없습니다. – Rosenberg

+0

예. 맞습니다. doOnSubscribe() 및 subscribe() 블록에는 있지만 BG 스레드에는 들어갈 수 없습니다. –