我们正在研究react native,我们实现了NetInfo事件监听器来检查互联网连接。
我们还在事件上调用fetch()来从google api获取数据。当应用程序处于后台并且如果互联网连接丢失,则应用程序崩溃并出现以下错误:
ReactNativeJS: Network request failed
E AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
E AndroidRuntime: Process: com.example, PID: 30344
E AndroidRuntime: com.facebook.react.common.JavascriptException: Network request failed, stack:
E AndroidRuntime: onerror@25623:21
E AndroidRuntime: dispatchEvent@10670:19
E AndroidRuntime: setReadyState@27824:19
E AndroidRuntime: __didCompleteResponse@27660:19
E AndroidRuntime: <unknown>@27764:57
E AndroidRuntime: emit@9771:28
E AndroidRuntime: __callFunction@7571:39
E AndroidRuntime: <unknown>@7443:21
E AndroidRuntime: guard@7381:3
E AndroidRuntime: callFunctionReturnFlushedQueue@7442:6
E AndroidRuntime:
E AndroidRuntime: at com.facebook.react.modules.core.ExceptionsManagerModule.showOrThrowError(ExceptionsManagerModule.java:97)
E AndroidRuntime: at com.facebook.react.modules.core.ExceptionsManagerModule.reportFatalException(ExceptionsManagerModule.java:81)
E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E AndroidRuntime: at com.facebook.react.bridge.BaseJavaModule$JavaMethod.invoke(BaseJavaModule.java:318)
E AndroidRuntime: at com.facebook.react.cxxbridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:158)
E AndroidRuntime: at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
E AndroidRuntime: at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
E AndroidRuntime: at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:196)
E AndroidRuntime: at java.lang.Thread.run(Thread.java:818)
I ReactNativeJS: auth/network-request-failed
I ReactNativeJS: A network error (such as timeout, interrupted connection or unreachable host) has occurred.
W ActivityManager: Force finishing activity com.example/.MainActivity
我创建了android react本机模块,使用NETWORK_PROVIDER获取GPS当前位置。
public class GpsLocationCheckModule extends ReactContextBaseJavaModule implements LocationListener{
private Promise promiseCallback;
public boolean gps_enabled = false;
private ReactApplicationContext mReactContext;
private Activity currentActivity;
private static final String SETTINGS_FAILURE = "SETTINGS_FAILURE";
private LocationManager locationManager;
public static final String TAG = GpsLocationCheckModule.class.getSimpleName();
private String messageText;
private Location location;
private boolean isPopUpDisplayed = false;
public GpsLocationCheckModule(ReactApplicationContext reactContext) {
super(reactContext);
//reactContext.addActivityEventListener(mActivityEventListener);
mReactContext = reactContext;
reactContext.addActivityEventListener(mActivityEventListener);
}
@Override
public String getName() {
return "GpsServiceLocation"; //this will be use at JS side.
}
@ReactMethod
public void checkLocation(String message, Promise promise) {
currentActivity = getCurrentActivity();
promiseCallback=promise;
messageText= message;
Log.i(TAG,"check location");
locationManager = (LocationManager)mReactContext.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0, 0, this);
boolean gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!gps_enabled){
if(!isPopUpDisplayed){
isPopUpDisplayed = true;
Log.i(TAG,"checklocatoin disabled" + Boolean.toString(isPopUpDisplayed));
displayPromptForEnablingGPS(currentActivity,messageText,promiseCallback);
}
}
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG,"location changed");
String msg = "New Latitude: " + location.getLatitude()
+ "New Longitude: " + location.getLongitude();
Log.i(TAG,msg);
WritableMap params = Arguments.createMap();
params.putDouble("Longitude", location.getLongitude());
params.putDouble("Latitude", location.getLatitude());
//locationManager.removeUpdates(this);
Log.i(TAG,"removed");
sendEvent(mReactContext, "locationChanged", params);
}
@Override
public void onProviderDisabled(String provider) {
Log.i(TAG,"disabled");
Log.i(TAG,"ispopup disabled" + Boolean.toString(isPopUpDisplayed));
if(!isPopUpDisplayed){
isPopUpDisplayed = true;
Log.i(TAG,"ispopup inside disabled" + Boolean.toString(isPopUpDisplayed));
displayPromptForEnablingGPS(currentActivity,messageText,promiseCallback);
}
}
@Override
public void onProviderEnabled(String provider) {
Log.i(TAG,"enabled");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(TAG,"status changed");
// TODO Auto-generated method stub
}
private void displayPromptForEnablingGPS(final Activity activity, final String message, final Promise promise) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final String action = android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS;
builder.setMessage(Html.fromHtml(message))
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
activity.startActivityForResult(new Intent(action), 1);
dialogInterface.dismiss();
}
})
.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
popupRejected();
dialogInterface.cancel();
}
});
builder.create().show();
}
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
currentActivity = activity;
checkLocationService(true);
}
};
public void checkLocationService(Boolean status){
WritableMap map = Arguments.createMap();
map.putString("status", "success");
isPopUpDisplayed=false;
Log.i(TAG,"ispopup checklocation" + Boolean.toString(isPopUpDisplayed));
if(promiseCallback != null){
promiseCallback.resolve(map);
promiseCallback = null;
}
}
public void popupRejected(){
isPopUpDisplayed = false;
Log.i(TAG,"ispopup rejected" + Boolean.toString(isPopUpDisplayed));
if(promiseCallback != null){
promiseCallback.reject(SETTINGS_FAILURE,"Gps enabling failed");
}
}
/*
* Internal function for communicating with JS
*/
private void sendEvent(ReactContext reactContext,
String eventName, @Nullable WritableMap params) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} else {
Log.i(TAG, "Waiting for CatalystInstance...");
}
}
}
我以下列方式在componentDidMount()中调用此模块:
componentDidMount() {
NetInfo.addEventListener(
'change',
this._handleConnectionInfoChange
);
NetInfo.fetch().done(
(connectionInfo) => { this.setState({connectionInfo}); }
);
GpsServiceLocation.checkLocation(this.state.message).catch((error)=>{});
}
位置更新的事件监听器
constructor(props) {
if (!this.evEmitter) {
// Register Listener Callback - has to be removed later
this.evEmitter = DeviceEventEmitter.addListener('locationChanged', this.onLocationChange.bind(this));
}
}
听众功能
onLocationChange (e: Event) {
NetInfo.fetch().done(
(connectionInfo) => {
if(connectionInfo != 'NONE'){
if(e.Latitude != 0 && e.Longitude != 0){
fetch('https://maps.googleapis.com/maps/api/distancematrix/json?origins='+e.Latitude+','+e.Longitude+'&destinations='+destLatlng+'&mode=walking&key=<key>')
.then((responseData) => responseData.json())
.done((responseData)=>{
...
});
}
}
}
}
任何建议都表示赞赏。
答案 0 :(得分:0)
我找到了问题的原因。这是因为fetch()而发生的。如果您在后台使用app时使用fetch()和互联网连接丢失,则fetch()方法会因网络错误而失败。
我在fetch()中添加了catch()来处理与网络相关的错误。下面是语法。
fetch('https://maps.googleapis.com/maps/api/distancematrix/json?origins='+e.Latitude+','+e.Longitude+'&destinations='+destLatlng+'&mode=walking&key=<key>')
.then((responseData) => responseData.json())
.done((responseData)=>{
...
}).catch((error)=>{
//handle your error here
});