NativeScript / android

NativeScript for Android using v8
https://docs.nativescript.org/guide/android-marshalling
Apache License 2.0
523 stars 134 forks source link

TypeScript Worker code cannot access native Android classes when called a second time on a real Android device #1683

Closed darkyelox closed 2 years ago

darkyelox commented 2 years ago

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

Describe the bug When calling a worker that instantiate a HashMap everything goes well until it runs a second time (the code is executed after a login, so if the user closes session and enters again it breaks) Only happens in a real device but not in a Genymotion emulator, this is the error output and my TypeScript worker code:

The error on onerror callback:

JS: WORKER ERROR {
JS:   "message": "Uncaught TypeError: java.util.HashMap is not a constructor",
JS:   "stackTrace": "TypeError: java.util.HashMap is not a constructor\n    at sendDeleteWithParams (file:///data/data/org.nativescript.acrapp/files/app/src_app_modules_shared_tools_android-tools_worker_android_ts.js:59:24)\n    at context.onmessage (file: src/webpack:/@nativescript/template-hello-world-ng/src/app/modules/shared/tools/android-tools.worker.android.ts:21:0)",
JS:   "filename": "file:///data/data/org.nativescript.acrapp/files/app/src_app_modules_shared_tools_android-tools_worker_android_ts.js",
JS:   "lineno": 59
JS: }
// android-tools.worker.android.ts
require('globals')

enum Messages {
    SEND_DELETE_WITH_BODY = 'SEND_DELETE_WITH_BODY'
}

interface SendDeleteWithBodyParams {
    url: string
    body: Record<string, unknown>
    headers: Record<string, string>
}

const context: Worker = self as any

context.onmessage = event => {
    const workerMessage = event.data
    switch (workerMessage.eventType) {
        case Messages.SEND_DELETE_WITH_BODY:
            const params = workerMessage.params as SendDeleteWithBodyParams

            console.log('WORKER DELETE WITH PARAMS', params)

            sendDeleteWithParams(params)

            break
    }
}

function sendDeleteWithParams(params: SendDeleteWithBodyParams) {
    const { url, body, headers } = params as SendDeleteWithBodyParams

    const headersMap = new java.util.HashMap<string, string>(); // Here it breaks on second call.

    Object.keys(headers).forEach(header => {
        const headerValue = headers[header]

        headersMap.put(header, headerValue)
    })

    const responseText = org.acrapp.Tools.sendDeleteWithParams(url, headersMap, JSON.stringify(body))

    const content = JSON.parse(responseText);

    context.postMessage(content)
}
// some function where it returns an RxJS Observable.
if (isAndroid) {
    return new Observable((emitter) => {
        const worker = new Worker('./android-tools.worker')

        worker.onmessage = event => {
            const content = event.data as Record<string, unknown>

            emitter.next(content as T)
            emitter.complete()
        }

        worker.onerror = event => {
            console.log('WORKER ERROR', event)
            emitter.error(new Error(event.message))
        }

        worker.postMessage({
            eventType: Messages.SEND_DELETE_WITH_BODY,
            params: {
                url,
                body, 
                headers
            } as SendDeleteWithBodyParams
        } as AndroidToolsWorkerMessage)

        return () => {
            Console.debug('TERMINATE WORKER')
            worker.terminate()
        }
    })
}

It seems like for some reason cannot access native code from my worker in second call. What could I do to prevent this?

To Reproduce Simply call a worker a second time with some java or android native code on a real device.

Expected behavior Don't break on devices, emulators goes well.

Additional context Running my code in a Moto G7 Plus Android 10, doesn't happen in a Genymotion Emulator (User can logging out and in many times and the worker works every time).

rigor789 commented 2 years ago

I believe 8.2.0 should fix this.