Cordova WebvView をコンポーネントとしてプロジェクトに組み込みましたが、1 つのことを除いてすべて正常に動作します。戻るボタンを押すと、LogCat で「Receiver Not Registered!」というエラーが表示されます。受信者を登録しているとは思いません。GitHub のサンプル プロジェクトもここにあります。このアプリケーションを実行すると、同じエラーが発生します。
私がやりたいことは、Cordova WebView を Android プロジェクトに埋め込み、いくつかの JavaScript 関数を実行することです。
これが私の主な活動です。
public class MainNativeViewController extends FragmentActivity implements CordovaInterface,
JavaScriptListener {
FragmentTransaction transaction;
RelativeLayout childBrowser;
RelativeLayout dialogBox;
RelativeLayout emailComposer;
private ExecutorService threadPool;
CordovaWebViewFragment cordovaWebViewFragment;
public CordovaWebView cordovaWebView;
public LayoutInflater inflater;
CordovaPlugin mActivityResultCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
threadPool = Executors.newCachedThreadPool();
cordovaWebView = SingleTonCordovaWebView.getCordovaWebView(this);
cordovaWebView.loadUrl("file:///android_asset/www/invoke_native_view.html");
FragmentManager manager = getSupportFragmentManager();
ListFragment listFragment = new ListFragment();
manager.beginTransaction().add(R.id.fragment_container, listFragment).commit();
}
@Override
public void showFragment(String fragmentName) {
/*
* This method is used to create and replace a fragment to the
* container. according to name passed through here.
*/
transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left,
R.anim.slide_in_left, R.anim.slide_out_right);
if (fragmentName.equals("error")) {
DialogCreator dialog = new DialogCreator(this);
dialog.createDialog("Error !", "Fragment Name is wrong,", "Check fragment name", false);
} else {
// fragment name is ignored for different cases, it will be used for
// further proporties.
// Just checking out the error in the case its not right parameter.
NativeViewTestFragment testFragment = new NativeViewTestFragment(fragmentName);
transaction.replace(R.id.fragment_container, testFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
@Override
protected void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
// Forward to plugins
if ((this.cordovaWebView != null) && (this.cordovaWebView.pluginManager != null)) {
this.cordovaWebView.pluginManager.onNewIntent(intent);
}
}
@Override
public void cancelLoadUrl() {
}
@Override
public ExecutorService getThreadPool() {
return threadPool;
}
@Override
public Activity getActivity() {
return this;
}
@Override
public Context getContext() {
return this;
}
@Override
public Object onMessage(final String id, final Object data) {
// return getCordovaFragment().onMessage(id, data);
return null;
}
@Override
public void setActivityResultCallback(CordovaPlugin arg0) {
// TODO Auto-generated method stub
}
@Override
public void startActivityForResult(CordovaPlugin plugin, Intent intent, int requestCode) {
mActivityResultCallback = plugin;
startActivityForResult(intent, requestCode);
}
@Override
/**
* Called when the system is about to start resuming a previous activity.
*/
protected void onPause() {
super.onPause();
// Send pause event to JavaScript
this.cordovaWebView.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
// Forward to plugins
if (this.cordovaWebView.pluginManager != null) {
this.cordovaWebView.pluginManager.onPause(true);
}
threadPool.shutdown();
threadPool = null;
}
@Override
/**
* Called when the activity will start interacting with the user.
*/
protected void onResume() {
super.onResume();
threadPool = Executors.newCachedThreadPool();
if (this.cordovaWebView == null) {
return;
}
// Send resume event to JavaScript
this.cordovaWebView
.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
// Forward to plugins
if (this.cordovaWebView.pluginManager != null) {
this.cordovaWebView.pluginManager.onResume(true);
}
}
@Override
/**
* The final call you receive before your activity is destroyed.
*/
public void onDestroy() {
super.onDestroy();
if (cordovaWebView.pluginManager != null) {
cordovaWebView.pluginManager.onDestroy();
}
if (this.cordovaWebView != null) {
// Send destroy event to JavaScript
this.cordovaWebView
.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
// Load blank page so that JavaScript onunload is called
this.cordovaWebView.loadUrl("about:blank");
// Forward to plugins
if (this.cordovaWebView.pluginManager != null) {
this.cordovaWebView.pluginManager.onDestroy();
}
} else {
// this.endActivity();
}
}
}
編集: LogCat の出力は次のとおりです。
11-23 12:25:36.117: E/AndroidRuntime(9645): FATAL EXCEPTION: main
11-23 12:25:36.117: E/AndroidRuntime(9645): java.lang.RuntimeException: Unable to destroy activity {org.apache.cordova.example/okan.apps.nativeview.MainNativeViewController}: java.lang.IllegalArgumentException: Receiver not registered: org.apache.cordova.Device$1@45391938
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3655)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3673)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread.access$2900(ActivityThread.java:125)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.os.Handler.dispatchMessage(Handler.java:99)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.os.Looper.loop(Looper.java:123)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-23 12:25:36.117: E/AndroidRuntime(9645): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 12:25:36.117: E/AndroidRuntime(9645): at java.lang.reflect.Method.invoke(Method.java:521)
11-23 12:25:36.117: E/AndroidRuntime(9645): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-23 12:25:36.117: E/AndroidRuntime(9645): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-23 12:25:36.117: E/AndroidRuntime(9645): at dalvik.system.NativeStart.main(Native Method)
11-23 12:25:36.117: E/AndroidRuntime(9645): Caused by: java.lang.IllegalArgumentException: Receiver not registered: org.apache.cordova.Device$1@45391938
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:793)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:814)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
11-23 12:25:36.117: E/AndroidRuntime(9645): at org.apache.cordova.Device.onDestroy(Device.java:98)
11-23 12:25:36.117: E/AndroidRuntime(9645): at org.apache.cordova.api.PluginManager.onDestroy(PluginManager.java:317)
11-23 12:25:36.117: E/AndroidRuntime(9645): at okan.apps.nativeview.MainNativeViewController.onDestroy(MainNativeViewController.java:204)
11-23 12:25:36.117: E/AndroidRuntime(9645): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3642)
11-23 12:25:36.117: E/AndroidRuntime(9645): ... 11 more
編集:
私は解決策で終わった。フラグメントで Cordova Web View を使用していましたが、フラグメントから移動し、フラグメント コンテナーと同じ xml に入れました。これでエラーなく動作します。GitHub のサンプル プロジェクトと同じで、CordovaWebView は FrameLayout にあります。