react-native-background-actions icon indicating copy to clipboard operation
react-native-background-actions copied to clipboard

Task started but not running on Android (OK on iOS)

Open adriendomoison opened this issue 1 year ago • 12 comments

Hi, I'm running into an issue on Android only. The app shows no signs of errors on the JS side. The background notification shows and remains displayed indefinitely in the notification bar, but nothing happens, the task function is never called.

await BackgroundService.start(
  async () => {
    console.log('I am never called'); // never printed
  },
  {
    taskName: 'Sending Message',
    taskTitle: 'Sending Message',
    taskDesc: 'Sending Message',
    taskIcon: {
      name: 'ic_launcher',
      type: 'mipmap',
    },
  },
);
console.log(
  'Background service is running > ', BackgroundService.isRunning(),
); // print "Background service is running > true"

Android Studio does give me an error when the background service is started however.

Logcat
E  Exception in native call from JS
com.facebook.react.common.JavascriptException: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, stack:
Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime
    at queueMicrotask (native)
    at anonymous (http://localhost:8081/index.bundle/:347048:25)
    at anonymous (http://localhost:8081/index.bundle/:397427:7)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)
    at anonymous (http://localhost:8081/index.bundle/:396674:62)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)
    at anonymous (http://localhost:8081/index.bundle/:396612:58)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)
    at anonymous (http://localhost:8081/index.bundle/:396546:46)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)
    at anonymous (http://localhost:8081/index.bundle/:396056:62)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)

Attempting to call JS function on a bad application bundle: HMRClient.setup()
Exception in native call
java.lang.RuntimeException: Attempting to call JS function on a bad application bundle: HMRClient.setup()
    at com.facebook.jni.NativeRunnable.run(Native Method)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:235)
    at java.lang.Thread.run(Thread.java:920)

Attempting to call JS function on a bad application bundle: AppRegistry.startHeadlessTask()
Unable to launch redbox because react activity is not available, here is the error that redbox would've displayed: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime, stack:
Error: Exception in HostFunction: Could not enqueue microtask because they are disabled in this runtime
    at queueMicrotask (native)
    at anonymous (http://localhost:8081/index.bundle/:347048:25)
    at anonymous (http://localhost:8081/index.bundle/:397427:7)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)
    at anonymous (http://localhost:8081/index.bundle/:396674:62)
    at loadModuleImplementation (http://localhost:8081/index.bundle/:268:14)
    at guardedLoadModule (http://localhost:8081/index.bundle/:176:38)
    at metroRequire (http://localhost:8081/index.bundle/:90:92)

Exception in native call
java.lang.RuntimeException: Attempting to call JS function on a bad application bundle: RCTDeviceEventEmitter.emit()
    at com.facebook.jni.NativeRunnable.run(Native Method)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:235)
    at java.lang.Thread.run(Thread.java:920)

Unable to launch redbox because react activity is not available, here is the error that redbox would've displayed: Attempting to call JS function on a bad application bundle: AppRegistry.startHeadlessTask()
Attempting to call JS function on a bad application bundle: RCTDeviceEventEmitter.emit()
UIManagerBinding::~UIManagerBinding() was called
CatalystInstanceImpl.destroy() end

I did set up the AndroidManifest.xml according to the documentation (adding permissions and service)

The app is running on [email protected] and [email protected]

build.gradle
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply plugin: 'com.google.gms.google-services'

def getPassword(String currentUser, String keyChain) {
   def stdout = new ByteArrayOutputStream()
   def stderr = new ByteArrayOutputStream()
   exec {
       commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-s', keyChain, '-w'
       standardOutput = stdout
       errorOutput = stderr
       ignoreExitValue true
   }
   stdout.toString().trim()
}

react {
 
    /* Autolinking */
    autolinkLibrariesWithApp()

    // Added by install-expo-modules
    entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", rootDir.getAbsoluteFile().getParentFile().getAbsolutePath(), "android", "absolute"].execute(null, rootDir).text.trim())
    cliFile = new File(["node", "--print", "require.resolve('@expo/cli')"].execute(null, rootDir).text.trim())
    bundleCommand = "export:embed"
}

def enableProguardInReleaseBuilds = false
def jscFlavor = 'org.webkit:android-jsc:+'
def pass = getPassword("[email protected]", "android_keystore")

android {
    ndkVersion rootProject.ext.ndkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    compileSdk rootProject.ext.compileSdkVersion

    namespace "app.app.app"
    defaultConfig {
        applicationId "app.app.app"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 10
        versionName "0.3.15"
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword pass
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword pass
            }
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
}

dependencies {
    implementation("com.facebook.react:react-android")

    if (hermesEnabled.toBoolean()) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }
}
MainApplication.kt
package app.app.app
import android.content.res.Configuration
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ReactNativeHostWrapper

import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader

class MainApplication : Application(), ReactApplication {

  override val reactNativeHost: ReactNativeHost =
      ReactNativeHostWrapper(this, object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply {
              // Packages that cannot be autolinked yet can be added manually here, for example:
              // add(MyReactNativePackage())
            }

        override fun getJSMainModuleName(): String = "index"

        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

        override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
      })

  override val reactHost: ReactHost
    get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)

  override fun onCreate() {
    super.onCreate()
    SoLoader.init(this, false)
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      load()
    }
    ApplicationLifecycleDispatcher.onApplicationCreate(this)
  }

  override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
  }
}

Any insights would be greatly appreciated. Thank you!

adriendomoison avatar Sep 12 '24 01:09 adriendomoison

can you please the steps for ios. My android is running but not ios.

somasekharkakarla avatar Sep 16 '24 20:09 somasekharkakarla

It's not starting for me at all in Android, any solutions yet? The app is running on [email protected] and [email protected]

ravindraguptacapgemini avatar Oct 22 '24 18:10 ravindraguptacapgemini

Switching newArchEnabled=true to newArchEnabled=false in android/gradle.properties allowed the started task to actually run.

I'm not sure if this needs to be documented or if it already exists somewhere I could not find?

adriendomoison avatar Oct 28 '24 04:10 adriendomoison

@adriendomoison I am facing the same issue it's working fine on iOS with newArchEnabled but in android it fails, Is there any fix to work with newArchEnabled?

tohel17 avatar Oct 28 '24 10:10 tohel17

@tohel17

AFAIK, you need to wait for RN 0.76.1 (coming in a few days) for the library to work on New Arch.

Source: https://github.com/invertase/react-native-firebase/issues/8091#issuecomment-2440499904

shovel-kun avatar Oct 28 '24 12:10 shovel-kun

@tohel17 what about the fix in 0.75.x version?

ravindraguptacapgemini avatar Oct 28 '24 15:10 ravindraguptacapgemini

I am on 0.75.4 still same issues. Looks like you have to wait for 0.76.1

tohel17 avatar Oct 28 '24 15:10 tohel17

To add some more info, a good amount of other packages do not work yet with 0.76.x and it could take several extra weeks for maintainers to deliver the required updates.

Depending on how many dependencies you have in your current project and how much you are using the newArch already, it could be easier to just stay on 0.75.x and disable newArch.

The decision will highly depends on your circumstances ✌️

adriendomoison avatar Oct 28 '24 19:10 adriendomoison

It works fine with latest version of RN 0.76.3 with new architecture enabled.

tohel17 avatar Nov 04 '24 13:11 tohel17

Can we expect it to start working with any RN 0.75.x release?

ravindraguptacapgemini avatar Nov 05 '24 09:11 ravindraguptacapgemini

@ravindraguptacapgemini Since the issue was on RN side either you have to update to 0.76.1 or use old architecture on 0.75.x version.

tohel17 avatar Nov 05 '24 09:11 tohel17

I don't see newer react native version under releases https://github.com/facebook/react-native/releases

ravindraguptacapgemini avatar Nov 05 '24 09:11 ravindraguptacapgemini