java - generate - react native swift
React Native: escribe en AsyncStorage con java (2)
Después de bastante pelea finalmente encontré una solución . No utiliza AsyncStorage
mientras leo en el código fuente. AsyncStorage podría localizarse de manera diferente (SQLite, u otra cosa) dependiendo del teléfono. Estaría sucio duplicar esta lógica.
En su lugar, creé un módulo como sugiere el documento y pasé inputText
como un argumento para la .addPackage(new EphemeralStoragePackage(inputText))
en MainActivity.java
.
El módulo expone un método readOnceAsync
en el mundo JS, con el que puedo llamar más adelante:
NativeModules.EphemeralStorage.readOnceAsync((text :string) => {
if (text.length) {
this._addValue(text); // this method is in charge of storing in AsyncStorage
}
})
Aquí está el detalle:
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStorageModule.java
package com.browseitlater.modules.ephemeralstorage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import java.util.Map;
public class EphemeralStorageModule extends ReactContextBaseJavaModule {
private String inputText;
public EphemeralStorageModule(ReactApplicationContext reactContext, String _inputText) {
super(reactContext);
this.inputText = _inputText;
}
@Override
public String getName() {
return "EphemeralStorage";
}
public String getInputText() {
return inputText;
}
@ReactMethod
public void readOnceAsync(Callback successCallback) {
successCallback.invoke(getInputText());
this.inputText = null;
}
}
Y
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStoragePackage.java
package com.browseitlater.modules.ephemeralstorage;
import android.app.Activity;
import java.util.*;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
public class EphemeralStoragePackage implements ReactPackage {
private String inputText;
public EphemeralStoragePackage(String _inputText) {
super();
this.inputText = _inputText;
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new EphemeralStorageModule(reactContext, getInputText()));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
public String getInputText() {
return inputText;
}
}
Finalmente en MainActivity.java
, mi método onCreate
se ve así:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
String inputText = intent.getStringExtra(Intent.EXTRA_TEXT);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new EphemeralStoragePackage(inputText))
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
}
Así que tengo este texto en java que viene de un Intent
, que me gustaría guardar en AsyncStorage
para poder acceder a él a través de React luego.
¿Hay alguna posibilidad de que pueda lograr esto?
Yo tengo:
package com.myapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.content.Intent;
import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
// This code is from http://developer.android.com/training/sharing/receive.html
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
handleSendText(intent);
}
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// How can I handle this ????
}
}
// ...
}
¿O hay alguna otra solución para hacer que MainActivity.java
comunique con JS?
Si no desea escribir un módulo nativo, puede hacerlo en MainActivity.java
Declare una variable global dentro de la clase MainActivity (no olvide importar com.facebook.react.modules.storage.ReactDatabaseSupplier
):
private ReactDatabaseSupplier mReactDatabaseSupplier;
Dentro del método onCreate
, inicializa la variable global:
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
Declare un método privado para guardar el par de clave / valor dentro de AsyncStorage
private void saveKeyValuePair(String key, String value) {
String sql = "INSERT OR REPLACE INTO catalystLocalStorage VALUES (?, ?);";
SQLiteStatement statement = mReactDatabaseSupplier.get().compileStatement(sql);
try {
mReactDatabaseSupplier.get().beginTransaction();
statement.clearBindings();
statement.bindString(1, key);
statement.bindString(2, value);
statement.execute();
mReactDatabaseSupplier.get().setTransactionSuccessful();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
} finally {
try {
mReactDatabaseSupplier.get().endTransaction();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
}
}
}
Luego puede guardar pares clave / valor como este (dentro de onCreate
, por ejemplo):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
saveKeyValuePair("myAsyncStorageKey", "myValueInAsyncStorageKey");
}
Esta es una manera simple de guardar en AsyncStorage
de una aplicación React Native. Considera escribir un módulo nativo.