[OK]を私はこれが最高の解決策か、十分にきれいであるかわかりませんが、私が知っている唯一のものです。それが動作し、安定しているようだが、それは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を作成し、WebViewのを取り外す際に、他のいくつかの画面に戻って切り替えています。
WebViewがキャッシュされる前のビュー(これは効率的でしょうか?別の方法でアクセスするほうがよいでしょう)、WebViewが破棄されたときに再び使用されます。 quit_screen()呼び出しはdetach_webview()に移動する必要があるかもしれませんが、コード全体がより良い編成を必要とする可能性があります。
WebView.loadUrl( "about:blank")を使用すると、ビューステートを確実にリセットし、ページリソース(実行中のJavaScriptを含む)を解放できます。これにより、Webビューを破棄できますか? – RandomHash
私はKivyについてよく分かりませんが、http://stackoverflow.com/a/28964755/4033690を参照してください。 – momo
実際に私はこれを回避する方法を見つけました。方法、しかし働く。実際にはwebview自体を破壊する問題ではなく、appviewはwebviewによって所有されています(finish()、destroy()メソッドはwebviewだけでなく、アプリ全体を実際に終了します)。 android.runnableとkivyのメインスレッドのUIスレッドとのジャグリングはほとんどありません。私が言ったように、私はこれが最善の方法であるかどうかはわかりませんが、私が知っている唯一の方法です。私はちょうど時間があるときに私はすぐに答えを投稿します。 – kilbee