forked from github/cordova-android
CB-8382 Make CordovaActivity not implement CordovaInterface
Instead, use a CordovaInterfaceImpl class. This also makes it easier for apps to implement the interface without extending CordovaActivity.
This commit is contained in:
parent
20723896e1
commit
83120a5bea
@ -22,8 +22,6 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -78,23 +76,17 @@ import android.widget.LinearLayout;
|
|||||||
* deprecated in favor of the config.xml file.
|
* deprecated in favor of the config.xml file.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CordovaActivity extends Activity implements CordovaInterface {
|
public class CordovaActivity extends Activity {
|
||||||
public static String TAG = "CordovaActivity";
|
public static String TAG = "CordovaActivity";
|
||||||
|
|
||||||
// The webview for our app
|
// The webview for our app
|
||||||
protected CordovaWebView appView;
|
protected CordovaWebView appView;
|
||||||
|
|
||||||
private final ExecutorService threadPool = Executors.newCachedThreadPool();
|
|
||||||
|
|
||||||
private static int ACTIVITY_STARTING = 0;
|
private static int ACTIVITY_STARTING = 0;
|
||||||
private static int ACTIVITY_RUNNING = 1;
|
private static int ACTIVITY_RUNNING = 1;
|
||||||
private static int ACTIVITY_EXITING = 2;
|
private static int ACTIVITY_EXITING = 2;
|
||||||
private int activityState = 0; // 0=starting, 1=running (after 1st resume), 2=shutting down
|
private int activityState = 0; // 0=starting, 1=running (after 1st resume), 2=shutting down
|
||||||
|
|
||||||
// Plugin to call when activity result is received
|
|
||||||
protected int activityResultRequestCode;
|
|
||||||
protected CordovaPlugin activityResultCallback;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The variables below are used to cache some of the activity properties.
|
* The variables below are used to cache some of the activity properties.
|
||||||
*/
|
*/
|
||||||
@ -107,14 +99,14 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
// when another application (activity) is started.
|
// when another application (activity) is started.
|
||||||
protected boolean keepRunning = true;
|
protected boolean keepRunning = true;
|
||||||
|
|
||||||
private String initCallbackClass;
|
|
||||||
|
|
||||||
// Read from config.xml:
|
// Read from config.xml:
|
||||||
protected CordovaPreferences preferences;
|
protected CordovaPreferences preferences;
|
||||||
protected Whitelist internalWhitelist;
|
protected Whitelist internalWhitelist;
|
||||||
protected Whitelist externalWhitelist;
|
protected Whitelist externalWhitelist;
|
||||||
protected String launchUrl;
|
protected String launchUrl;
|
||||||
protected ArrayList<PluginEntry> pluginEntries;
|
protected ArrayList<PluginEntry> pluginEntries;
|
||||||
|
protected CordovaInterfaceImpl cordovaInterface;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the activity is first created.
|
* Called when the activity is first created.
|
||||||
@ -146,9 +138,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
cordovaInterface = makeCordovaInterface();
|
||||||
if(savedInstanceState != null)
|
if(savedInstanceState != null)
|
||||||
{
|
{
|
||||||
initCallbackClass = savedInstanceState.getString("callbackClass");
|
cordovaInterface.restoreInstanceState(savedInstanceState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +149,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
appView = makeWebView();
|
appView = makeWebView();
|
||||||
createViews();
|
createViews();
|
||||||
appView.init(this, pluginEntries, internalWhitelist, externalWhitelist, preferences);
|
appView.init(this, pluginEntries, internalWhitelist, externalWhitelist, preferences);
|
||||||
|
cordovaInterface.setPluginManager(appView.getPluginManager());
|
||||||
|
|
||||||
// Wire the hardware volume controls to control media if desired.
|
// Wire the hardware volume controls to control media if desired.
|
||||||
String volumePref = preferences.getString("DefaultVolumeStream", "");
|
String volumePref = preferences.getString("DefaultVolumeStream", "");
|
||||||
@ -206,14 +200,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Android activity.
|
* Construct the default web view object.
|
||||||
*/
|
|
||||||
@Override public Activity getActivity() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct the CordovaWebView object.
|
|
||||||
*
|
*
|
||||||
* Override this to customize the webview that is used.
|
* Override this to customize the webview that is used.
|
||||||
*/
|
*/
|
||||||
@ -227,6 +214,17 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to create webview. ", e);
|
throw new RuntimeException("Failed to create webview. ", e);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CordovaInterfaceImpl makeCordovaInterface() {
|
||||||
|
return new CordovaInterfaceImpl(this) {
|
||||||
|
@Override
|
||||||
|
public Object onMessage(String id, Object data) {
|
||||||
|
// Plumb this to CordovaActivity.onMessage for backwards compatibility
|
||||||
|
return CordovaActivity.this.onMessage(id, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,29 +322,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
super.finish();
|
super.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
|
||||||
* your onActivityResult() method will be called.
|
|
||||||
*
|
|
||||||
* @param command The command object
|
|
||||||
* @param intent The intent to start
|
|
||||||
* @param requestCode The request code that is passed to callback to identify the activity
|
|
||||||
*/
|
|
||||||
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
|
|
||||||
setActivityResultCallback(command);
|
|
||||||
try {
|
|
||||||
startActivityForResult(intent, requestCode);
|
|
||||||
} catch (RuntimeException e) { // E.g.: ActivityNotFoundException
|
|
||||||
activityResultCallback = null;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
|
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
|
||||||
// Capture requestCode here so that it is captured in the setActivityResultCallback() case.
|
// Capture requestCode here so that it is captured in the setActivityResultCallback() case.
|
||||||
activityResultRequestCode = requestCode;
|
cordovaInterface.setActivityResultRequestCode(requestCode);
|
||||||
super.startActivityForResult(intent, requestCode, options);
|
super.startActivityForResult(intent, requestCode, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,29 +342,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
LOG.d(TAG, "Incoming Result. Request code = " + requestCode);
|
LOG.d(TAG, "Incoming Result. Request code = " + requestCode);
|
||||||
super.onActivityResult(requestCode, resultCode, intent);
|
super.onActivityResult(requestCode, resultCode, intent);
|
||||||
CordovaPlugin callback = this.activityResultCallback;
|
cordovaInterface.onActivityResult(requestCode, resultCode, intent);
|
||||||
if(callback == null && initCallbackClass != null) {
|
|
||||||
// The application was restarted, but had defined an initial callback
|
|
||||||
// before being shut down.
|
|
||||||
callback = appView.getPluginManager().getPlugin(initCallbackClass);
|
|
||||||
}
|
|
||||||
initCallbackClass = null;
|
|
||||||
activityResultCallback = null;
|
|
||||||
|
|
||||||
if (callback != null) {
|
|
||||||
LOG.d(TAG, "We have a callback to send this result to");
|
|
||||||
callback.onActivityResult(requestCode, resultCode, intent);
|
|
||||||
} else {
|
|
||||||
LOG.w(TAG, "Got an activity result, but no plugin was registered to receive it.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActivityResultCallback(CordovaPlugin plugin) {
|
|
||||||
// Cancel any previously pending activity.
|
|
||||||
if (activityResultCallback != null) {
|
|
||||||
activityResultCallback.onActivityResult(activityResultRequestCode, Activity.RESULT_CANCELED, null);
|
|
||||||
}
|
|
||||||
this.activityResultCallback = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -499,24 +456,15 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
} else if ("exit".equals(id)) {
|
||||||
else if ("exit".equals(id)) {
|
|
||||||
this.endActivity();
|
this.endActivity();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService getThreadPool() {
|
|
||||||
return threadPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onSaveInstanceState(Bundle outState)
|
protected void onSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
if(this.activityResultCallback != null)
|
cordovaInterface.onSaveInstanceState(outState);
|
||||||
{
|
|
||||||
String cClass = this.activityResultCallback.getClass().getName();
|
|
||||||
outState.putString("callbackClass", cClass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
122
framework/src/org/apache/cordova/CordovaInterfaceImpl.java
Normal file
122
framework/src/org/apache/cordova/CordovaInterfaceImpl.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of CordovaInterface.
|
||||||
|
*/
|
||||||
|
public class CordovaInterfaceImpl implements CordovaInterface {
|
||||||
|
private static final String TAG = "CordovaInterfaceImpl";
|
||||||
|
protected Activity activity;
|
||||||
|
protected ExecutorService threadPool;
|
||||||
|
protected PluginManager pluginManager;
|
||||||
|
|
||||||
|
protected CordovaPlugin activityResultCallback;
|
||||||
|
protected String initCallbackClass;
|
||||||
|
protected int activityResultRequestCode;
|
||||||
|
|
||||||
|
public CordovaInterfaceImpl(Activity activity) {
|
||||||
|
this(activity, Executors.newCachedThreadPool());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CordovaInterfaceImpl(Activity activity, ExecutorService threadPool) {
|
||||||
|
this.activity = activity;
|
||||||
|
this.threadPool = threadPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPluginManager(PluginManager pluginManager) {
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
|
||||||
|
setActivityResultCallback(command);
|
||||||
|
try {
|
||||||
|
activity.startActivityForResult(intent, requestCode);
|
||||||
|
} catch (RuntimeException e) { // E.g.: ActivityNotFoundException
|
||||||
|
activityResultCallback = null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActivityResultCallback(CordovaPlugin plugin) {
|
||||||
|
// Cancel any previously pending activity.
|
||||||
|
if (activityResultCallback != null) {
|
||||||
|
activityResultCallback.onActivityResult(activityResultRequestCode, Activity.RESULT_CANCELED, null);
|
||||||
|
}
|
||||||
|
activityResultCallback = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object onMessage(String id, Object data) {
|
||||||
|
if ("exit".equals(id)) {
|
||||||
|
activity.finish();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutorService getThreadPool() {
|
||||||
|
return threadPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes the result to the awaiting plugin. Returns false if no plugin was waiting.
|
||||||
|
*/
|
||||||
|
public boolean onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
CordovaPlugin callback = activityResultCallback;
|
||||||
|
if(callback == null && initCallbackClass != null) {
|
||||||
|
// The application was restarted, but had defined an initial callback
|
||||||
|
// before being shut down.
|
||||||
|
callback = pluginManager.getPlugin(initCallbackClass);
|
||||||
|
}
|
||||||
|
initCallbackClass = null;
|
||||||
|
activityResultCallback = null;
|
||||||
|
|
||||||
|
if (callback != null) {
|
||||||
|
Log.d(TAG, "Sending activity result to plugin");
|
||||||
|
callback.onActivityResult(requestCode, resultCode, intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Log.w(TAG, "Got an activity result, but no plugin was registered to receive it.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this from your startActivityForResult() overload. This is required to catch the case
|
||||||
|
* where plugins use Activity.startActivityForResult() + CordovaInterface.setActivityResultCallback()
|
||||||
|
* rather than CordovaInterface.startActivityForResult().
|
||||||
|
*/
|
||||||
|
public void setActivityResultRequestCode(int requestCode) {
|
||||||
|
activityResultRequestCode = requestCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves parameters for startActivityForResult().
|
||||||
|
*/
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
if (activityResultCallback != null) {
|
||||||
|
String cClass = activityResultCallback.getClass().getName();
|
||||||
|
outState.putString("callbackClass", cClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this from onCreate() so that any saved startActivityForResult parameters will be restored.
|
||||||
|
*/
|
||||||
|
public void restoreInstanceState(Bundle savedInstanceState) {
|
||||||
|
initCallbackClass = savedInstanceState.getString("callbackClass");
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,8 @@ public class userwebview extends MainTestActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
testViewClient = new TestViewClient(this, ((AndroidWebView)appView));
|
testViewClient = new TestViewClient(cordovaInterface, ((AndroidWebView)appView));
|
||||||
testChromeClient = new TestChromeClient(this, ((AndroidWebView)appView));
|
testChromeClient = new TestChromeClient(cordovaInterface, ((AndroidWebView)appView));
|
||||||
super.init();
|
super.init();
|
||||||
((AndroidWebView)appView).setWebViewClient(testViewClient);
|
((AndroidWebView)appView).setWebViewClient(testViewClient);
|
||||||
((AndroidWebView)appView).setWebChromeClient(testChromeClient);
|
((AndroidWebView)appView).setWebChromeClient(testChromeClient);
|
||||||
|
@ -28,7 +28,7 @@ public class whitelist extends MainTestActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
super.init();
|
super.init();
|
||||||
((AndroidWebView)appView).setWebViewClient(new TestViewClient(this, ((AndroidWebView)appView)));
|
((AndroidWebView)appView).setWebViewClient(new TestViewClient(cordovaInterface, ((AndroidWebView)appView)));
|
||||||
super.loadUrl("file:///android_asset/www/whitelist/index.html");
|
super.loadUrl("file:///android_asset/www/whitelist/index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user