2013-01-09 31 views
6

Tôi có một ứng dụng Android, sử dụng một số PhoneGap WebView được nhúng. Tôi đã triển khai thành công CordovaInterface hoạt động của mình và ứng dụng bắt đầu và hoạt động như thế nào.Lưu & khôi phục WebView trong ứng dụng PhoneGap được nhúng

Khi tôi tạm dừng ứng dụng (chuyển sang ứng dụng khác hoặc tab Trang chủ), tôi lưu trạng thái của WebView với phương pháp saveState, sẽ được khôi phục khi ứng dụng khởi động lại (phương pháp này hoạt động trong ứng dụng không có PhoneGap).

Tuy nhiên, khi ứng dụng bắt đầu lại, tôi cố khôi phục trạng thái (với phương pháp restoreState) mà không tải url trước (vì tôi muốn sử dụng trạng thái cuối cùng). Điều này gây ra một lỗi vì PhoneGap hy vọng một url sẽ được tải (ít nhất đó là những gì tôi thu thập từ ngoại lệ).

Câu hỏi của tôi là: Làm cách nào để lưu và khôi phục trạng thái của WebView một cách chính xác trong một WebView PhoneGap được nhúng?

onCreate phương pháp của tôi:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    webView = (CordovaWebView) findViewById(R.id.webView); 

    if (savedInstanceState == null) { 
     savedInstanceState = restoreFromPreferences(); 
    } 
    if (savedInstanceState == null) { 
     webView.loadUrl("file:///android_asset/www/index.html"); 
    } else { 
     webView.restoreState(savedInstanceState); 
     webView.loadUrlIntoView(savedInstanceState.getString("url")); 
    } 
} 

Phương pháp của tôi (logic tương tự trong onSaveInstanceState):

@Override 
protected void onPause() { 
    super.onPause(); 

    Bundle out = new Bundle(); 
    webView.saveState(out); 

    saveToPreferences(out); 
} 

Lỗi khi đóng/app tạm dừng (giải quyết - xem cập nhật 1):

Tôi gặp lỗi khi tôi đóng ứng dụng. Đây có lẽ là liên quan, nhưng tôi không thấy thế nào:

01-09 11:44:50.181: E/ActivityThread(2068): Activity my.package.MainActivity has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
01-09 11:44:50.181: E/ActivityThread(2068): android.app.IntentReceiverLeaked: Activity my.package.MainActivity has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
... 

Lỗi khi khởi động ứng dụng đó nữa (giải quyết - xem cập nhật 1):

Điều này gây ra một lỗi, vì WebView cố gắng để tải một địa chỉ mà là null:

01-09 11:38:22.813: E/AndroidRuntime(1979): FATAL EXCEPTION: main 
01-09 11:38:22.813: E/AndroidRuntime(1979): java.lang.NullPointerException 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at java.lang.String.indexOf(String.java:994) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at org.apache.cordova.CordovaWebView.loadUrlNow(CordovaWebView.java:499) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at org.apache.cordova.CordovaWebView.loadUrl(CordovaWebView.java:384) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at org.apache.cordova.CordovaWebViewClient.onPageFinished(CordovaWebViewClient.java:298) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:327) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at android.os.Looper.loop(Looper.java:137) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at android.app.ActivityThread.main(ActivityThread.java:4745) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at java.lang.reflect.Method.invoke(Method.java:511) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
01-09 11:38:22.813: E/AndroidRuntime(1979):  at dalvik.system.NativeStart.main(Native Method) 

UPDATE 1:

Cả hai lỗi này đã được giải quyết nhưng được thay thế bằng một cái mới.

Lỗi đầu tiên là do webView.handleDestroy() trong số onDestroy() không được gọi.

Lỗi thứ hai là do trường baseUrl trong CordovaWebView chưa được đặt. Hiện nay tôi đang cố gắng để giải quyết rằng bằng cách tiết kiệm url thăm cuối cùng vào SharedPreferences khi onPause()/onSaveInstanceState() xảy ra:

 String url = webView.peekAtUrlStack(); 
     out.putString("url", url); 
     webView.handlePause(true); 

Trong onResume(), tôi tải các url trong SharedPreferences:

