2016-07-19 1 views
4

Я успешно привязал WebView к моему приложению Kivy following Kivy wiki instructions. Он работает так, как ожидалось, но я хотел бы отключить и вернуться к своей обычной Kivy ui. Как это сделать?Как отключить веб-просмотр после прикрепления?

Я пытался исследовать WebView documentation, доступ к его методам (WebView.destroy() жалуется на уничтожение WebView, что все еще прилагается), это родительские методы (я даже не уверен, что это путь), но я не мог избавиться от WebView.

+0

Используйте WebView.loadUrl («about: blank»), чтобы надежно сбросить состояние представления и освободить ресурсы страницы (включая любой запущенный JavaScript). Это позволяет вам уничтожить веб-представление? – RandomHash

+0

Я мало знаю о Киви, но вы можете взглянуть на http://stackoverflow.com/a/28964755/4033690 – momo

+0

На самом деле я нашел способ обойти это, я не уверен, что это лучший но работает. На самом деле это не проблема разрушения самого веб-сайта, проблема заключается в том, что активность приложения становится «принадлежащей» веб-просмотру (методы finish(), destroy() фактически убили бы все приложение, а не только веб-просмотр), поэтому требуется немного из жонглирования с ui нитью android.runnable и kivy's mainthread. Как я уже сказал, я не уверен, что это лучший способ, но это единственный способ, о котором я знаю. Я отправлю ответ в ближайшее время, когда у меня будет время. – kilbee

ответ

2

Хорошо, я не уверен, является ли это лучшим решением или достаточно чистым, но единственное, что я знаю, это работает. Несмотря на то, что он работает и кажется стабильным, он нуждается в дальнейшем тестировании кем-то с лучшими знаниями о Kivy и Android API.

if platform == 'android': 
    from jnius import autoclass 
    from android.runnable import run_on_ui_thread 
    WebView = autoclass('android.webkit.WebView') 
    WebViewClient = autoclass('android.webkit.WebViewClient') 
    activity = autoclass('org.renpy.android.PythonActivity').mActivity 
else: 
    import webbrowser 
    def run_on_ui_thread(func): 
     ''' just for desktop compatibility ''' 
     return func 


class MyScreen(Screen): 
    view_cached = None # make these object properties? 
    webview  = None 
    wvc   = None # not even needed probably 
    code  = StringProperty() # this property triggers webview to close 
    url_to_load = None 

    def on_enter(self): 
     if platform == 'android': 
      Clock.schedule_once(self.create_webview, 0) # probably doesn't need clocked call (because decorators will make sure 
                 # function runs on correct thread), but leaving it until tested properly 
     else:   
      webbrowser.open_new(self.url_to_load)  # on desktop just run the webbrowser 

    @run_on_ui_thread 
    def on_code(self, *args): 
     ''' runs when you are ready to detach WebView ''' 
     self.detach_webview() 

    @run_on_ui_thread 
    def create_webview(self, *args): 
     ''' attaching webview to app ''' 
     if self.view_cached is None: 
      self.view_cached = activity.currentFocus # caches current view (the one with kivy) as a view we want to go back to; currentFocus or getCurrentFocus() works 
     self.webview = WebView(activity) 
     settings = self.webview.getSettings() 
     settings.setJavaScriptEnabled(True)   # enables js 
     settings.setUseWideViewPort(True)   # enables viewport html meta tags 
     settings.setLoadWithOverviewMode(True)  # uses viewport 
     settings.setSupportZoom(True)    # enables zoom 
     settings.setBuiltInZoomControls(True)  # enables zoom controls 
     self.wvc = WebViewClient() 
     self.webview.setWebViewClient(self.wvc) 
     activity.setContentView(self.webview) 
     self.webview.loadUrl(self.url_to_load) 

    @run_on_ui_thread 
    def key_back_handler(self, *args): 
     ''' sketch for captured "key back" event (in App), not tested properly ''' 
     if self.webview: 
      if self.webview.canGoBack() == True: 
       self.webview.goBack() 
      else: 
       self.detach_webview() 
       Clock.schedule_once(self.quit_screen, 0) 
     else: 
      App.get_running_app().root.current = 'some_other_screen_to_switch_to' 

    @run_on_ui_thread 
    def detach_webview(self, *args): 
     if self.webview: 
      self.webview.clearHistory() 
      self.webview.clearCache(True) 
      self.webview.loadUrl("about:blank") 
      self.webview.freeMemory()     # probably not needed anymore 
      self.webview.pauseTimers()     # this should stop any playing content like videos etc. in the background; probably not needed because of 'about:blank' above 
      activity.setContentView(self.view_cached) # sets cached view as an active view 
      #self.webview = None # still needs testing; 
      #self.wvc = None    

    @mainthread 
    def quit_screen(self, *args): 
     ''' if not called on @mainthread, it will be freezed ''' 
     app = App.get_running_app() 
     app.root.current = 'some_other_screen_to_switch_to' 

Я создаю WebView при входе MyScreen (экран), а при отсоединении WebView, переключаясь на какой-либо другой экран.

Перед тем, как WebView получит кеширование (возможно, было бы лучше получить доступ к нему каким-либо другим способом) и снова использовать, когда WebView будет уничтожен. Вызовы quit_screen(), возможно, должны быть перенесены в detach_webview(), но в целом код, вероятно, нуждается в лучшей организации, поэтому оставить его как есть, так как это проверенный образец.

+0

рабочий пример https://github.com/suchyDev/Kivy-Dynamic-Screens-Template/blob/master/screens/screenwebview.py – kilbee

Смежные вопросы