android 保存webview状态在片断中

5jdjgkvh  于 2023-03-11  发布在  Android
关注(0)|答案(2)|浏览(119)

我基本上是使用导航组件与图表。我从主页片段导航到网页片段时,我打开了网址在一个网页视图。我的问题是,我想保存网页视图状态时,我离开网页片段,当我回来,我想显示保存的示例,而不是重新加载整个页面,但我所做的到目前为止是行不通的。如果有人能帮助,我会很感激。谢谢

  • 这是我的密码
public class TestFragment extends Fragment {

    private WebView webView;
    private Bundle webViewBundle;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.test_layout, container, false);
        webView = v.findViewById(R.id.webView);

        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new MyWebViewClient());
        if(webViewBundle != null){
            webView.restoreState(webViewBundle);
        } else {
            assert getArguments() != null;
            String url = getArguments().getString("url");
            webView.loadUrl(url);
        }
        return v;
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        webView.restoreState(savedInstanceState);
    }

    @Override
    public void onPause() {
        super.onPause();
        webViewBundle = new Bundle();
        webView.saveState(webViewBundle);
    }

    class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            webView.loadUrl(url);
            webView.saveState(webViewBundle);
            return true;
        }
    }
}
f0brbegy

f0brbegy1#

尝试使用onSaveInstanceState方法,而不是创建“虚拟”Bundle,将WebView的状态保存到其中(在onPause中),然后...不对此Bundle执行任何操作-它将被GC'艾德,状态丢失(当Fragment被销毁,并将创建新示例时)

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    webView.saveState(outState);
    super.onSaveInstanceState(outState);
}
bcs8qyzn

bcs8qyzn2#

您需要将创建的bundle保存在某个地方,根据不同的用例,您存储bundle的位置可能会有所不同-saveState的设计用例是在活动重新创建期间,您将其放入onSaveInstanceState并在onRestoreInstanceState中恢复,如@snachmsm的回答所建议的那样。
但是,如果您希望处理用户离开并且片段从回栈中移除的情况,这将不会有任何帮助。例如,如果您有一个带有多个片段的选项卡式Activity,在这种情况下,您可能希望将bundle传递给Activity以保留,并使用https://developer.android.com/guide/fragments/communicate中描述的模式。
例如,可以按如下方式定义视图模型:

class WebViewModel : ViewModel() {
    val webViewState = Bundle()
}

然后在Activity和片段之间共享它们:

class MainActivity : AppCompatActivity() {
    private val viewModel: WebViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}

class WebFragment : Fragment() {
    private val viewModel: WebViewModel by activityViewModels()

    override fun onCreateView(): View {
        val webview = ... // inflate the webview
        webview.restoreState(viewModel.webViewState)
        return webview
    }

    override fun onDestroyView() {
        webView.saveState(viewModel.webViewState)
    }
}

如果您想更进一步,即使活动结束也要让用户回到同一页面,据我所知,没有好的方法。由于Bundle本身是不可持久的,因此您无法将其写入磁盘而不冒兼容性问题的风险。它可能会根据WebView实现工作,如How can i save and restore android WebView's WebBackForwardList?中所述。但如果您尝试这样做,请准备好处理任何错误。
还有copyBackForwardList(),它允许你获取WebBackForwardList,它的所有公共API数据都是持久的,但是,没有API可以在重新创建后将列表恢复/设置/注入到WebView中,所以你必须通过重复调用setUrl来重放历史记录,或者使用javascript History API
这些都不是特别好的选择,所以我建议你考虑一下“恢复”的要求是否可以放宽,只回到堆栈上的最后一个(当前)页面,而不是恢复完整的历史记录。显然不理想,但如果你只是嵌入一个网页视图来与一些简单的网页交互,而不是构建自己的浏览器,这是一个合理的妥协。

相关问题