【发布时间】:2016-02-15 18:29:01
【问题描述】:
我在使用 webview 和电源按钮时遇到活动生命周期问题。
我在 webview 中加载带有游戏的 javascript 页面,并且我将 webview 保留在应用程序上下文中,因此它可以在 Activity 破坏中幸存下来。我知道我不应该像这样保存视图,但我有非常具体的场景,它是唯一的解决方案。在应用程序之间切换时它工作正常(即使使用“不保留活动”调试标志)但是当我这样做时:
- 使用 webview 运行活动
- 游戏加载到 webview 后,按电源按钮关闭屏幕
- 重新打开屏幕
- 解锁屏幕(向上滑动)
- activity 会加载,但是 webview 没有加载,只是黑屏
我尝试打印出所有活动生命周期方法,并且在两种情况下都相同。这两种情况有什么区别?
代码应用上下文:
public class MyApp extends Application {
private WebView mWebView;
//getter, setter ...
//preserving webview in app context
}
代码活动:
public void onCreate() {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWebView();
}
private void initWebView() {
MyApp app = (MyApp) getApplication();
mWebView = app.getWebView();
if (!app.isWebViewInitialized()) {
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.requestFocus();
mWebView.addJavascriptInterface(new JavascriptInterface(this), "JSInterface");
mWebView.loadUrl("http://js-game-url.com");
mWebView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
mWebView.setWebViewClient(new WebViewClient());
app.setWebViewInitialized(true);
} else {
try {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
//todo remake the try catch
} catch(NullPointerException e) {
System.out.println("Null"); //todo remove try catch
}
}
webviewPlaceholder = (RelativeLayout) findViewById(R.id.rlayout2);
webviewPlaceholder.addView(mWebView);
}
protected void onPause() {
super.onPause();
webviewPlaceholder.removeView(mWebView);
}
protected void onResume() {
super.onResume();
initWebView();
}
protected void onDestroy() {
super.onDestroy();
webviewPlaceholder.removeView(mWebView);
}
我肯定错过了一些简单的东西,但我找不到解决方案。
【问题讨论】:
-
对不起,我删除了我的其他答案。在尝试了解您要做什么之后,我认为这是不可能的。 WebView 并非旨在通过保存持久状态来像完整的 Web 浏览器一样长时间保存(甚至 saveState 和 restoreState 方法都不会做你想做的事情。如果你真的需要保存状态,你将不得不构建WebView 内容和应用程序之间的 javascript 桥梁,并确保它可以保存和恢复您需要的任何内容。
-
它工作正常,您可以终止活动,并且 webview 与游戏进度一起正确存储,并在再次创建活动后重新加载。问题是当您使用电源按钮关闭屏幕与在 2 个打开的活动之间切换时,活动的生命周期可能存在一些差异。
-
如果JS还没有加载,当你关闭屏幕时,你的工作很可能会停止,因为你没有CPU的唤醒锁。如果您完全加载游戏,然后在加载完所有内容后关闭屏幕会发生什么?
-
@Darwind 在这两种情况下,webview 都不会加载,但我想我知道问题出在哪里。它不是活动生命周期,而是 javascript 或游戏生命周期。因为当窗口失去焦点时游戏会自行暂停,并且我认为 js 在这两种情况下会触发不同的事件,所以我必须通过一些简单的示例对其进行测试。
-
是的,我是对的 - webview 在我的场景中没有获得焦点:mWebView.requestFocus();解决了问题
标签: android android-activity webview android-lifecycle