6

Ich habe die Cordova WebvView als Komponente in mein Projekt eingebettet, alles funktioniert gut außer einer Sache; Wenn die Zurück-Taste gedrückt wird, erhalte ich einen Fehler auf LogCat, der sagt "Empfänger nicht registriert!" Ich glaube nicht, dass ich einen Empfänger registriert habe. Es gibt auch ein Beispielprojekt auf GitHub here. Ich bekomme auch den gleichen Fehler, wenn ich diese Anwendung ausführen.Embedding Cordova WebView, Empfänger ist nicht registriert

Was ich tun möchte, ist Cordova WebView in mein Android-Projekt einbetten und einige Javascript-Funktionen ausführen.

Hier ist meine Haupttätigkeit;

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(); 
    } 
} 
} 

EDIT: Hier ist die LogCat Ausgang;

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:  [email protected] 
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: [email protected] 
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 

EDIT:

landete ich mit einer Lösung auf. Ich benutzte Cordova Web View in einem Fragment, ich zog es aus dem Fragment und legte es in dasselbe XML mit Fragmentcontainer. Jetzt funktioniert es ohne Fehler. Es ist das gleiche im Beispielprojekt in der GitHub, CordovaWebView ist in FrameLayout.

Antwort

1

Sie brauchen nicht das ganze zu implementieren zerstören selbst fließen, können Sie die folgende verwenden:

public void onDestroy() { 
    LOG.d("Destroying the View", "onDestroy()"); 
    super.onDestroy(); 

    if (this.cwv != null) { 
    this.cwv.handleDestroy(); 
    } 
} 

Hoffnung, das hilft.

+0

Hey, ich Ihre Lösung versucht, aber ich immer noch die gleichen Fehler. es heißt, 'Aktivität MainNativeViewController hat IntentReceiver [email protected] durchgesickert, die ursprünglich hier registriert wurde. Vermissen Sie einen Aufruf von unregisterReceiver()? ' – osayilgan

+0

Hey ich denke, ich fand den Weg, rief ich' this.cwv.removeAllViews(); ' vor handleDestroy(), Es scheint, es funktioniert. Ich bekomme den Fehler nicht mehr, aber ich weiß es nicht richtig? – osayilgan

+0

** BEARBEITEN: ** Auf diese Weise wird es ohne Fehler zerstört, aber in dem Fall, dass ich versuche, die App erneut zu starten, nachdem ich es zerstört habe, bekomme ich einen weiteren Fehler, der sagt: '" java.lang.IllegalStateException: Kann dies nicht ausführen action after onSaveInstanceState "' – osayilgan

4

Ich löste dies in meinem Fragment das durch Zugabe von folgenden onDestroyView()

@Override 
    public void onDestroyView() { 
     super.onDestroyView(); 
     mCordovaWebView.handleDestroy(); 

    } 
+0

Nicht sicher, welche Version von Cordova Sie verwenden, aber (es ist wahrscheinlich in den neueren Versionen gelöst), diese Zeit, als ich diese Frage gestellt, Ihre Lösung hat nicht funktioniert. – osayilgan

+0

Ich benutze 3.6.4 auf Android. Meine obige Lösung scheint jedoch '' 'java.lang.IllegalArgumentException: Empfänger nicht registriert: org.apache.cordova.App''' beim Beenden ... Ich bin hier gelandet, weil die Zurück-Taste zu verwenden Beenden Sie die App gab mir die '' 'Aktivität MainNativeViewController hat IntentReceiver [email protected] durchgesickert, die ursprünglich hier registriert wurde. Verpassen Sie einen Aufruf von unregisterReceiver() '' ' Das scheint das Gegenteil von dem zu sein, was Sie ursprünglich sahen. – theSociableme

+0

Wenn Sie diese Ausnahme sehen, ist es das gleiche Problem nach dem Hinzufügen von @Yoel 's Lösung oben. Also anstatt onDestroy zu verwenden, wenn Sie handleDestroy in onDestroyView aufrufen, löst das Problem? – osayilgan