if (savedInstanceState != null) { 
     webView.restoreState(savedInstanceState);   
     webView.loadUrlIntoView(savedInstanceState.getString("url")); 
    } 

Bây giờ tôi nhận được một (nasty) lỗi. Điều kỳ lạ là ứng dụng ngay lập tức gặp sự cố (không thông báo). Sau một vài cố gắng nó bắt đầu anyway.Dưới đây là các lỗi:

01-09 15:11:19.869: A/libc(3392): Fatal signal 11 (SIGSEGV) at 0x00000008 (code=1), thread 3404 (WebViewCoreThre) 
01-09 15:11:19.925: I/ActivityManager(281): Displayed my.package/.MainActivity: +197ms 
01-09 15:11:19.973: I/DEBUG(86): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
01-09 15:11:19.973: I/DEBUG(86): Build fingerprint: 'generic/vbox86tp/vbox86tp:4.1.1/JRO03L/eng.dan.20121106.232935:userdebug/test-keys' 
01-09 15:11:19.973: I/DEBUG(86): pid: 3392, tid: 3404, name: WebViewCoreThre >>> my.package <<< 
01-09 15:11:19.973: I/DEBUG(86): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008 
01-09 15:11:20.249: I/DEBUG(86):  eax 00000000 ebx b6b61c98 ecx 00000000 edx 00000001 
... 

UPDATE 2:

Khôi phục trạng thái WebView xảy ra hai lần, trong đó gây ra vấn đề. Vì vậy, loại bỏ nó từ onResume.

Trả lời

10

Những vấn đề với việc khôi phục một nhúng CordovaWebView là bởi vì sự tương tác với CordovaWebView trong onPause(), onResume(), onCreate()onDestroy() đã không xảy ra một cách chính xác. Khi bắt đầu sửa chữa, restoreState() xảy ra hai lần gây ra các vấn đề khác.

onCreate:

Next để khôi phục lại trạng thái, e cần phải thiết lập địa chỉ cơ sở CordovaWebView bằng cách sử dụng phương pháp loadUrlIntoView():

webView.restoreState(savedInstanceState); 
webView.loadUrlIntoView(savedInstanceState.getString("url")); 

onDestroy:

Chúng ta cần phải thực hiện handleDestroy() để dọn dẹp tất cả các nội dung liên quan đến PhoneGap, như PluginManager, bộ thu phát sóng, ...:

@Override 
public void onDestroy() { 
    super.onDestroy(); 

    webView.handleDestroy(); 
} 

onPause:

Trong onPause(), chúng tôi lưu trữ nhà nước 's CordovaWebView. Chúng tôi tra cứu url đã đăng ký cuối cùng và chúng tôi lưu trữ nó trong SharedPreferences. Ngoài ra, cần phải gọi số handlePause().

@Override 
protected void onPause() { 
    super.onPause(); 

    String url = webView.peekAtUrlStack(); 
    webView.handlePause(true); 

    Bundle out = new Bundle(); 
    webView.saveState(out); 
    out.putString("url", url); 

    saveToPreferences(out); 
} 

onResume:

Trong onResume() chúng ta cần phải gọi CordovaWebView 's handleResume():

webView.handleResume(true, false); 

Kết luận:

Nhúng một CordovaWebView và tiết kiệm và khôi phục trạng thái của nó là có thể, nhưng bởi vì bạn phải biết rất nhiều nội bộ từ DroidGap & CordovaWebView, KHÔNG nên làm như vậy.

Tôi hy vọng câu trả lời của tôi sẽ giúp ai đó.

+0

Điều này có thể sử dụng ['onPause'] hay không (http://docs.phonegap.com/en/1.1.0/phonegap_events_events.md.html#pause) & [' onResume'] (http: // docs .phonegap.com/vi/1.1.0/phonegap_events_events.md.html # resume) phương pháp từ khoảng cách Điện thoại. – GoodSp33d

+0

mã onCreate and on Destroy hoạt động cho tôi! cảm ơn. phương thức peekAtUrlStack không xuất hiện trong thư viện cordova của tôi ... tôi có phiên bản v2.9.1 –

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