【问题标题】:RxJava - Can't create handler inside thread that has not called Looper.prepare() - API 16RxJava - 无法在未调用 Looper.prepare() 的线程内创建处理程序 - API 16
【发布时间】:2017-10-24 03:09:57
【问题描述】:

完全披露,我还在学习 RxJava,如果许多可用的教程对新手不友好,这有点难以理解。

此错误发生在 API 16 上,在 API 23 及更高版本上运行良好(已在下面测试)。

如您所见,我正在尝试用 RxJava 替换 Async Task。

这是我的代码:

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);
            });
}

编辑:下面的堆栈:

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)

【问题讨论】:

    标签: android rx-java


    【解决方案1】:

    您不能在Scheduler 线程中显示与 UI 相关的内容。您正在尝试显示Toast,而且我认为您的showSettingsAlert() 也在尝试显示对话框。

    这违反了线程策略。非常相似

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

    【讨论】:

    • 啊,这就是错误。您可以在前后显示它,但不能在后台线程期间显示。
    • 是的,没错。它可以进入你的 doOnSubscribe() 和 subscribe() 块,但不能进入 BG 线程。
    猜你喜欢
    • 2015-11-07
    • 2017-01-13
    • 2018-05-13
    • 1970-01-01
    • 2012-08-15
    • 2011-09-06
    • 1970-01-01
    相关资源
    最近更新 更多