【问题标题】:Calendar.Events?.get(calendarId, eventId) throws a android.os.NetworkOnMainThreadException errorCalendar.Events?.get(calendarId, eventId) 抛出 android.os.NetworkOnMainThreadException 错误
【发布时间】:2020-04-03 08:25:23
【问题描述】:

我有一个问题,如果我使用 Google 日历 Java 库通过 ID 搜索事件,它不会返回任何内容并引发错误。我有以下代码:


@Module
class GoogleCalendarsApiServiceModule @Inject constructor(): IGoogleCalendarsApiServiceModule {

    private lateinit var googleCalendarService: Calendar

    private val httpTransport: NetHttpTransport = NetHttpTransport()
    private val subscriptions: Disposable = Disposable.empty()

    init {
        this.subscriptions.apply {
            AndroidContextObservable.context()
                .subscribe { context ->
                    val googleCredential = GoogleCredentialsBuilder.getCredentials(httpTransport, context)
                    googleCalendarService = ServiceBuilder.buildGoogleCalendarService(googleCredential, httpTransport)
                }
        }
    }

    fun finalize() {
        this.subscriptions.dispose()
    }

    override fun getEventById(eventId: String): Observable<Event> {
        return Observable.create { subscriber ->
            val calendarEvents: Calendar.Events? = googleCalendarService.events()

            val event: Event = calendarEvents!!
                .get("primary", eventId)
                .execute()

            subscriber.onNext(event)
            subscriber.onComplete()
        }
    }
}

然后被服务称为上一层映射:

@Module
class GoogleCalendarService @Inject constructor(): IGoogleCalendarService {

    @Inject
    lateinit var googleCalendarsApiServiceModule: GoogleCalendarsApiServiceModule

    init {
        DaggerServiceModuleComponent.create().inject(this)
    }

    override fun getCalendarEventById(eventId: String): Observable<MeetingEvent> {
        return this.googleCalendarsApiServiceModule.getEventById(eventId)
            .map { mapMeetingEvent(it) }
            .onErrorReturn { throw Exception(it) }
    }
}

然后我得到错误:I/System.out: io.reactivex.rxjava3.exceptions.CompositeException: 2 exceptions occurred.

当我调试时,问题来自 Calendar.Events?.get() 没有返回任何内容。我对此感到有些困惑,因为如果我转到 https://developers.google.com/calendar/v3/reference/events/get 并使用 ID 为...的交互式 API,比如说 2ilol72ocluq4i1mvlbqn7egel(实际存在并被此应用程序使用的事件 ID),我会得到以下回复:

{
 "kind": "calendar#event",
 "etag": "\"3168457487134000\"",
 "id": "2ilol72ocluq4i1mvlbqn7egel",
 "status": "confirmed",
 "htmlLink": "https://www.google.com/calendar/event?eid=Mmlsb2w3Mm9jbHVxNGkxbXZsYnFuN2VnZWwgZnJlZW1hbi5tYXJjODgwQG0",
 "created": "2020-03-14T23:32:23.000Z",
 "updated": "2020-03-14T23:32:23.567Z",
 "summary": "TEST123",
 "description": "Test123",
 "location": "IKEA Room",
 "creator": {
  "email": "example@email.com",
  "self": true
 },
 "organizer": {
  "email": "example@email.com",
  "self": true
 },
 "start": {
  "dateTime": "2020-03-14T23:32:00Z"
 },
 "end": {
  "dateTime": "2020-03-15T00:32:00Z"
 },
 "iCalUID": "2ilol72ocluq4i1mvlbqn7egel@google.com",
 "sequence": 0,
 "reminders": {
  "useDefault": true
 }
}

有人对可能导致问题的原因有任何建议吗?

我也尝试仅获取列表并根据 ID 对其进行过滤:

    override fun getCalendarEventsByRoomName(eventId: String): Observable<Event> {
        return Observable.create { subscriber ->
            val now = DateTime(System.currentTimeMillis())
            val events: Calendar.Events? = googleCalendarService.events()

            val event = events!!.list("primary")
                .setQ(eventId) // <-- use the event ID as a query
                .setMaxResults(1)
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute()

            subscriber.onNext(event )
            subscriber.onComplete()
        }
    }

但这不会返回任何内容,这与 googleCalendarService.events().list() 的交互式 API 中的结果相同

编辑:进一步调试发现以下错误:

android.os.NetworkOnMainThreadException

表示可疑代码行在调用活动中:

class ViewMeetingEventDataActivity: AppCompatActivity() {

    @Inject lateinit var bundleUtilityModule: BundleUtilityModule
    @Inject lateinit var fragmentUtilityModule: FragmentUtilityModule
    @Inject lateinit var googleCalendarService: GoogleCalendarService

    private val subscriptions: Disposable = Disposable.empty()
    private lateinit var eventId: String
    private lateinit var event: MeetingEvent;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        AndroidContextObservable.setContext(this)
        DaggerServiceModuleComponent.create().inject(this)
        DaggerUtilityModuleComponent.create().inject(this)

        this.eventId = intent.getStringExtra(BundleData.MEETING_EVENT_ID.name)!!
        this.subscriptions.apply {
            googleCalendarService.getCalendarEventById(eventId)
                .subscribe(
                    { meetingEvent: MeetingEvent -> event = meetingEvent; println(meetingEvent.description + "Hello") },
                    {}
                )
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        this.subscriptions.dispose()
    }
}

this._subscriptions.apply {} 被调用的地方。

【问题讨论】:

    标签: android kotlin rx-java google-calendar-api


    【解决方案1】:

    设法用以下代码解决了这个问题:

    this.subscriptions.apply {
        googleCalendarService.getCalendarEventById(eventId)
            .subscribeOn(Schedulers.io())
            .subscribe(
                { meetingEvent: MeetingEvent -> event = meetingEvent },
                {}
            )
    }
    

    问题是原来的块:

    this.subscriptions.apply {
        googleCalendarService.getCalendarEventById(eventId)
            .subscribe(
                { meetingEvent: MeetingEvent -> event = meetingEvent },
                {}
            )
        }
    

    在调用活动中阻塞了主 UI 线程。然而,这个错误被 GoogleCalendarService 吞噬了。我们现在打电话给subscribeOn() 来解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多