我们有一个基于Android
的{{1}}应用程序。该应用程序不使用Cordova 3.5
,而是通过创建CordovaActivity
并将其嵌入应用程序中来工作。当我最初构建这个应用程序时,我很难在应用程序中实例化并初始化CordovaWebView
,我写了this question寻求帮助。我获得了this link有关获取此设置的说明。我遵循了说明并使应用程序正常工作,尽管我确实需要偏离给出的指令,因为在我们的例子中,javascripts必须从远程服务器而不是从Android项目的/ assets / www文件夹加载。
以下是我为CordovaWebView
实施主要活动的方式:
Cordova 3.5
请注意,我仅在此处显示与import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.Toast;
import org.apache.cordova.*;
public class MobileForms extends FragmentActivity implements CordovaInterface, RetryDialogListener, EditServerDialogListener
{
protected FrameLayout webViewPlaceholder;
protected MobileformsPreferences preferences;
protected CordovaWebView cwv;
protected CordovaPlugin activityResultCallback = null;
protected boolean activityResultKeepRunning;
protected final ExecutorService threadPool = Executors.newCachedThreadPool();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences = new MobileformsPreferences(getApplicationContext());
setContentView(R.layout.main);
initializeUI();
org.apache.cordova.Config.init(this);
navigateToMobileforms();
}
protected void initializeUI() {
webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder));
// Initialize the WebView if necessary
if (cwv == null)
{
// Create the webview
cwv = new CordovaWebView(this);
cwv.getSettings().setJavaScriptEnabled(true);
cwv.getSettings().setGeolocationEnabled(true);
cwv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
cwv.getSettings().setBuiltInZoomControls(false);
cwv.getSettings().setSupportZoom(false);
cwv.getSettings().setDomStorageEnabled(true);
cwv.setWebViewClient(new CordovaWebViewClient(this, cwv) {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
try {
view.stopLoading();
} catch (Exception e) {}
if (view.canGoBack()) {
view.goBack();
}
view.loadUrl("about:blank");
Toast.makeText(MobileForms.this, "Cannot connect. Please check your internet connection.", Toast.LENGTH_LONG).show();
Thread thread = new Thread() {
@Override
public void run() {
try {
Thread.sleep(3500); // As I am using LENGTH_LONG in Toast
showRetryDialog();
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
});
cwv.setWebChromeClient(new CordovaChromeClient(this, cwv) {});
// Application cache
cwv.getSettings().setDomStorageEnabled(true);
cwv.getSettings().setAppCachePath(getApplicationContext().getCacheDir().getAbsolutePath()); //"/data/data/"+ getPackageName() +"/cache");
cwv.getSettings().setAppCacheEnabled(true);
cwv.getSettings().setAppCacheMaxSize(1024*1024*20);
cwv.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
}
// Attach the WebView to its placeholder
webViewPlaceholder.addView(cwv);
}
protected void navigateToMobileforms() {
String serverName = preferences.getServerName();
if (serverName != null) {
cwv.loadUrl(buildUrl(serverName));
}
else {
showServerEditDialog();
}
}
protected String buildUrl(String serverText) {
return "http://"+serverText+"/path/to/index.php";
}
protected void showRetryDialog()
{
FragmentManager fm = getSupportFragmentManager();
RetryDialogFragment retryDialog = new RetryDialogFragment();
retryDialog.show(fm, "retry_dialog");
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
// Remove the WebView from the old placeholder
if (cwv != null) {
webViewPlaceholder.removeView(cwv);
}
super.onConfigurationChanged(newConfig);
// Load the layout resource for the new configuration
setContentView(R.layout.main);
// Reinitialize the UI
initializeUI();
}
@Override
public Activity getActivity() {
return this;
}
/**
* Launch an activity for which you would like a result when it finished. When this activity exits,
* your onActivityResult() method is 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) {
this.activityResultCallback = command;
// Start activity
super.startActivityForResult(intent, requestCode);
}
@Override
/**
* Called when an activity you launched exits, giving you the requestCode you started it with,
* the resultCode it returned, and any additional data from it.
*
* @param requestCode The request code originally supplied to startActivityForResult(),
* allowing you to identify who this result came from.
* @param resultCode The integer result code returned by the child activity through its setResult().
* @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
*/
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
CordovaPlugin callback = this.activityResultCallback;
if (callback != null) {
callback.onActivityResult(requestCode, resultCode, intent);
}
}
@Override
public ExecutorService getThreadPool() {
return threadPool;
}
@Override
public Object onMessage(String id, Object data) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onSettings() {
MobileForms.this.showServerEditDialog();
}
... Code snipped ...
}
实施相关的代码。
现在问题是我们需要将此代码带到最新版本的Cordova
(版本5.2.0),我很难将此代码转换为最新版本,因为它似乎很多自版本3.5.0起,Cordova
代码的重组已经发生。例如,此行现在不再有效:
Cordova
因为cwv = new CordovaWebView(this);
现在是一个接口,而不是一个类。
我已经看到updated instructions用于在更大的应用内部实现CordovaWebView
作为webview,但我也在努力思考现在{{1}中的所有类和接口以及它们如何组合在一起。例如,Cordova
,Cordova
,CordovaWebView
,CordovaWebViewImpl
,SystemWebView
。
我很感激在解释不同类如何组合在一起和/或将我上面复制的代码移植到CordovaWebViewEngine
时提供的任何帮助。
答案 0 :(得分:1)
CordovaWebView
不再是View了。您必须实例化保存视图的CordovaWebViewImpl
,然后在其上调用getView()
以检索视图。
以下是CordovaView
,它是嵌入CordovaWebViewImpl
的视图。您可以使用它代替旧的CordovaWebView
。
public class CordovaView extends FrameLayout {
private CordovaWebViewEngine cordovaEngine;
private CordovaWebView cordovaWebView;
public CordovaView(Context context) {
super(context);
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(context);
CordovaPreferences preferences = parser.getPreferences();
ArrayList<PluginEntry> pluginEntries = parser.getPluginEntries();
cordovaEngine = CordovaWebViewImpl.createEngine(context, preferences);
cordovaWebView = new CordovaWebViewImpl(cordovaEngine);
cordovaWebView.init(new CordovaContext(context), pluginEntries, preferences);
View webView = cordovaWebView.getView();
addView(webView);
}
public WebView getWebView() {
View view = cordovaWebView.getView();
if (!(view instanceof WebView))
throw new IllegalStateException("unexpected view type");
return (WebView)view;
}
public void setInitialScale(int scale) {
getWebView().setInitialScale(scale);
}
private class CordovaContext implements CordovaInterface {
private final Activity activity;
private final ExecutorService threadPool = Executors.newCachedThreadPool();
public CordovaContext(Context context) {
if (!(context instanceof Activity))
throw new IllegalArgumentException("Context must be an Activity");
activity = (Activity)context;
}
@Override
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
}
@Override
public void setActivityResultCallback(CordovaPlugin plugin) {
}
@Override
public Activity getActivity() {
return activity;
}
@Override
public Object onMessage(String id, Object data) {
return null;
}
@Override
public ExecutorService getThreadPool() {
return threadPool;
}
@Override
public void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
}
@Override
public void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
}
@Override
public boolean hasPermission(String permission) {
return false;
}
}
}