6

Ho incorporato Cordova WebvView come componente del mio progetto, tutto funziona bene tranne una cosa; quando viene premuto il pulsante Indietro, ricevo un errore su LogCat che dice "Ricevitore non registrato!" Non penso di aver registrato un ricevitore. C'è anche un progetto di esempio su GitHub here. Ho anche lo stesso errore quando eseguo questa applicazione.Embedding Cordova WebView, il ricevitore non è registrato

Quello che voglio fare è incorporare Cordova WebView nel mio progetto Android ed eseguire alcune funzioni javascript.

Ecco la mia attività principale;

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: Ecco l'output 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:  [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:

ho finito con una soluzione. Stavo usando Cordova Web View in un frammento, l'ho spostato dal frammento e lo ho inserito nello stesso xml con contenitore dei frammenti. Ora funziona senza errori. È lo stesso nel progetto di esempio in GitHub, CordovaWebView è in FrameLayout.

risposta

1

Non è necessario implementare l'intero flusso di distruggere te stesso, è possibile utilizzare il seguente:

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

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

Spero che questo aiuti.

+0

Ehi, ho provato la soluzione, ma ancora ottengo lo stesso errore. Dice, 'Attività MainNativeViewController ha trapelato IntentReceiver [email protected] che è stato registrato in origine qui. Ti manca una chiamata per annullare la registrazioneReceiver()? ' – osayilgan

+0

Ehi, credo di aver trovato la strada, ho chiamato' this.cwv.removeAllViews(); ' prima di handleDestroy(), Sembra che funzioni. Non ottengo più l'errore ma non lo conosco nel modo giusto? – osayilgan

+0

** MODIFICA: ** In questo modo viene distrutto senza errori ma Nel caso in cui tento di riavviare l'app dopo averlo distrutto, ricevo un altro errore, che dice "java.lang.IllegalStateException: Impossibile eseguire questo azione dopo onSaveInstanceState "' – osayilgan

4

Ho risolto questo nel mio frammento aggiungendo il seguente a onDestroyView()

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

    } 
+0

Non sei sicuro di quale versione di Cordova stai usando ma (Probabilmente è stata risolta nelle versioni più recenti), quella volta, quando ho posto quella domanda, la tua soluzione non ha funzionato. – osayilgan

+0

Sto usando 3.6.4 su Android. Tuttavia, la mia soluzione precedente sembra aver introdotto '' 'java.lang.IllegalArgumentException: Receiver not registered: org.apache.cordova.App''' in uscita ... Sono finito qui perché usando il pulsante Indietro per finire l'applicazione mi stava dando il '' 'Attività MainNativeViewController ha trapelato IntentReceiver [email protected] che è stato originariamente registrato qui. Ti manca una chiamata per annullare la registrazioneReceiver() '' ' Quale sembra essere il contrario di ciò che stavi vedendo in origine. – theSociableme

+0

Se vedi questa eccezione, è lo stesso problema dopo aver aggiunto la soluzione di @Yoel sopra. Quindi invece di usare onDestroy se chiami handleDestroy in onDestroyView risolve il problema? – osayilgan

Problemi correlati