CB-8768 Fix onActivityResult called before plugins are loaded (after MainActivity gets killed)

situation: one of the plugins launches startActivityForResult and the Android OS decides to kill our MainActivity.
once the launched activity is fulfilled it comes back to our MainActivity, which has to be recreated first.
unfortunately Android calls onActivityResult before our Activity has fully loaded our installed plugins.

close #171
This commit is contained in:
Serge Huijben 2015-03-31 08:28:13 +02:00 committed by Andrew Grieve
parent b8f2b8948f
commit 1aaba440b5
2 changed files with 31 additions and 8 deletions

View File

@ -138,7 +138,7 @@ public class CordovaActivity extends Activity {
if (!appView.isInitialized()) {
appView.init(cordovaInterface, pluginEntries, preferences);
}
cordovaInterface.setPluginManager(appView.getPluginManager());
cordovaInterface.onCordovaInit(appView.getPluginManager());
// Wire the hardware volume controls to control media if desired.
String volumePref = preferences.getString("DefaultVolumeStream", "");

View File

@ -17,6 +17,7 @@ public class CordovaInterfaceImpl implements CordovaInterface {
protected ExecutorService threadPool;
protected PluginManager pluginManager;
protected ActivityResultHolder savedResult;
protected CordovaPlugin activityResultCallback;
protected String initCallbackService;
protected int activityResultRequestCode;
@ -30,10 +31,6 @@ public class CordovaInterfaceImpl implements CordovaInterface {
this.threadPool = threadPool;
}
public void setPluginManager(PluginManager pluginManager) {
this.pluginManager = pluginManager;
}
@Override
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
setActivityResultCallback(command);
@ -72,6 +69,16 @@ public class CordovaInterfaceImpl implements CordovaInterface {
return threadPool;
}
/**
* Dispatches any pending onActivityResult callbacks.
*/
public void onCordovaInit(PluginManager pluginManager) {
this.pluginManager = pluginManager;
if (savedResult != null) {
onActivityResult(savedResult.requestCode, savedResult.resultCode, savedResult.intent);
}
}
/**
* Routes the result to the awaiting plugin. Returns false if no plugin was waiting.
*/
@ -80,17 +87,21 @@ public class CordovaInterfaceImpl implements CordovaInterface {
if(callback == null && initCallbackService != null) {
// The application was restarted, but had defined an initial callback
// before being shut down.
callback = pluginManager.getPlugin(initCallbackService);
savedResult = new ActivityResultHolder(requestCode, resultCode, intent);
if (pluginManager != null) {
callback = pluginManager.getPlugin(initCallbackService);
}
}
initCallbackService = null;
activityResultCallback = null;
if (callback != null) {
Log.d(TAG, "Sending activity result to plugin");
initCallbackService = null;
savedResult = null;
callback.onActivityResult(requestCode, resultCode, intent);
return true;
}
Log.w(TAG, "Got an activity result, but no plugin was registered to receive it.");
Log.w(TAG, "Got an activity result, but no plugin was registered to receive it" + (savedResult != null ? " yet!": "."));
return false;
}
@ -119,4 +130,16 @@ public class CordovaInterfaceImpl implements CordovaInterface {
public void restoreInstanceState(Bundle savedInstanceState) {
initCallbackService = savedInstanceState.getString("callbackService");
}
private static class ActivityResultHolder {
private int requestCode;
private int resultCode;
private Intent intent;
public ActivityResultHolder(int requestCode, int resultCode, Intent intent) {
this.requestCode = requestCode;
this.resultCode = resultCode;
this.intent = intent;
}
}
}