6

Tôi đã nhúng Cordova WebvView làm thành phần cho dự án của mình, mọi thứ hoạt động tốt ngoại trừ một điều; khi nhấn nút quay lại, tôi gặp lỗi trên LogCat có nội dung "Người nhận chưa đăng ký!" Tôi không nghĩ rằng tôi đã đăng ký một người nhận. Ngoài ra còn có một dự án mẫu trên GitHub here. Tôi cũng gặp lỗi tương tự khi chạy ứng dụng này.Nhúng Cordova WebView, Người nhận chưa được đăng ký

Điều tôi muốn làm là nhúng Cordova WebView vào dự án Android của tôi và chạy một số hàm javascript.

Đây là hoạt động chính của tôi;

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: Đây là kết quả 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:

tôi đã kết thúc với một giải pháp. Tôi đã sử dụng Cordova Web View trong một Fragment, tôi đã chuyển nó ra khỏi phân đoạn và đặt nó vào cùng một xml với vùng chứa mảnh. Bây giờ nó hoạt động mà không có lỗi. Cũng giống như trong dự án mẫu trong GitHub, CordovaWebView nằm trong FrameLayout.

Trả lời

1

Bạn không cần phải thực hiện toàn bộ phá hủy chảy chính mình, bạn có thể sử dụng như sau:

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

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

Hope this helps.

+0

Này, tôi đã cố gắng giải pháp của bạn nhưng tôi vẫn nhận được lỗi tương tự. nó nói, 'Hoạt động MainNativeViewController đã bị rò rỉ IntentReceiver [email protected] đã được đăng ký ban đầu ở đây. Bạn có bỏ lỡ một cuộc gọi đến unregisterReceiver()? ' – osayilgan

+0

Hey tôi đoán tôi đã tìm ra cách, tôi gọi là' this.cwv.removeAllViews(); ' trước handleDestroy(), Dường như nó hoạt động. Tôi không nhận được lỗi nữa nhưng tôi không biết đúng cách của nó? – osayilgan

+0

** EDIT: ** Bằng cách này nó bị phá hủy mà không có lỗi nhưng trong trường hợp tôi cố gắng để khởi động lại ứng dụng sau khi phá hủy nó sau đó tôi nhận được một lỗi, mà nói, '" java.lang.IllegalStateException: Không thể thực hiện điều này hành động sau onSaveInstanceState "' – osayilgan

4

tôi giải quyết này trong đoạn của tôi bằng cách thêm dòng sau vào onDestroyView()

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

    } 
+0

Không chắc chắn bạn đang sử dụng phiên bản Cordova nào nhưng (Có thể giải quyết trong các phiên bản mới hơn), lúc đó, khi tôi hỏi câu hỏi đó, Giải pháp của bạn không hoạt động. – osayilgan

+0

Tôi đang sử dụng 3.6.4 trên Android. Tuy nhiên, giải pháp của tôi ở trên dường như đã giới thiệu '' 'java.lang.IllegalArgumentException: Người nhận chưa đăng ký: org.apache.cordova.App''' khi thoát ... Tôi đã kết thúc ở đây vì sử dụng nút quay lại kết thúc ứng dụng đã cho tôi '' 'MainNativeViewController hoạt động đã bị rò rỉ IntentReceiver [email protected] đã được đăng ký ban đầu ở đây. Bạn có bỏ lỡ cuộc gọi đến unregisterReceiver() '' ' Điều này có vẻ ngược lại với những gì bạn nhìn thấy ban đầu. – theSociableme

+0

Nếu bạn thấy ngoại lệ thì đó là cùng một vấn đề sau khi thêm giải pháp @Yoel ở trên. Vì vậy, thay vì sử dụng onDestroy nếu bạn gọi handleDestroy trong onDestroyView giải quyết vấn đề? – osayilgan

Các vấn đề liên quan