2016-12-13 6 views
2

React-Nativeでバックグラウンドサービスを実行しようとしています。私が聞いたことから、ネイティブのJavaで記述し、それを反応ネイティブコードに接続する必要があります。私はイベントを放出しようとすると、私はエラーを取得する:ReactネイティブReactContextライフサイクルがBEFORE_CREATEにスタックされました

Tried to access a JS module before the React instance was fully set up. Calls to should only happen once initialize() has been called on your native module. 

だから私は、モジュールが動作しているかどうかを確認するためのチェックを追加しました:

if (reactContext.getLifecycleState() == LifecycleState.RESUMED) 

しかし、それは常にfalseを返します。ライフサイクルがBEFORE_CREATEに止まっています。私はどのようにイベントを出すべきですか?

サービス:

public class TestService extends Service { 

double distance = 0.0; 
ReactContext reactContext; 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    reactContext = new ReactContext(getApplicationContext()); 
    new Timer().scheduleAtFixedRate(new TimerTask(){ 
     @Override 
     public void run(){ 
      WritableMap params = Arguments.createMap(); 
      distance+= 0.7; 
      Log.d("LOG", "Trying to send distance: "+distance+" on lifecycle: "+reactContext.getLifecycleState()); 
      params.putDouble("distance", distance); 
      sendEvent(reactContext, "updateDistance", params); 
     } 
    },0,1000); 
    return START_STICKY; 
} 

private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { 
    if (reactContext.getLifecycleState() == LifecycleState.RESUMED) { 
     reactContext.getJSModule(DeviceEventManagerModule 
       .RCTDeviceEventEmitter.class) 
       .emit(eventName, params); 
     Log.d("LOG", "Sent distance: "+distance); 
    } 
} 

@Nullable 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 
} 

モジュール:

public class ServiceModule extends ReactContextBaseJavaModule { 
ReactContext reactContext; 

public ServiceModule(ReactApplicationContext reactContext) { 
    super(reactContext); 
    this.reactContext = reactContext; 
    this.initialize(); 
} 

@ReactMethod 
public void startTrackingService() { 
    Intent intent = new Intent(reactContext, TestService.class); 
    reactContext.startService(intent); 
} 

@Override 
public String getName() { 
    return "ServiceModule"; 
} 
} 

パッケージ:

public class ServicePackage implements ReactPackage { 
@Override 
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { 
    List<NativeModule> modules = new ArrayList<>(); 
    modules.add(new ServiceModule(reactContext)); 
    return modules; 
} 

@Override 
public List<Class<? extends JavaScriptModule>> createJSModules() { 
    return Collections.emptyList(); 
} 

@Override 
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
    return Collections.emptyList(); 
} 
} 

MainApplication:

@Override 
protected List<ReactPackage> getPackages() { 
    return Arrays.<ReactPackage>asList(
     new MainReactPackage(), 
     new ReactNativePushNotificationPackage(), 
     new ServicePackage() 
); 
} 

答えて

3

私はそれを解決しました:) サービスでは、私は同じコンテキストではないベースコンテキストから新しいコンテキストを作成していました。この問題を回避するには、サービスからデータをブロードキャストしてから、javascriptを送信することでした。

ServiceModule:

public class ServiceModule extends ReactContextBaseJavaModule { 
public static String UPDATE = "updateDistance"; 
public static String DISTANCE = "distance"; 

private IntentFilter intentFilter; 
private BroadcastReceiver receiver; 

public ServiceModule(ReactApplicationContext reactContext) { 
    super(reactContext); 
    initializeBroadcastReceiver(); 
} 

@ReactMethod 
public void startTrackingService() { 
    Intent intent = new Intent(getReactApplicationContext(), TestService.class); 
    getReactApplicationContext().startService(intent); 
} 

@ReactMethod 
public void stopTrackingService() { 
    Intent intent = new Intent(getReactApplicationContext(), TestService.class); 
    getReactApplicationContext().stopService(intent); 
} 

private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { 
    if (reactContext.hasActiveCatalystInstance()) { 
     reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 
       .emit(eventName, params); 
    } 
} 

private void initializeBroadcastReceiver() { 
    intentFilter = new IntentFilter(); 
    intentFilter.addAction(UPDATE); 
    receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      WritableMap params = Arguments.createMap(); 
      params.putDouble(DISTANCE, intent.getDoubleExtra(DISTANCE, 0)); 
      sendEvent(getReactApplicationContext(), UPDATE, params); 
     } 
    }; 
    getReactApplicationContext().registerReceiver(receiver, intentFilter); 
} 

@Override 
public String getName() { 
    return "ServiceModule"; 
} 
} 

TestService:

public class TestService extends Service { 

double distance = 0.0; 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    new Timer().scheduleAtFixedRate(new TimerTask(){ 
     @Override 
     public void run(){ 
      Intent broadcastIntent = new Intent(); 
      broadcastIntent.setAction(ServiceModule.UPDATE); 
      broadcastIntent.putExtra(ServiceModule.DISTANCE, distance); 
      sendBroadcast(broadcastIntent); 
      distance+= 0.7; 
     } 
    },0,1000); 
    return START_STICKY; 
} 

@Nullable 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 
} 
+0

はそれました '場合(reactContext.hasActiveCatalystInstance())' 'それをやったsendEvent'で?それは私の最後に同様のエラーを修正したものです。つまり、エラーを受け取ったときに私は全く警戒していませんでしたが、オリジナルにはif(reactContext.getLifecycleState()== LifecycleState.RESUMED) – TinyTheBrontosaurus

関連する問題