在rxJava函数中由于foreach而崩溃android设备

时间:2017-04-20 04:15:58

标签: java android java-8 rx-java

我在我的应用程序中使用rxJava。而且我经常使用这样的代码:

couponListInteractor.getObservableData(storeId)
        .subscribe(data -> 
                data.forEach(item ->
                {
                    if (!couponsCode.contains(item.getCode()))
                    {
                        couponsCode.add(item.getCode());
                    }
                }
        );

当我在我的模拟器中开发应用程序时,一切都很好。但是当我开始在设备中测试我的应用程序(4.0 android版本)。我得到了一些错误。

FATAL EXCEPTION: RxNewThreadScheduler-1
                                                                        Process: com.mrrebates.cashback, PID: 20428
                                                                        java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
                                                                            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59)
                                                                            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                            at java.lang.Thread.run(Thread.java:818)
                                                                         Caused by: java.lang.NoClassDefFoundError: com.couponautoapplier.cashback.model.api.apistorage.DataConfigApiStorage$1$$Lambda$1
                                                                            at com.couponautoapplier.cashback.model.api.apistorage.DataConfigApiStorage$1.call(DataConfigApiStorage.java:50)
                                                                            at com.couponautoapplier.cashback.model.api.apistorage.DataConfigApiStorage$1.call(DataConfigApiStorage.java:28)
                                                                            at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
                                                                            at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:41)
                                                                            at retrofit2.adapter.rxjava.OperatorMapResponseToBodyOrError$1.onNext(OperatorMapResponseToBodyOrError.java:38)
                                                                            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:173)
                                                                            at rx.Subscriber.setProducer(Subscriber.java:211)
                                                                            at rx.internal.operators.OnSubscribeMap$MapSubscriber.setProducer(OnSubscribeMap.java:102)
                                                                            at rx.Subscriber.setProducer(Subscriber.java:205)
                                                                            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)
                                                                            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)
                                                                            at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
                                                                            at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
                                                                            at rx.Observable.unsafeSubscribe(Observable.java:10200)
                                                                            at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
                                                                            at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
                                                                            at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
                                                                            at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
                                                                            at rx.Observable.unsafeSubscribe(Observable.java:10200)
                                                                            at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)

我很容易纠正此错误:

couponListInteractor.getObservableData(storeId)
        .subscribe(data -> {
                for(CouponListItemViewModel item: data)
                {
                    if(!couponsCode.contains(item.getCode()))
                    {
                        couponsCode.add(item.getCode());
                    }
                }
          });

我是否必须更正到处纠正?

我不想这样做,因为它看起来很漂亮:

 couponsCode.forEach(value -> couponsCodes.add(new CouponsCode(value)));

2 个答案:

答案 0 :(得分:4)

问题是您在低于24的API级别使用Java 8的For Each row As DataGridViewRow In dgvLosshours.Rows If (row.Cells("losshrs").Value = "") Then MsgBox("Losshours can't Empty", MsgBoxStyle.Critical) Return Else Dim i As Integer = 0 Dim hd As Integer = row.Cells("headcount").Value * row.Cells("workhrs").Value - row.Cells("losshrs").Value Dim cmd1 As New MySqlCommand Dim mydt1 As New DataSet Dim myadapt1 As New MySqlDataAdapter openConnectionsMySQL() cmd1 = New MySqlCommand("select * from whweek where periode = date_format(NOW(), '%m-%Y') ", connectMySQL) myadapt1 = New MySqlDataAdapter(cmd1) myadapt1.Fill(mydt1, "list") connectMySQL.Dispose() If (mydt1.Tables(0).Rows.Count = 19) Then Dim c As String = "Update whweek losshours : " & row.Cells("losshrs").Value & ", RegularHours :" & hd With dgvLosshours dt = ctrl.ActionQuery("update whweek set workhrs = '" & row.Cells("workhrs").Value & "', losshours = '" & _ row.Cells("losshrs").Value & "', reghrs = '" & hd & "', Ke = '" & _ row.Cells("edate").Value & "', modifyby = '" & frmMenu.toolempno.Text & _ "', modifyon = '" & today & "' where CodeDept = '" & _ row.Cells("dept").Value & "' and class = '" & row.Cells("class").Value & "' ") dt = ctrl.ActionQuery("INSERT INTO log (EmpNo, Tanggal, Ket) VALUES ('" & frmMenu.toolempno.Text & "', '" & today & "', '" & c & "')") End With MsgBox("LossHours had been updated!") dgvLosshours.Rows.Clear() ElseIf (mydt1.Tables(0).Rows.Count = 0) Then Dim hd1 As Integer = row.Cells("headcount").Value * row.Cells("workhrs").Value - row.Cells("losshrs").Value Dim c As String = "Add LossHrs By :" & frmMenu.toolempno.Text & " Period : " & period dt = ctrl.ActionQuery("insert into whweek(codedept, class, workhrs, losshours, reghrs, Dari, Ke, createby, createon) values('" & _ row.Cells("dept").Value & _ "','" & row.Cells("class").Value & _ "','" & row.Cells("workhrs").Value & _ "','" & row.Cells("losshrs").Value & _ "','" & hd1 & "','" & _ row.Cells("sdate").Value & "', '" & _ row.Cells("edate").Value & "', '" & _ frmMenu.toolempno.Text & "','" & today & "')") dt = ctrl.ActionQuery("INSERT INTO log (EmpNo, Tanggal, Ket) VALUES ('" & _ frmMenu.toolempno.Text & "', '" & today & "', '" & c & "')") MsgBox("Successful Save LossHours") dgvLosshours.Rows.Clear() End If End If API。

目前仅支持API级别24。

Java 8功能支持机制最近已被改变,当时谷歌放弃了杰克和吉尔的新工具链,而lately announced支持Java 8功能使用旧的工具链,调用'desugar'来改变Java8类文件到Java 7兼容的类文件(可从Android Studio 2.4 Preview 6获得) 您可以阅读更多here

答案 1 :(得分:1)

感谢 yosriz 。 我使用:https://github.com/aNNiMON/Lightweight-Stream-API。 我的代码看起来像那样:

 couponsCode.forEach(value -> couponsCodes.add(new CouponsCode(value)));

我的代码现在看起来像这样:

 Stream.of(couponsCode).forEach(value -> couponsCodes.add(new CouponsCode(value)));

所有错误都消失了。