-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Environment
System:
OS: macOS 13.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 137.46 MB / 16.00 GB
Shell:
version: 3.2.57
path: /bin/bash
Binaries:
Node:
version: 18.20.8
path: ~/.nvm/versions/node/v18.20.8/bin/node
Yarn:
version: 1.22.19
path: /usr/local/bin/yarn
npm:
version: 10.8.2
path: ~/.nvm/versions/node/v18.20.8/bin/npm
Watchman:
version: 2024.12.02.00
path: /usr/local/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.2
- iOS 17.2
- macOS 14.2
- tvOS 17.2
- visionOS 1.0
- watchOS 10.2
Android SDK: Not Found
IDEs:
Android Studio: 2024.3 AI-243.26053.27.2432.13536105
Xcode:
version: 15.2/15C500b
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.15
path: /Users/ipaddev/.jenv/shims/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 18.0.0
wanted: 18.0.0
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.79.5
wanted: 0.79.5
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: false
newArchEnabled: false
iOS:
hermesEnabled: false
newArchEnabled: false
Things I’ve done to figure out my issue
- [ x] I used upgrade-helper to do my upgrade.
Upgrading version
0.79.5
Description
I'm upgrading from RN 0.78.3 to RN 0.79.5.
I have a custom module to handle push notifications.
On Android I implemented a background service which extends HeadlessJsTaskService
and overrides getReactNativeHost
, as my application does not implement ReactApplication
.
When upgrading to RN 0.79.5 I get a build error as getReactNativeHost
since this RN version has been marked as final
:
error: getReactNativeHost() in PushHeadless cannot override getReactNativeHost() in HeadlessJsTaskService protected ReactNativeHost getReactNativeHost() { ^ overridden method is final
I checked HeadlessJsTaskService.kt
source file (https://github.com/facebook/react-native/blob/v0.79.5/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/HeadlessJsTaskService.kt) and it still reports this in the comments:
/**
* Get the [ReactNativeHost] used by this app. By default, assumes [getApplication] is an instance
* of [ReactApplication] and calls [ReactApplication.reactNativeHost].
*
* Override this method if your application class does not implement `ReactApplication` or you
* simply have a different mechanism for storing a `ReactNativeHost`, e.g. as a static field
* somewhere.
*/
protected val reactNativeHost: ReactNativeHost
get() = (application as ReactApplication).reactNativeHost
But in ReactAndroid.api
(https://github.com/facebook/react-native/blob/v0.79.5/packages/react-native/ReactAndroid/api/ReactAndroid.api), the method is declared as follows:
public abstract class com/facebook/react/HeadlessJsTaskService : android/app/Service, com/facebook/react/jstasks/HeadlessJsTaskEventListener {
...
protected final fun getReactNativeHost ()Lcom/facebook/react/ReactNativeHost;
...
}
Is this comment still accurate?
Is there still a way to override getReactNativeHost
in custom headless tasks?
Reproducible demo
Create custom Task service which extend HeadlessJsTaskService
and try to override method getReactNativeHost
Example:
import android.app.Application;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import java.lang.reflect.InvocationTargetException;
import javax.annotation.Nullable;
/**
* called from PushMessagingService if app is closed or in background
*/
public class PushHeadless extends HeadlessJsTaskService {
private static final long TIMEOUT_DEFAULT = 60000;
@Override
protected ReactNativeHost getReactNativeHost() {
return PushReactHost.getReactNativeHost(getApplication());
}
@Override
protected @Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
try {
if (intent == null) {
return null;
}
Bundle extras = intent.getExtras();
if (extras == null) {
return null;
}
WritableMap messageMap = ((Push) intent.getParcelableExtra(PushHandler.MESSAGE)).toMap();
if(messageMap != null) {
// Prevents race condition where the user opens the app at the same time as a notification
// is delivered, causing a crash.
return new HeadlessJsTaskConfig(getTaskName(), messageMap, TIMEOUT_DEFAULT, true);
}
} catch (Exception e){
e.printStackTrace();
}
return null;
}
protected String getTaskName(){
return "TaHeadlessTask";
}