Repository: Tencent/VasSonic Branch: master Commit: 59936beff656 Files: 288 Total size: 2.1 MB Directory structure: gitextract_nx2cxqfl/ ├── .gitignore ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE ├── LICENSE ├── README.md ├── assets/ │ ├── Sonic2.0.md │ ├── VasSonic3.0_preload.md │ └── sonic发展历程.md ├── checkstyle.xml ├── sonic-android/ │ ├── .gitignore │ ├── README.md │ ├── build.gradle │ ├── docs/ │ │ ├── Sonic Quick模式实现原理.md │ │ ├── Sonic Standard模式实现原理.md │ │ ├── Sonic接入指引.md │ │ ├── Sonic框架介绍.md │ │ ├── javadoc/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── com/ │ │ │ │ └── tencent/ │ │ │ │ └── sonic/ │ │ │ │ └── sdk/ │ │ │ │ ├── QuickSonicSession.html │ │ │ │ ├── SonicCacheInterceptor.html │ │ │ │ ├── SonicConfig.Builder.html │ │ │ │ ├── SonicConfig.html │ │ │ │ ├── SonicConstants.html │ │ │ │ ├── SonicDBHelper.html │ │ │ │ ├── SonicDiffDataCallback.html │ │ │ │ ├── SonicEngine.html │ │ │ │ ├── SonicFileUtils.html │ │ │ │ ├── SonicResourceDataHelper.ResourceData.html │ │ │ │ ├── SonicResourceDataHelper.html │ │ │ │ ├── SonicRuntime.html │ │ │ │ ├── SonicServer.html │ │ │ │ ├── SonicSession.Callback.html │ │ │ │ ├── SonicSession.html │ │ │ │ ├── SonicSessionClient.html │ │ │ │ ├── SonicSessionConfig.Builder.html │ │ │ │ ├── SonicSessionConfig.html │ │ │ │ ├── SonicSessionConnection.SessionConnectionDefaultImpl.html │ │ │ │ ├── SonicSessionConnection.html │ │ │ │ ├── SonicSessionConnectionInterceptor.html │ │ │ │ ├── SonicSessionStatistics.html │ │ │ │ ├── SonicSessionStream.Callback.html │ │ │ │ ├── SonicSessionStream.html │ │ │ │ ├── SonicUtils.html │ │ │ │ ├── StandardSonicSession.html │ │ │ │ ├── download/ │ │ │ │ │ ├── SonicDownloadCache.SonicResourceCache.html │ │ │ │ │ ├── SonicDownloadCache.html │ │ │ │ │ ├── SonicDownloadCallback.SimpleDownloadCallback.html │ │ │ │ │ ├── SonicDownloadCallback.html │ │ │ │ │ ├── SonicDownloadClient.DownloadTask.html │ │ │ │ │ ├── SonicDownloadClient.SonicDownloadConnection.html │ │ │ │ │ ├── SonicDownloadClient.SubResourceDownloadCallback.html │ │ │ │ │ ├── SonicDownloadClient.html │ │ │ │ │ ├── SonicDownloadEngine.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ └── package-tree.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ └── package-tree.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-frame.html │ │ │ ├── overview-summary.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── script.js │ │ │ └── stylesheet.css │ │ └── sdk-3.0.0-javadoc.jar │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── sample/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── sonic-demo-index.html │ │ ├── java/ │ │ │ └── com/ │ │ │ └── tencent/ │ │ │ └── sonic/ │ │ │ └── demo/ │ │ │ ├── BrowserActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── SonicJavaScriptInterface.java │ │ │ ├── SonicRuntimeImpl.java │ │ │ ├── SonicSessionClientImpl.java │ │ │ ├── UrlListAdapter.java │ │ │ └── UrlSelector.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_add_circle_accent_24dp.xml │ │ │ ├── ic_add_circle_black_24dp.xml │ │ │ ├── ic_add_circle_selector.xml │ │ │ ├── ic_remove_circle_accent_24dp.xml │ │ │ └── sonic_button_round_mask.xml │ │ ├── layout/ │ │ │ ├── activity_browser.xml │ │ │ ├── activity_main.xml │ │ │ ├── dialog_url.xml │ │ │ └── list_item_url.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── sdk/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── tencent/ │ │ │ └── sonic/ │ │ │ └── sdk/ │ │ │ ├── BaseSonicTest.java │ │ │ ├── ExampleInstrumentedTest.java │ │ │ ├── QuickSonicSessionTest.java │ │ │ ├── SonicRuntimeImplTest.java │ │ │ ├── SonicSessionClientImplTest.java │ │ │ └── SonicTestData.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── tencent/ │ │ │ └── sonic/ │ │ │ └── sdk/ │ │ │ ├── QuickSonicSession.java │ │ │ ├── SonicCacheInterceptor.java │ │ │ ├── SonicConfig.java │ │ │ ├── SonicConstants.java │ │ │ ├── SonicDBHelper.java │ │ │ ├── SonicDataHelper.java │ │ │ ├── SonicDiffDataCallback.java │ │ │ ├── SonicEngine.java │ │ │ ├── SonicFileUtils.java │ │ │ ├── SonicResourceDataHelper.java │ │ │ ├── SonicRuntime.java │ │ │ ├── SonicServer.java │ │ │ ├── SonicSession.java │ │ │ ├── SonicSessionCallback.java │ │ │ ├── SonicSessionClient.java │ │ │ ├── SonicSessionConfig.java │ │ │ ├── SonicSessionConnection.java │ │ │ ├── SonicSessionConnectionInterceptor.java │ │ │ ├── SonicSessionStatistics.java │ │ │ ├── SonicSessionStream.java │ │ │ ├── SonicSessionThreadPool.java │ │ │ ├── SonicSniSSLSocketFactory.java │ │ │ ├── SonicUtils.java │ │ │ ├── StandardSonicSession.java │ │ │ └── download/ │ │ │ ├── SonicDownloadCache.java │ │ │ ├── SonicDownloadCallback.java │ │ │ ├── SonicDownloadClient.java │ │ │ └── SonicDownloadEngine.java │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── settings.gradle ├── sonic-iOS/ │ ├── .gitignore │ ├── README.md │ ├── Sonic/ │ │ ├── Cache/ │ │ │ ├── SonicCache.h │ │ │ ├── SonicCache.m │ │ │ ├── SonicCacheItem.h │ │ │ ├── SonicCacheItem.m │ │ │ ├── SonicDatabase.h │ │ │ └── SonicDatabase.m │ │ ├── Engine/ │ │ │ ├── SonicConfiguration.h │ │ │ ├── SonicConfiguration.m │ │ │ ├── SonicEngine.h │ │ │ └── SonicEngine.m │ │ ├── Info.plist │ │ ├── Network/ │ │ │ ├── SonicConnection.h │ │ │ ├── SonicConnection.m │ │ │ ├── SonicServer.h │ │ │ ├── SonicServer.m │ │ │ ├── SonicURLProtocol.h │ │ │ └── SonicURLProtocol.m │ │ ├── ResourceLoader/ │ │ │ ├── SonicResourceLoadOperation.h │ │ │ ├── SonicResourceLoadOperation.m │ │ │ ├── SonicResourceLoader.h │ │ │ └── SonicResourceLoader.m │ │ ├── Session/ │ │ │ ├── SonicSession.h │ │ │ ├── SonicSession.m │ │ │ ├── SonicSessionConfiguration.h │ │ │ └── SonicSessionConfiguration.m │ │ ├── Sonic.h │ │ ├── SonicConstants.h │ │ ├── SonicProtocol.h │ │ ├── Statistics/ │ │ │ ├── SonicEventConstants.h │ │ │ ├── SonicEventStatistics.h │ │ │ └── SonicEventStatistics.m │ │ └── Util/ │ │ ├── SonicUtil.h │ │ └── SonicUtil.m │ ├── Sonic.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── Sonic.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── SonicSample/ │ │ ├── SonicSample/ │ │ │ ├── 36f620dddab622727b270e6b79b20a98/ │ │ │ │ └── main.html │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ ├── RootViewController.h │ │ │ ├── RootViewController.m │ │ │ ├── SonicEventObserver.h │ │ │ ├── SonicEventObserver.m │ │ │ ├── SonicJSContext.h │ │ │ ├── SonicJSContext.m │ │ │ ├── SonicOfflineCacheConnection.h │ │ │ ├── SonicOfflineCacheConnection.m │ │ │ ├── SonicWebViewController.h │ │ │ ├── SonicWebViewController.m │ │ │ └── main.m │ │ ├── SonicSample.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ └── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── SonicSampleUITests/ │ │ ├── Info.plist │ │ └── SonicSampleUITests.m │ └── docs/ │ ├── iOS终端实现原理.md │ └── 终端接入指引-iOS版本.md ├── sonic-java/ │ ├── README.md │ ├── apidocs/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── com/ │ │ │ └── github/ │ │ │ └── tencent/ │ │ │ ├── AbstractReplaceCallBack.html │ │ │ ├── HttpServletResponseCopier.html │ │ │ ├── ReplaceCallBack.html │ │ │ ├── ServletOutputStreamCopier.html │ │ │ ├── SonicFilter.html │ │ │ ├── SonicUtil.html │ │ │ ├── class-use/ │ │ │ │ ├── AbstractReplaceCallBack.html │ │ │ │ ├── HttpServletResponseCopier.html │ │ │ │ ├── ReplaceCallBack.html │ │ │ │ ├── ServletOutputStreamCopier.html │ │ │ │ ├── SonicFilter.html │ │ │ │ └── SonicUtil.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── script.js │ │ └── stylesheet.css │ ├── lib/ │ │ ├── VasSonic-1.1-javadoc.jar │ │ ├── VasSonic-1.1-sources.jar │ │ └── VasSonic-1.1.jar │ ├── sample/ │ │ └── webapp/ │ │ ├── WEB-INF/ │ │ │ ├── lib/ │ │ │ │ └── VasSonic-1.1.jar │ │ │ └── web.xml │ │ └── index.jsp │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── github/ │ └── tencent/ │ ├── AbstractReplaceCallBack.java │ ├── HttpServletResponseCopier.java │ ├── ReplaceCallBack.java │ ├── ServletOutputStreamCopier.java │ ├── SonicFilter.java │ └── SonicUtil.java ├── sonic-nodejs/ │ ├── .gitignore │ ├── README.md │ ├── README_CN.md │ ├── app.js │ ├── assets/ │ │ ├── build/ │ │ │ └── gulpfile.js │ │ ├── package.json │ │ ├── page/ │ │ │ ├── demo1.ejs │ │ │ ├── demo1.js │ │ │ ├── demo2-data.js │ │ │ ├── demo2.ejs │ │ │ ├── demo2.js │ │ │ ├── demo3-data.js │ │ │ ├── demo3.ejs │ │ │ ├── demo3.js │ │ │ ├── index.ejs │ │ │ ├── index.js │ │ │ └── tpls/ │ │ │ ├── common_body_header.ejs │ │ │ ├── common_body_header.js │ │ │ ├── common_header.ejs │ │ │ ├── common_header.js │ │ │ ├── common_meta.ejs │ │ │ └── common_meta.js │ │ └── project.config.js │ ├── common/ │ │ └── diff.js │ ├── middleware/ │ │ └── compress.js │ ├── package.json │ └── router/ │ ├── config.js │ └── index.js ├── sonic-php/ │ ├── README.md │ ├── sample/ │ │ ├── README.md │ │ ├── controller/ │ │ │ └── demo.php │ │ ├── index.php │ │ ├── js/ │ │ │ └── sonic-3.js │ │ ├── util/ │ │ │ └── sonic.php │ │ └── view/ │ │ └── demo_template.php │ └── sdk/ │ └── sonic.php └── sonic-react/ ├── README.md ├── README_CN.md ├── components/ │ ├── GameArea.js │ ├── GameFooter.js │ └── GameHeader.js ├── containers/ │ └── GameContainer.js ├── package.json ├── pages/ │ └── demo.js ├── redux/ │ └── duck.js ├── server.js └── static/ └── js/ └── flexible.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # MacOS .DS_Store # Windows *.txt .idea/ ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to VasSonic Welcome to [report Issues](https://github.com/Tencent/VasSonic/issues) or [pull requests](https://github.com/Tencent/VasSonic/pulls). It's recommended to read the following Contributing Guide first before contributing. ## Issues We use Github Issues to track public bugs and feature requests. ### Search Known Issues First Please search the existing issues to see if any similar issue or feature request has already been filed. You should make sure your issue isn't redundant. ### Reporting New Issues If you open an issue, the more information the better. Such as detailed description, screenshot or video of your problem, logcat or code blocks for your crash. ## Pull Requests We strongly welcome your pull request to make VasSonic better. ### Branch Management There are two main branches here: 1. `master` branch. 1. It is the latest (pre-)release branch. We use `master` for tags, with version number `1.1.0`, `1.2.0`, `1.3.0`... 2. **Don't submit any PR on `master` branch.** 2. `dev` branch. 1. It is our stable developing branch. After full testing, `dev` will be merged to `master` branch for the next release. 2. **You are recommended to submit bugfix or feature PR on `dev` branch.** Normal bugfix or feature request should be submitted to `dev` branch. After full testing, we will merge them to `master` branch for the next release. ``` master ↑ dev ↑ feature/bugfix PR ``` ### Make Pull Requests The code team will monitor all pull request, we run some code check and test on it. After all tests passed, we will accecpt this PR. But it won't merge to `master` branch at once, which have some delay. Before submitting a pull request, please make sure the followings are done: 1. Fork the repo and create your branch from `master`. 2. Update code or documentation if you have changed APIs. 3. Add the copyright notice to the top of any new files you've added. 4. Check your code lints and checkstyles. 5. Test and test again your code. 6. Now, you can submit your pull request on `dev`. ## Code Style Guide Use [Code Style](https://github.com/Tencent/VasSonic/blob/master/checkstyle.xml) for Java and Android. * 4 spaces for indentation rather than tabs ## License By contributing to VasSonic, you agree that your contributions will be licensed under its [BSD LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) ================================================ FILE: ISSUE_TEMPLATE ================================================ What steps will reproduce the problem? 该问题的重现步骤是什么? 1. 2. 3. What is the expected output? What do you see instead? 你期待的结果是什么?实际看到的又是什么? What version of the product are you using? On what operating system? 你正在使用产品的哪个版本?在什么操作系统上? Please provide any additional information below. 如果有的话,请在下面提供更多信息。 ================================================ FILE: LICENSE ================================================ Tencent is pleased to support the open source community by making VasSonic available. Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. If you have downloaded a copy of the VasSonic binary from Tencent, please note that the VasSonic binary is licensed under the BSD 3-Clause License. If you have downloaded a copy of the VasSonic source code from Tencent, please note that VasSonic source code is licensed under the BSD 3-Clause License, except for the third-party components listed below which are subject to different license terms. Your integration of VasSonic into your own projects may require compliance with the BSD 3-Clause License, as well as the other licenses applicable to the third-party components included within VasSonic. A copy of the BSD 3-Clause License is included in this file. Other dependencies and licenses: Open Source Software Licensed Under the Apache License, Version 2.0: ---------------------------------------------------------------------------------------- 1. Android Source Code 4.4_r1 Copyright (C) 2005-2015 The Android Open Source Project Terms of the Apache License, Version 2.0: -------------------------------------------------------------------- Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License. “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.” “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: a) You must give any other recipients of the Work or Derivative Works a copy of this License; and b) You must cause any modified files to carry prominent notices stating that You changed the files; and c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Terms of the BSD 3-Clause License: -------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of [copyright holder] nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ ## VasSonic: A Lightweight And High-performance Hybrid Framework [![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki) ---

logo

VasSonic is a lightweight and high-performance Hybrid framework developed by tencent VAS team, which is intended to speed up the first screen of websites working on Android and iOS platform. Not only does VasSonic supports the static or dynamic websites which are rendered by server, but it is also compatible with web offline resource perfectly. VasSonic uses custom url connection instead of original network connection to request the index html, so it can request resource in advance or parallel to avoid waiting for the view initialization. In this parallel case, VasSonic can read and render partial data by WebKit or Blink kernel without spending too much time waiting for the end of data stream. VasSonic can cache html cleverly according to VasSonic Specification obeyed by client and server. VasSonic Specification specify template and data by inserting different comment anchor, templates are bigger parts of html which stay the same or changed rarely , in contradiction data, which is the smaller and constantly change part of html. According to this, VasSonic request less data by incremental updating templates and data, the websites are faster and feel more like native application. In conclusion, VasSonic effectively enhance the user experience and increase click rate, retention rate and other indicators. Sonic is called for short in project. ### Before VS After Using VasSonic Pic 1: Before Using VasSonic | Pic 2: After Using VasSonic :-------------------------:|:-------------------------: ![default mode][1] | ![VasSonic mode][2] ## Getting started [Getting started with Android](https://github.com/Tencent/VasSonic/blob/master/sonic-android/README.md) [Getting started with iOS](https://github.com/Tencent/VasSonic/blob/master/sonic-iOS/README.md) [Getting started with Java](https://github.com/Tencent/VasSonic/blob/dev/sonic-java/README.md) [Getting started with Node.js](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/README.md) [Getting started with PHP](https://github.com/Tencent/VasSonic/blob/master/sonic-php/README.md) [Getting started with React](https://github.com/Tencent/VasSonic/blob/master/sonic-react/README.md) ## Demo Downloads 1. [Here](https://github.com/Tencent/VasSonic/releases) are the latest sample demo for Android and iOS. ## Support Any problem? 1. Learn more from the following sample.
[Android sample](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sample)
[iOS sample](https://github.com/Tencent/VasSonic/tree/master/sonic-iOS/SonicSample)
[Java sample](https://github.com/Tencent/VasSonic/tree/dev/sonic-java/sample/webapp)
[Node.js sample](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs)
[PHP sample](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sample)
[React sample](https://github.com/Tencent/VasSonic/tree/master/sonic-react)
2. Read the following source code
[Android source code](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sdk)
[iOS source code](https://github.com/Tencent/VasSonic/tree/master/sonic-iOS/Sonic)
[Java source code](https://github.com/Tencent/VasSonic/tree/dev/sonic-java/src/main/java/com/github/tencent) [Node.js source code](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs)
[PHP source code](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sdk)
[React source code](https://github.com/Tencent/VasSonic/tree/master/sonic-react)
3. Read the [wiki](https://github.com/Tencent/VasSonic/wiki) for help. 4. Contact [us](https://jq.qq.com/?_wv=1027&k=4EaxB4K) or scan QR code for help.
![QR code][3] ## Contributing For more information about contributing issues or pull requests, see our [VasSonic Contributing Guide](https://github.com/Tencent/VasSonic/blob/master/CONTRIBUTING.md). ## License VasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details. ## The End If you are interested in VasSonic, don't forget to STAR [it](https://github.com/Tencent/VasSonic). VasSonic's mission is MAKING WEB MUCH BETTER! Thank you for reading ~ [1]: https://github.com/Tencent/VasSonic/blob/master/assets/20170705120005424.gif [2]: https://github.com/Tencent/VasSonic/blob/master/assets/20170705120029897.gif [3]: https://github.com/Tencent/VasSonic/blob/master/assets/QR.JPG [4]: https://github.com/Tencent/VasSonic/blob/master/assets/logo.png ================================================ FILE: assets/Sonic2.0.md ================================================ Sonic 2.0相比1.0,主要新增了以下几个特性: * 支持纯终端模式(Local Server模式),在该模式下无需后台配合亦可完成秒开; * 支持自定义请求头和自定义响应头; * 支持Cache-Control来控制缓存生命周期; * 支持非utf-8编码。 # Local Server模式 ## Local Server模式介绍 Local Server模式是Sonic 2.0新增的纯终端模式,相比于Sonic 1.0需要终端、前端、后台全部改造接入Sonic,Local Server模式可以在业务后台无法及时支持时,通过终端模拟Server实现Sonic逻辑,从而降低接入成本。 Local Server的开启方式如下: SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); sessionConfigBuilder.setSupportLocalServer(true); sessionConfigBuilder.build(); 开启Local Server模式后,对于一般页面的请求,Sonic会模拟Sonic后台,对返回的页面数据进行eTag的计算,以及模板和数据的拆分,对比本地缓存的数据,添加sonic响应头(eTag、template-change、template-tag)。最后根据Server数据和本地缓存数据的对比结果,来决定此次请求模式是完全缓存、局部刷新还是模板更新,从而执行不同的刷新逻辑。后台无需接入sonic,也能体验页面秒开。 ## Local Server执行流程 ### 1、首次请求 首次请求也就是无缓存情况下发起的请求,与普通Sonic无缓存模式流程一致。具体细节可参考QuickSonicSession和StandardSonicSession的无缓存模式流程。 ### 2、非首次请求 非首次请求也就是有缓存情况下发起的请求,分为完全缓存、局部刷新、模板变更三种情况。 #### (1) 完全缓存 完全缓存就是本地的数据跟服务器的数据是完全一样的。以Quick模式为例,Local Server的执行流程如下图: ![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeCache.png) 上图主要展示了两条并行线,左边是在主线程执行的Webview流程,右边是在子线程执行Sonic流程。 **Sonic线程:** Sonic会话创建完成后,首先获取url对应的本地缓存数据,并通知主线程Webview加载该数据。接着Sonic会与Server建立连接,如果Server返回304,则Server数据没有变更,直接使用本地缓存,Sonic流程结束;否则,Sonic拉取到完整的Server数据,计算其SHA1作为eTag,如果与请求头中的eTag相同,就确定本次请求是完全缓存模式,Sonic流程结束。 **主线程:** 主线程在收到Sonic通知后,加载本地缓存数据,交给Webview渲染。 #### (2) 局部刷新 局部刷新就是本地的数据跟服务器的数据相比,只有data部分有变化,模板与服务器一样。 ![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeDataUpdate.png) **Sonic线程:** Sonic会话创建完成后,首先获取url对应的本地缓存数据,并通知主线程Webview加载该数据。接着Sonic与Server建立连接,读取到完整的Server数据,计算其SHA1作为eTag,如果与请求头中的eTag不同,Sonic将Server数据拆分为template和data,计算template的SHA1作为template-tag,如果与请求头中的template-tag相同,则说明模板没有变更,此时确定本次请求是局部刷新,将拆分得到的data与本地保存的data做对比计算,得到增量数据。最后通知Webview进行局部刷新,并更新本地缓存。 **主线程:** 局部刷新模式下主线程会先收到加载本地缓存数据的通知,而Sonic线程通知主线程刷新data时,主线程可能还未开始加载本地缓存,也可能已经开始渲染本地缓存。如果WebView还未开始加载本地缓存,就会直接加载最新的数据(拆分得到的data跟本地模版合成的数据);如果主线程已经加载本地缓存,就会直接通过Js接口让WebView用增量数据刷新页面。 #### (3) 模板更新 模板更新是本地的模板跟服务器的模板不一致。 ![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeTemplateChange.png) **Sonic线程:** Sonic会话创建完成后,首先获取url对应的本地缓存数据,并通知主线程Webview加载该数据。接着Sonic与Server建立连接,读取到完整的Server数据,计算其SHA1作为eTag,如果与请求头中的eTag不同,Sonic将Server数据拆分为template和data,计算template的SHA1作为template-tag,如果与请求头中的template-tag不同则说明模板发生了变更,此时确定本次请求是模板刷新模式,通知主线程Webview进行模板刷新,并更新本地缓存。 **主线程:** 主线程会先收到加载本地缓存数据的通知,之后Sonic线程通知主线程进行模板刷新时,无论WebView是否已经开始加载本地缓存数据,都会直接重新加载最新的Server数据,完成模板刷新。 # 其他新增特性 ### 1、支持自定义请求头和自定义响应头 Sonic 2.0支持添加自定义请求头和自定义响应头,添加方式如下: SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); sessionConfigBuilder.setCustomRequestHeaders(requestHeaderMap); sessionConfigBuilder.setCustomResponseHeaders(responseHeaderMap); sessionConfigBuilder.build(); ### 2、支持Cache-Control来控制缓存生命周期 Sonic 2.0支持在Http响应头部添加Cache-Control字段来控制缓存生命周期,目前支持max-age、private、public三个可选值。 ### 3、支持非UTF-8编码 Sonic 2.0优化了字符编码的使用。如果http响应头中包含"Content-Type"字段,则优先使用该字段的值作为字符编码,否则默认使用UTF-8编码。 # FAQ ### 1、Sonic后台返回的数据与非sonic后台返回的数据的区别? 接入了Sonic的Server返回的数据,http响应头会包含"cache-offline"、"template-change"或者"template-tag"字段,而未接入Sonic的Server返回的数据,响应头中不会包含以上三个字段。 ### 2、Local Server模式的优缺点? **优点:** Local Server模式下,简化了终端执行逻辑;而且无需后台接入Sonic,大大减少了接入成本。 **缺点:** Local Server模式相比后台接入,损失了一定的性能。因为终端模拟后台的话,非首次请求场景需要等Server数据全部返回才能计算eTag,template-tag,template-change,从而判断是哪种模式(完全缓存、局部刷新还是模板更新)。 ================================================ FILE: assets/VasSonic3.0_preload.md ================================================ # Sonic 3.0 子资源预下载功能特性介绍 ## 1 子资源预下载 VasSonic中子资源预下载功能的灵感就来源于Chrome中的\。 > \:\元素的rel属性的属性值preload能够让你在你的HTML页面中\元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源,你可能希望在页面加载的生命周期的早期阶段就开始获取,在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。 ### 1.1 子资源预下载开启方式 想要开启VasSonic 3.0中的子资源预下载功能,需要终端或者后台参与。在请求主资源时,由后台在Response Header中添加一个名为```sonic-link```的响应头部字段,这个字段的值指定了期望得到预下载的子资源,不同的子资源url之间由";"区分。可以预下载的子资源类型包括图片、css样式文件、js脚本文件等等。示例如下: ```http sonic-link: http://test.js;http://test.css;http://test.jpg ``` 除了后台返回```sonic-link```相应头,也可以通过终端指定```sonic-link```,方式如下: ```java SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); Map headers = new HashMap(); headers.put("sonic-link", "http://test.js;http://test.css;http://test.jpg"); sessionConfigBuilder.setCustomResponseHeaders(headers); sessionConfigBuilder.build(); ``` ### 1.2 子资源预下载的流程说明 VasSonic检测到主资源响应头中的```sonic-link```字段时,子资源预下载模块就会开始工作,具体执行流程如下图: ![子资源预下载模块的流程](subresource_preload.png) 1. 对```sonic-link```字段中的字资源进行下载是在单独的预下载线程中进行; 2. 当内核请求的子资源url不在```sonic-link```头中时,VasSonic不做处理,完全抛给内核; 3. 当内核请求的子资源url在```sonic-link```头中时,有以下四种情况: - 如果对应的子资源有缓存且缓存不过期,则直接加载该缓存; - 如果对应的子资源没有缓存,且子资源下载处于排队状态,抛给内核处理(Sonic仍会完成该资源的下载并进行缓存); - 如果对应的子资源没有缓存,且子资源正在下载,则将已下载的内存数据和未下载的网络流数据组成桥接流给内核; - 如果对应的子资源没有缓存,且子资源已下载完成,则将下载完成的子资源数据给内核。 ### 1.3 子资源缓存相关 子资源完成预下载之后会在本地进行缓存,缓存规则如下: 1. 子资源数据和子资源响应头数据会分别进行缓存,子资源url的MD5作为子资源数据缓存文件名,子资源url的MD5.header作为子资源响应头缓存的文件名。 2. 子资源和子资源响应头的缓存数据都保存在```/sdcard/SonicResource/```目录下; 2. 子资源缓存的过期过期时间由```sonic-link```头中子资源url参数```max-age```唯一决定; 3. 一旦本地子资源缓存被恶意篡改,被篡改过的子资源不会通过VasSonic校验,该缓存会被删除; 4. 默认每隔24小时进行一次缓存检查,如果超过大小限制(默认60M,可设置),会进行一次缓存清理。 使用如下方式进行缓存相关设置: ```java SonicConfig.Builder builder = new SonicConfig.Builder(); // 设置缓存校验方式为校验文件大小,默认为对文件内容进行Sha1校验 builder.setCacheVerifyWithSha1(false); // 设置子资源缓存最大为100M,默认为60M builder.setResourceCacheMaxSize(100 * 1024 * 1024); // 设置缓存大小检查时间间隔为12小时,默认为24小时 builder.setCacheCheckTimeInterval(12 * 60 * 60 * 1000L); builder.build(); ``` ================================================ FILE: assets/sonic发展历程.md ================================================ # VasSonic成长历程 ## 1.前言 2017年8月8日,腾讯SNG增值产品部技术团队(以下简称VAS)研发的轻量级高性能Hybrid框架VasSonic通过了公司最终审核,作为腾讯开源组件的一份子分享给大家。从当初立项优化页面加载速度,到不断摸索、优化,再到整理代码、文档,最终在Github上开源,并且在24小时内获取star数超过1600。我们非常高兴看到我们的成果收到这么多的关注,趁此机会,正好回顾一下VasSonic的成长历程,也希望能够让大家更了解VasSonic。 ## 2.项目背景 Web相信大家再熟悉不过了,它具有快速迭代发布的天然优势,但也存在一些让人诟病的问题,比如加载速度慢,体验差等。在此之前,手Q上很多页面首屏打开速度居高不下,甚至有些耗时达到3s以上,这意味着用户打开页面必须经过3秒之后才能进行交互操作,体验相当差,很多用户忍受不了这个漫长的时间直接流失掉了。 为了提升用户体验和业务用户留存率,我们很多业务一开始通过Web开发,等页面模型验证符合预期后,再将H5页面转化成原生界面。我们很快意识到这不是一种健康的可持续的开发模式,一方面存在重复人力浪费,另外一方面原生商城除了速度快一点,要运营活动改版都很难。 所以后来团队改了切入方向,安排人力专心研究如何加快页面打开速度。经过了一系列的摸爬滚打和优化探索,最终我们研发出了VasSonic框架,让H5页面首屏达到秒开,给用户一个更好的H5体验。期间也曾和空间技术团队共同合作将空间的首屏优化方案wns-html引入到手Q中(共同命名为webso方案)进行尝试,虽然在我们业务使用过程中存在部分场景体验较差,但webso中页面模板和数据分离等思路给VasSonic框架的发展提供了很好的帮助,在此特别感谢webso技术团队的贡献。下面就和大家分享VasSonic框架的发展历程。 ## 3.业务形态 任何一个技术框架都是结合具体的业务形态来进行发展优化的,技术是为了更好地服务业务,业务也会驱动技术的发展。因此在此首先介绍一下业务形态,我们是来自手Q增值产品部门的VAS团队,负责手机QQ上很多深受年轻人喜欢的个性化增值服务,比如气泡、挂件、主题等等。手Q上大部分的业务还是基于H5开发的,大家对手Q的业务形态可能有简单的了解。比如游戏分发中心、会员特权中心、个性化装扮商城等。这部分商城的特点比较明显,页面的很多数据都是动态的,是由我们的产品经理在后台配置的。 ![业务](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870447_pr_yewu.png) 这些都是很常见页面,我们通常将html/js/css等静态资源放到CDN上,然后页面加载后,再通过CGI去拉取最新的数据,进行拼接展示, 这样子可以利用到CDN的多地部署和就近接入等优势,同时提高了服务器的并发能力。这种传统模式的加载流程如下所示:
![加载流程](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870478_pr_jiazai.png) 1. 用户点击后,经过终端一系列初始化流程,比如进程启动、Runtime初始化、创建WebView等等。 2. 完成初始化后,WebView开始去CDN上面请求Html加载页面。 3. 页面发起CGI请求对应的数据或者通过localStorage获取数据,数据回来后再对DOM进行操作更新 可以看出上述流程存在着几个问题: ![问题](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870570_pr_question.png) 1. 从外网统计数据来看,用户的终端耗时在1s以上,这意味着在这1s多的时间里,网络完全是空闲在等待的,非常浪费; 2. 页面的资源和数据完全依赖于网络,特别是用户在弱网络场景下,页面会出现很长时间的白屏,体验非常差; 3. 因为页面的数据依赖于动态拉取,加载完页面后,往往是看到一些模块先转菊花,再展示,体验也是不好的。同时这里涉及到较多数据更新,经常要更新DOM,性能上也有不少开销。 所以针对以上几个问题,我们也对应做了很多优化和探索。 ## 4.VasSonic的前世 基于传统模式的加载流程存在的种种问题,我们做了以下优化: ### 4.1 终端优化 针对终端耗时1s以上的情况,我们对手Q WebView框架进行了重构: 1. 启动流程彻底拆分,设计为一个状态机按序按需执行 2. View相关拆分模块化设计,尽可能懒加载,IO异步化 3. X5内核在手Q中的独立进程中提前预加载 4. 创建WebView对象复用池 关于第四点,我们想分享一些Android平台上的细节,由于Android系统的生态原因,导致用户的系统版本和系统Webkit内核处于极其分裂状态,所以我们公司在手Q和微信统一使用X5内核。相对系统WebView来说,首次启动X5内核时,创建WebView比较耗时,因此我们尽量想复用WebView,但是WebView却是与Activity Context绑定。销毁复用的时候,需要释放Activity的Context,否则会内存泄露。针对这种情况,有没有一种两全其美的办法呢? 计算机有一句经典的名言:```计算机领域任何一个问题都可以通过引入中间层来解决```。于是我们通过包装的方式,实现了一个Context的壳,真正的实现体包装在里面,逻辑调用真正调用到对应的实现体的函数。 经过实验发现,Android系统本身提供了这么一个```MutableContextWrapper```,作为Context的一个中间层。 我们会将Activity context包在MutableContextWrapper里面,destory的时候,会将WebView的Context设置为Application的Context,从而释放Activity Context。 类似如下: ```Java //precreate WebView MutableContextWrapper contextWrapper = new MutableContextWrapper(BaseApplicationImpl.sApplication); mPool[0] = new WebView(contextWrapper); //reset WebView ct =(MutableContextWrapper)webview.getContext(); ct.setBaseContext(getApplication()); //reuse WebView ((MutableContextWrapper)webview.getContext()).setBaseContext(activityContext); ``` ### 4.2 静态直出 ![直出](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869605_pr_zhichu.png) “直出”这个概念对前端同学来说,并不陌生。为了优化首屏体验,大部分主流的页面都会在服务器端拉取首屏数据后通过NodeJs进行渲染,然后生成一个包含了首屏数据的Html文件,这样子展示首屏的时候,就可以解决内容转菊花的问题了。 当然这种页面“直出”的方式也会带来一个问题,服务器需要拉取首屏数据,意味着服务端处理耗时增加。 不过因为现在Html都会发布到CDN上,WebView直接从CDN上面获取,这块耗时没有对用户造成影响。 手Q里面有一套自动化的构建系统Vnues,当产品经理修改数据发布后,可以一键启动构建任务,Vnues系统就会自动同步最新的代码和数据,然后生成新的含首屏Html,并发布到CDN上面去。 ### 4.3 离线预推 ![带宽优化](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870585_pr_daikuan.png) 页面发布到CDN上面去后,那么WebView需要发起网络请求去拉取。当用户在弱网络或者网速比较差的环境下,这个加载时间会很长。于是我们通过离线预推的方式,把页面的资源提前拉取到本地,当用户加载资源的时候,相当于从本地加载,即使没有网络,也能展示首屏页面。这个也就是大家熟悉的离线包。 手Q使用7Z生成离线包, 同时离线包服务器将新的离线包跟业务对应的历史离线包进行BsDiff做二进制差分,生成增量包,进一步降低下载离线包时的带宽成本,下载所消耗的流量从一个完整的离线包(253KB)降低为一个增量包(3KB)。 经过一系列优化后,在Android平台上,点击到页面首屏展示的耗时从平均*3s*多降低为*1.8s*,优化*40% 以上*。 ![数据对比](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870598_pr_duibi.png) 所以针对以上几个问题,我们对应做了很多优化和探索,这些优化帮助我们形成VasSonic的最初构想。 ### 4.4 业务形态变化 虽然通过静态直出和离线预推等方式优化后,速度已经达到1.8s,但还存在很大的优化空间,当我们准备持续深入优化时,我们的业务形态发生了新的变化。 之前我们页面内容的数据主要是由产品经理要配置的,用户看到的内容基本都是一样的。而现在页面为了更好地为用户推荐喜欢的内容,我们后台引入机器学习和随机算法来做智能个性化推荐。比如左边新用户推荐的是新货精选,而右边活跃用户展示的是潮品推荐。另外还有部分的内容是随机算法推荐的。这意味着不同用户看到的内容是不同的,同一个用户不同时间看到的内容也有可能不同。 ![新业务](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869577_pr_xinyewu.png) ### 4.5 动态直出 所以为了满足业务的需求,我们只能实时拉取用户数据并在服务端渲染后返回给客户端,也就是动态直出的方案。 但是动态直出方案存在几个比较明显的问题: 1. 服务端实时拉取数据渲染导致白屏时间长,因为服务器要先实时拉取个人数据,然后进行渲染直出,这个耗时不可控; 2. 首屏无法使用离线预推等缓存策略,因为每个用户看到的内容不一样,我们无法通过静态直出的方式那样把Html全部发布到CDN; 虽然动态直出方案下,页面首屏无法通过离线预推等方式进行加载优化,但前面离线包优化积累的经验给我们提供了思路:要优化白屏问题,核心还是减少对网络的依赖,加速资源加载方向入手。所以,此时的技术挑战为:如何缓存动态直出页面和如何在缓存页面的基础上更新页面。(注:动态直出页面可能内部有用户实时数据,不更新页面会导致看到过时的数据导致投诉)。 ### 4.6 webso的尝试 在我们准备进一步优化的时候,了解到了QQ空间技术团队在动态直出方面做的一些实践尝试,他们提出了wns+html的解决方案:通过主动缓存首屏数据来获得加速,于是我们和QQ空间技术团队一起进行优化合作,将wns+html的解决方引入到手Q平台并命名为webso,其原理如图: ![image.png-103.9kB][1] 但我们使用过程中,发现页面在首次加载和模板变更场景加载耗时比较高,且在页面有内容变化的场景下需要重刷整个页面,对于变化频繁的页面体验较差,特别是在低端安卓机器上,白屏过程非常明显。于是我们分析背后的原因,发现主要有以下几个问题: 1、采用了sso+wns腾讯私有协议传输,虽然节省了服务器连接耗时,但需要经过跨进程、服务器中转、信令排队、加解密等步骤,导致传输效率变差(注:传输通道由之前的http->node.js变成了ipc->sso->wns->wns-proxy->node.js,同时也增加了额外的代理服务器和排查定位问题成本); 2、需要下载完整模板和数据并拼接html之后才能交给内核渲染,在内容没有完整下载之前,内核无法进行渲染,处于空闲等待状态,与内核边加载边渲染的特性冲突; 3、页面一旦发生内容变化(模板和数据),需要进行合并html重刷整个页面(或下次展示),无法进行局部刷新,仅更新变化的元素节点。 综上,webso方案更加适合变化较少的简单页面,无法满足我们业务变化频繁的场景(每次进入页面数据都有变化,我们的产品和用户都无法接受重刷页面的体验)。于是我们需要一个新的通用的解决方案,通过深入内核分析结合内核特性和不断的优化探索,最终提出了更轻量更高性能的解决方案:VasSonic。 ## 5. VasSonic的诞生 接下来详细介绍VasSonic的解决方案 ### 5.1 并行加载 首先在加载流程方面,我们发现这里WebView访问依然是串行的, WebView要等终端初始化完成之后,才发起请求。虽然终端耗时优化了不少,但是从外网的统计数据来看,终端初始化还是存在几百毫秒的耗时,而这段时间内网络是在空等的。 (注:在传输通道方面,我们选择了标准的http/https通道,原因是http/https通道支持流式传输,也支持chunk等特性,同时接入成本低,更加通用。) ![串行](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869445_pr_chuanxing.png) 因此性能上不够极致,我们优化代码,这两个操作并行处理,流程改为: ![并行](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869436_pr_bingxing.png) 并行处理后速度有所改善,但我们发现在某些场景下,终端初始化比较快,但数据没有完成返回,这意味着内核在空等,而内核是支持边加载边渲染的,我们在并行的同时,能否也利用内核的这个特性呢? 于是我们加入了一个中间层来桥接内核和数据,内部称为流式拦截: ![桥接流](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869522_pr_liushi.png) 1. 启动子线程请求页面主资源,子线程中不断讲网络数据读取到内存中,也就是网络流(NetStream)和内存流(MemStream)之间的转换; 2. 当WebView初始化完成的时候,提供一个中间层BridgeStream来连接WebView和数据流; 3. 当WebView读取数据的时候,中间层BridgeStream会先把内存的数据读取返回后,再继续读取网络的数据。 通过这种桥接流的方式,整个内核无需等待,继续做到边加载边解析。这种并行的方式让首屏的速度优化*15%以上*,进一步提升了页面加载速度。 ### 5.2 动态缓存 通过并行加载,我们极大地提升了WebView请求的速度,但是在弱网络场景下白屏时间还是非常长,用户体验非常糟糕。基于离线包和webso方案的优化实践经验,我们首先将用户的已经加载的页面内容缓存下来,等用户下此点击页面的时候,我们先加载展示页面缓存,第一时间让用户看到内容,然后同时去请求新的页面数据,等新的页面数据拉取下来之后,我们再重新加载一遍即可。 ![动态缓存](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870617_pr_huancun.png) 保存页面内容这个工作很简单,因为现在我们资源读取都是通过中间层BridgeStream来管理的,只需要将整个读取的内容缓存下来即可。 于是我们就按动态缓存这种方案去实现了,但很快就发现了问题。用户打开页面之后,先是看到历史页面,等用户准备去操作的时候,突然页面白闪一下,重新加载了一遍,这种体验非常差,特别在一些低端机器上,这个白闪的过程太明显,非常影响体验,这是用户和产品经理都不能接受的。于是我们在思考,能否只做局部的刷新,仅刷新变化的元素呢? 通过分析,我们发现同一个用户的页面,大部分数据都是不变的,经常变化的只有少量数据,于是我们提出了模板(template)和数据块(data)的概念:页面中经常变化的数据我们称为数据块,除了数据块之外的数据称为模板。 ### 5.3 页面分离 在页面分离这块,我们沿用了webso方案中的动静分离的思想,并扩展了部分新的字段。首先我们将整个页面html通过VasSonic标签进行划分,包裹在标签中的内容为data,标签外的内容为模版。 ![页面规范](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869473_pr_guifan.png) 首先我们对Html内容进行了扩展,通过代码注释的方式,增加了“sonicdiff-xxx”来标注一个数据块的开始与结束。 而模板就是将数据块抠掉之后的Html,然后通过{albums}来表示这个是一个数据块占位。 数据就是JSON格式,直接Key-Value。 当然,为了完美地兼容Html,我们对协议头部进行了扩展,比如增加accept-diff来标注是否支持增量更新、template-tag来标注模板的md5是多少等。OK,有了上面这个规则或者公式后,我们就可以实现增量更新了。 ### 5.4 请求规范约定 VasSonic为了支持区分客户端是否支持增量更新等能力,对头部字段进行了扩展 字段 | 说明 | 请求头(Y/N) | 响应头(Y/N) :-------------------------:|:-------------------------:|:-------------------------:|:-------------------------: accept-diff | 表示终端是否支持VasSonic模式,true为支持,否则不支持 | Y | N If-none-match | 本地缓存的etag,给服务端判断是否命中304 | Y | N etag | 页面内容的唯一标识(哈希值) | N | Y template-tag | 模版唯一标识(哈希值),客户端使用本地校验 或 服务端使用判断是模板有变更 | Y | Y template-change | 标记模版是否变更,客户端使用 | N | Y cache-offline | 客户端端使用,根据不同类型进行不同行为 | N |Y ### 5.5 cache-offline字段说明 字段 | 说明 :-------------------------:|:-------------------------: true | 缓存到磁盘并展示返回内容 false | 展示返回内容,无需缓存到磁盘 store | 缓存到磁盘,如果已经加载缓存,则下次加载,否则展示返回内容 http | 容灾字段,如果http表示终端六个小时之内不会采用sonic请求该URL ### 5.6 模式介绍 VasSonic根据本地是否有缓存以及本地缓存数据跟服务器数据的差异情况分为以下四种模式。 模式 | 说明 | 条件 :-------------------------:|:-------------------------:|:-------------------------: **首次加载** | 本地没有缓存,即第一次加载页面 | etag为空值或template_tag为空值 **完全缓存** | 本地有缓存,且缓存内容跟服务器内容完全一样 | etag一致 **数据更新** | 本地有缓存,本地模版内容跟服务器模版内容一样,但数据块有变化 | etag不一致 且 template_tag一致 **模版更新** | 本地有缓存,缓存的模版内容跟服务器的模版内容不一样 | etag不一致 且 template_tag不一致 #### 首次加载 我们会在请求头部带上支持accept-diff为true和sdk版本号等标识着首次加载的信息。当请求返回后,VasSonic会在延迟几秒后(避免激烈IO竞争)将页面抽离成模板和数据并保存到本地。此时终端缓存目录下,该页面将对应三个缓存文件xxx.html、xxx.template、xxx.data,其中xxx是该页面的唯一标识(即sonicSessionId)。 对于页面非首次加载场景,VasSonic优先加载本地缓存, 同时我们会在请求头部带上当前缓存和模板的md5,后台进行模板md5对比之后,分为以下几种情况: #### 非首次加载之完全缓存 本地有缓存,且缓存内容跟服务器内容完全一样. #### 非首次加载之增量数据 ![增量数据](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870643_pr_zengliang.png) 如果模板发现没有变化,那么会在响应头部返回template-change=false,同时响应包体返回的数据不再是完整的html,而是一段JSON数据,及全部的数据块。我们现在需要跟本地数据进行差分,找出真正的增量数据,如上图中,后台返回了N个数据,实际上仅有一个数据是有变化的,那么我们仅需要将这个变化的数据提交到页面即可。一般场景下,这个差异的数据比全部数据要小很多。如果页面拆分数据得更细,那么页面的变动就更小,这个取决于前端同学对数据块的细化程度。 获得变化数据块(diff_data)后,客户端只需要通知页面页面设置的回调接口(getDiffDataCallback)进行界面元素更新即可。这里javascript的通信方式也可以自由定义(可以使用webview标准的javascript通信方式,也可以使用伪协议的方式),只要页面跟终端协商一致就可以。 ![提交增量](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870607_pr_hebing.png) 对于数据更新这种场景,终端还会将新的数据和模板拼接成为新的页面,保持缓存最新。当终端初始化比较慢的时候,WebView去加载缓存的时候,这个页面可能已经是最新的了,连数据刷新都不需要。 #### 非首次加载之模板更新 与数据更新模式不一样,由于业务需求,页面的模板会发生更改。当终端在获取到新的模板和数据后,本地在子线程中进行合并,生成一个新的缓存,然后回调通知终端,刷新WebView来加载新的缓存。 我们来看一下最终的流程图,跟动态缓存对比,有不少细节优化: ![整体流程](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870626_pr_liucheng.png) 我们从第2步开始,SonicSession首先会去读取缓存。会抛个消息通知WebView读取缓存,如果Webview已经准备好,则直接加载缓存,如果没有,则缓存先放在内存里面。同时SonicSession也会带上模板等信息到后台拉取新的内容,后台经过Sonic-Diff之后,会返回新的数据。SonicSession拿到新的数据后,首先会跟本地数据进行Diff,如果发现WebView已经加载缓存,则直接提交增量数据给页面。否则继续拼接最新的页面,替换掉内存里面的缓存,同时保存到本地。这个时候WebView如果Ready,则直接进行第5步load最新的内容即可。 #### 效果统计 ![效果统计](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869563_pr_xiaoguo.png) 这个是我们外网的统计数据。在数据更新模式下,首屏的耗时在1s左右,相比普通的动态直出,优化了50%以上。模板更新这个会比首次高,是因为加载了两次页面,不过从模式占比上来看,我们大部分页面都是数据更新。针对模板更新这种耗时比较高的情况,前面优化积累的经验给我们提供了思路,核心还是从提前获取资源方向入手,因此我们优先考虑如何预加载模板更新。 #### 预加载 实际上整个SonicSession在没有WebView的情况下,也是可以独立完成所有逻辑的,当用户点击页面的时候,我们在将WebView和SonicSession绑定起来即可。于是我们支持了两种预加载的模式,一种是通过后台push的方式,来提前获取数据。还有一种就是JSAPI,页面可以调用JSAPI来预加载用户可能操作的下一个页面。通过这两种方式,我们可以把需要的增量更新数据提前拉取回来 ![预加载](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870634_pr_preload.png) ## 6. 效果对比 Pic 1: 没有使用VasSonic | Pic 2: 使用VasSonic :-------------------------:|:-------------------------: ![default mode](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869428_default.gif) | ![VasSonic mode](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869614_vassonic.gif) ## 7. 展望未来 开源只是故事的开始,我们仍会持续对 VasSonic 做改进,包括更易用的接口、更好的性能、更高的可靠性,同时快速响应解决开源后的issue和PR。这些改进最终也会原封不动地在手Q内使用,这一切都是为了更快的WebView加载速度。
Talk is cheap,read the fucking code. If you are interested in VasSonic, don't forget to STAR [VasSonic](https://github.com/Tencent/VasSonic). Thank you for reading ~ ## 8. 特别感谢 最后再次感谢qq空间技术团队的贡献及webso技术带来的启发,感谢infoQ,腾讯开源,bugly等媒体团队对vasSonic的开源支持。 [1]: http://static.zybuluo.com/feilang/7l6ptf1cl5k3qxl0o55a4cxq/image.png ================================================ FILE: checkstyle.xml ================================================ ================================================ FILE: sonic-android/.gitignore ================================================ .gradle /build # Ignore Gradle GUI config gradle-app.setting # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar # Cache of project .gradletasknamecache .DS_Store node_modules # Built application files *.apk *.ap_ # Java class files *.class # Generated files bin/ gen/ # Gradle files .gradle/ *.iml /*/*.iml .idea /*/.idea/ # Local configuration file (sdk path, etc) local.properties gradle.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log /*/.idea /buildSdk ================================================ FILE: sonic-android/README.md ================================================ ## Getting started with Android [![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki) --- ## Dependencies: Add VasSonic gradle plugin as a dependency in your module's build.gradle ```gradle compile 'com.tencent.sonic:sdk:3.1.0' ``` ## Implement sonic interface: 1. Implement a class which extends from ```SonicRuntime``` > SonicRuntime is a class which interacts with the overall running information in the system, including Context, UA, ID (which is the unique identification for the saved data) and other information. ```Java /** * Here is a sample subclass of SonicRuntime */ public class HostSonicRuntime extends SonicRuntime { public HostSonicRuntime(Context context) { super(context); } /** * @return User's UA */ @Override public String getUserAgent() { return ""; } /** * @return the ID of user. */ @Override public String getCurrentUserAccount() { return ""; } /** * @return the file path which is used to save Sonic caches. */ @Override public File getSonicCacheDir() { String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sonic/"; File file = new File(path.trim()); if(!file.exists()){ file.mkdir(); } return file; } } ``` 2. Implement a subclass which extends from ```SonicSessionClient``` ```Java /** * * SonicSessionClient is a thin API class that delegates its public API to a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl. */ public class SonicSessionClientImpl extends SonicSessionClient { private WebView webView; public void bindWebView(WebView webView) { this.webView = webView; } @Override public void loadUrl(String url, Bundle extraData) { webView.loadUrl(url); } @Override public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) { webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); } } ``` ## Android Demo Here is a simple demo shows how to create an Android activity which uses the VasSonic Framework ```Java public class BrowserActivity extends Activity { public final static String PARAM_URL = "param_url"; public final static String PARAM_MODE = "param_mode"; private SonicSession sonicSession; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); String url = intent.getStringExtra(PARAM_URL); int mode = intent.getIntExtra(PARAM_MODE, -1); if (TextUtils.isEmpty(url) || -1 == mode) { finish(); return; } getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); // step 1: Initialize sonic engine if necessary, or maybe u can do this when application created if (!SonicEngine.isGetInstanceAllowed()) { SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build()); } SonicSessionClientImpl sonicSessionClient = null; // step 2: Create SonicSession sonicSession = SonicEngine.getInstance().createSession(url, new SonicSessionConfig.Builder().build()); if (null != sonicSession) { sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl()); } else { // this only happen when a same sonic session is already running, // u can comment following codes to feedback as a default mode. throw new UnknownError("create session fail!"); } // step 3: BindWebView for sessionClient and bindClient for SonicSession // in the real world, the init flow may cost a long time as startup // runtime、init configs.... setContentView(R.layout.activity_browser); WebView webView = (WebView) findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (sonicSession != null) { sonicSession.getSessionClient().pageFinish(url); } } @TargetApi(21) @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return shouldInterceptRequest(view, request.getUrl().toString()); } @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (sonicSession != null) { //step 6: Call sessionClient.requestResource when host allow the application // to return the local data . return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url); } return null; } }); WebSettings webSettings = webView.getSettings(); // step 4: bind javascript // note:if api level lower than 17(android 4.2), addJavascriptInterface has security // issue, please use x5 or see https://developer.android.com/reference/android/webkit/ // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String) webSettings.setJavaScriptEnabled(true); webView.removeJavascriptInterface("searchBoxJavaBridge_"); intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis()); webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic"); // init webview settings webSettings.setAllowContentAccess(true); webSettings.setDatabaseEnabled(true); webSettings.setDomStorageEnabled(true); webSettings.setAppCacheEnabled(true); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true);        // step 5: webview is ready now, just tell session client to bind if (sonicSessionClient != null) { sonicSessionClient.bindWebView(webView); sonicSessionClient.clientReady(); } else { // default mode webView.loadUrl(url); } } @Override public void onBackPressed() { super.onBackPressed(); } @Override protected void onDestroy() { if (null != sonicSession) { sonicSession.destroy(); sonicSession = null; } super.onDestroy(); } ``` ## Support Any problem? 1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sample). 4. Contact us for help. ## License VasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details. [1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif [2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif ================================================ FILE: sonic-android/build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.0' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: sonic-android/docs/Sonic Quick模式实现原理.md ================================================ # Sonic Quick模式实现原理 --- 根据本地是否有缓存数据可以将Quick模式下的sonic分为无缓存和有缓存模式。对于有缓存模式又可以分为完全缓存、局部刷新和全局刷新(也就是模版变更),下面就看下这几种模式的执行流程。 无论是哪种执行模式,核心的思想都是并行,即充分利用webview初始化的时间进行一些数据的处理(webview的初始化耗时还是挺多的)。在包含webview的activity启动时会一边进行webview的初始化逻辑,一边并行的执行sonic的逻辑。 ## 一,无缓存模式 无缓存模式下的核心思想就是在webview初始化之前建立自己的网络连接,利用webview初始化的时间尽可能多的读取网络的数据,在webview需要数据的时候将自己从网络读取的数据交给webview处理。 代码的主要执行流程 这里主要有两条并行线,左边是webview的执行流程,右边是sonic的执行流程。Webview的执行流程比较简单,主要是进行webview的初始化,以及在初始化完之后调用SonicSession(这里的SonicSession对象是activity onCreate的时候通过SonicEngine创建的)的onClientReady方法,告知其webview已经init完毕。剩下的事情交给sonic那边处理。 右边这条sonic的执行流程线相对会复杂一些,首先,在activity create之后通过SonicEngine创建SonicSession对象。接着调用SonicCacheInterceptor来获取本地缓存的url对应的数据。由于是首次加载即本地无缓存数据,所以这里的数据是为空的。获取的数据为空之后会post一个CLIENT_CORE_MSG_PRE_LOAD(arg1 = PRE_LOAD_NO_CACHE )的消息到主线程中,同时继续执行下面的逻辑。主线程的逻辑后面统一分析,这里先分析sonic所在子线程中的逻辑。 Sonic在post消息到主线程之后会通过SonicSessionConnection建立一个URLConnection,接着通过这个连接获取服务器返回的数据。由于获取网络数据是个耗时的过程,所以在读取网络数据的过程中会不断的判断webView是否发起资源拦截请求(通过SonicSession的wasInterceptInvoked来判断),如果webview已经发起资源拦截请求,就中断网络数据的读取,将已经读取的数据和未读取的网络数据拼接成桥接流SonicSessionStream,并将其赋值给SonicSession的pendingWebResourceStream。如果整个网络数据读取完毕之后webview还没有初始化完,那么就会把之前post的CLIENT_CORE_MSG_PRE_LOAD的消息cancel调。同时post一个CLIENT_CORE_MSG_FIRST_LOAD的消息到主线程。之后再对html内容进行模版分割及数据保存。 接下来看看主线程的执行逻辑。之前说过sonic在本地无缓存的时候会先post一个CLIENT_CORE_MSG_PRE_LOAD的消息到主线程,如果主线程有执行到这个消息的话(之前也介绍过这个消息有可能被cancel掉)就会调用webview的loadUrl,发起真正的网络请求,之后webview会调用本身的资源拦截方法,在这个方法中sonic会将之前保存的pendingWebResourceStream返回给webview,有了这个pendingWebResourceStream之后webview就可以进行解析渲染逻辑了。同时webview在展示完页面之后会调SonicSessionStream的onClose方法进行关闭数据流,在这个onClose中我们会进行html内容的数据分割以及数据保存操作。 如果主线程处理的是CLIENT_CORE_MSG_FIRST_LOAD消息,则会先判断webview之前是否有发生过loadUrl(通过wasLoadUrlInvoked来判断),如果没有,调用webview的loadDataWithBaseUrl方法去加载之前读取的网络数据,这样webview就可以根据这个数据直接做解析渲染的逻辑了;如果有就不做任何的逻辑处理了。 以上就是在quick模式下sonic首次的基本逻辑。这里有个问题要注意,就是主线程在处理sonic post的消息之前都会判断webview是否ready(初始化完毕),只有webview ready的情况才会执行对应的操作。如果webview没有ready的话就会把对应的消息存起来,直到webview ready的时候再执行对应的逻辑。 ## 二,有缓存模式 有缓存模式的核心思想也是在webview初始化之前先读取本地的数据,同时建立自己的网络连接,通过网络连接获取服务器最新的数据。在webview需要数据的时候将本地或服务器返回的新的数据交给webview处理。 有缓存模式又可以分为完全缓存、局部刷新、模板变更。下面依次介绍这几种模式。 ###1,完全缓存: 所谓完全缓存就是本地的数据跟服务器的数据是完全一样的。 代码的主要执行流程: 左边webview的执行跟无缓存模式下没什么区别,右边sonic执行流程中前两步跟首次的逻辑一样,在完全缓存模式下通过SonicCacheInterceptor获取的url对应的本地数据是不为空的,这时候会post一个CLIENT_CORE_MSG_PRE_LOAD(arg1 = PRE_LOAD_WITH_CACHE)的消息到主线程中,同时服务器返回304,sonic流程就走完了。主线程在收到CLIENT_CORE_MSG_PRE_LOAD消息时通过loadDataWithBaseUrl加载本地数据给webview渲染。 ###2,局部刷新: 局部刷新就是本地的数据跟服务器的数据相比,只有data部分有变化,模板跟服务器一样。 代码的主要执行流程: 左边webview的执行跟无缓存模式下没什么区别,右边sonic执行流程中前两步跟首次的逻辑一样,在局部刷新模式下通过SonicCacheInterceptor获取的url对应的本地数据是不为空的,这时候会post一个CLIENT_CORE_MSG_PRE_LOAD(arg1 = PRE_LOAD_WITH_CACHE)的消息到主线程中(主线程的执行逻辑后面再分析)。接着通过SonicSessionConnection获取服务器返回的数据,在这种模式下服务器返回的内容就是html的data部分。拿到data之后跟本地保存的data做diff,得到页面需要刷新的diffData。再post一个CLIENT_CORE_MSG_DATA_UPDATE的消息到主线程中,接着将服务器返回的data跟本地保存的模版进行合并,生成最新的html内容。之后将CLIENT_CORE_MSG_PRE_LOAD的消息移除(如果这个消息没有被执行的话)。最后将新合并的数据,以及服务器返回的data保存在本地。 下面看下主线程的执行逻辑。 之前说过在数据刷新模式下会post一个CLIENT_CORE_MSG_PRE_LOAD的消息到主线程,主线程如果有执行到这个消息(因为有可能被remove掉)的话就会调用webview的loadDataWithBaseUrl将本地的数据交给内核渲染,同时将本地变量wasLoadDataInvoked置为true。 当主线程接收到CLIENT_CORE_MSG_DATA_UPDATE的消息时会先判断wasLoadDataInvoked是否为true,即判断webview之前是否有掉过loadDataWithBaseUrl方法,如果有的话就会调用SonicSessionClient的callJacaScript方法将diffData给到页面,从而刷新页面如果wasLoadDataInvoked为false的话就调loadDataWithBaseUrl把最新的数据(服务器返回的数据跟本地模版合成的数据)给到webview去渲染。 ### 3,模版变更 模板变更是本地的数据跟服务器数据相比,本地的模板跟服务器的模板不一样。 代码执行流程: 同样,左边webview的执行跟之前的模式相比也没什么区别。右边sonic流程的前面几步跟数据更新时候的逻辑是一样的。模版更新模式跟数据更新模式的不同点在于模版更新的时候服务器返回的是完整的html数据内容,sonic这边会先把html的内容读到内存中。由于读取网络数据耗时比较长,为了可以让页面更快的刷新,在读取网络数据的时候会不断判断之前load的本地缓存的数据的页面有没有finish(通过SonicSession的wasOnPageFinishInvoked来判断,这个值会在SonicSessionClient在webview onpagefinish的时候设置),如果wasOnPageFinishInvoked为true就不再读取网络数据了,而是将已读的数据和未读的数据组成桥接流SonicSessionStream,接着post CLIENT_CORE_MSG_TEMPLATE_CHANGE(msg.obj == null)的消息到主线程;如果整个网络数据读完wasOnPageFinishInvoked还是为false的话,就将已读的网络数据拼接成输入流。然后将CLIENT_CORE_MSG_PRE_LOAD的消息移除(如果这个消息没有被执行的话),post CLIENT_CORE_MSG_TEMPLATE_CHANGE(msg.obj == new html)的消息到主线程中,最后进行模版的分割以及数据的保存等操作。 跟前面一样,接下来分析下主线程的执行逻辑。 主线程执行逻辑比较简单,如果是CLIENT_CORE_MSG_PRE_LOAD消息的话就通过loadDataWithBaseUrl加载本地的数据,如果是CLIENT_CORE_MSG_TEMPLATE_CHANGE消息先判断msg.obj是否为空,如果为空发起loadUrl重新加载数据,同时在资源拦截的时候将本地建立的桥接流交给内核渲染。等待内核渲染完毕之后进行模版分割和模版拆分等操作。如果不为空就通过loadDataWithBaseUrl加载最新的数据。 这里解释下为什么在模版更新的时候需要判读之前load的本地页面是否有pagefinish。假设本地的页面已经展示完了,而sonic这边还在读取网络的数据,如果没有这个逻辑的话就会等sonic这边读完网络数据之后才能刷新页面;而有了这个逻辑之后就可以在pageFinish的时候直接发起loadUrl,利用webview边下载边解析的功能减少内核的等待时间,从而减少整个页面刷新的耗时。 以上就是sonic在Quick模式下的的大概流程 ================================================ FILE: sonic-android/docs/Sonic Standard模式实现原理.md ================================================ # Sonic Standard模式实现原理 --- 从前面介绍的sonic的基本原理可以知道,sonic分为Quick模式和Standard模式。本文介绍Standard模式的基本实现原理。 根据本地缓存的数据情况可以将Quick模式下的sonic分为无缓存和有缓存模式。对于有缓存模式又可以分为完全缓存、局部刷新和全局刷新(也就是模版变更),下面就看下这几种模式的执行流程。 无论是哪种执行模式,核心的思想都是并行,即充分利用webview初始化的时间进行一些数据的处理(webview的初始化耗时还是挺多的)。在包含webview的activity启动时会一边进行webview的初始化逻辑,一边并行的执行sonic的逻辑。 ## 一,无缓存模式 无缓存模式下的核心思想就是在webview初始化之前建立自己的网络连接,利用webview初始化的时间尽可能多的读取网络的数据,在webview需要数据的时候将自己从网络读取的数据交给webview处理。 代码执行流程为: 这里主要有两条并行线,左边是webview的执行流程,右边是sonic的执行流程。Webview的执行流程比较简单,主要是进行webview的初始话,以及在初始化完之后调用SonicSession(这里的SonicSession对象是activity onCreate的时候通过SonicEngine创建的)的onClientReady方法,告知其webview已经init完毕,之后就开始调webview的laodUrl方法,等待webview资源拦截的回调。剩下的事情交给sonic那边处理。 右边表示sonic的执行流程。首先调用SonicEngine.createSession创建SonicSession对象,接着调用SonicCacheIterceptor的getSonicCache方法来获取要加载的url对应的本地数据,由于是首次加载,所以这里的cache数据是为空的。之后会通过SonicSessionConnection建立一个URLConnection,接着通过这个连接获取服务器返回的数据。由于获取网络数据是个耗时的过程,所以在读取网络数据的过程中会不断判断webView是否发起资源拦截请求(通过SonicSession的wasInterceptInvoked来判断),如果webview已经发起资源拦截请求,就中断网络数据的读取,将已经读取的数据和未读取的网络数据拼接成桥接流SonicSessionStream,并将其赋值给SonicSession的pendingWebResourceStream。 因此在webview发起资源拦截时pendingWebResourceStream存在两种可能,一种时网络数据还没完全读完的桥接流,另一种是网络数据已经完全读完的数据流。如果是桥接流的话在webview渲染完成关闭桥接流的时候会进行模版分割,数据保存等操作。如果是已读完的数据流的话就会在将pendingWebResourceStream数据给内核之后继续在子线程中执行模版分割,数据保存等操作。 ## 二,有缓存模式: 有缓存模式的核心思想也是在webview初始化之前先读取本地的数据,同时建立自己的网络连接,通过网络连接获取服务器最新的数据。在webview需要数据的时候将本地或服务器返回的新的数据交给webview处理。 有缓存模式又可以分为完全缓存、局部刷新、模板变更。下面依次介绍这几种模式。 ### 1,完全缓存: 所谓完全缓存就是本地的数据跟服务器的数据是完全一样的。 代码执行流程为 左边webview的执行逻辑跟首次基本一致。右边sonic的执行逻辑前面几步跟首次的逻辑也基本一致,不同的地方开始于通过SonicCacheInterceptor获取的本地cacahe数据是不为空的,会将本地的数据包装为一个InputStream,在webview发起资源拦截的时候将这个InputStream交给内核渲染。同时通过SonicSessionConnection向服务器请求最新数据,由于服务器返回304,没有数据更新,整个sonic的流程执行完毕。 ### 2,局部刷新: 局部刷新就是本地的数据跟服务器的数据相比,只有data部分有变化,模板跟服务器一样。 代码执行流程为: 左边webview的流程跟前面介绍的基本一样,不一样的地方后面会讲。右边sonic的逻辑前面几步跟完全缓存的时候一样,会先讲本地的数据包装成一个InputStream赋值给SonicSession 的pendingWebResourceStream,接着通过SonicSessionConnection获取服务器的回包数据。这种模式下服务器的回包数据是html的data部分的内容。将这个data跟本地的data做diff,就会得到页面刷新需要的diffData,有了这个diffData之后会将它保存在SonicSession的pendingDiffData变量中。接着通过SonicUtils的buildHtml将服务器返回的data跟本地的模版数据拼接成新的html内容。有了新的html内容之后判断webview的资源拦截是否有发起(通过SonicSession的wasInterceptInvoked来判断),如果有发起的话就将新的html内容保存在本地,然后流程执行完毕。如果这是webview还没有发起资源拦截的话就会将pendingDiffData置空,同时将新的html包装成一个InputStream赋值给pendingWebResourceStream,然后执行最后的数据保存等操作。 通过上面的介绍可以知道在数据更新模式下,webview发起资源拦截的时候有可能得到两种值,一种是之前本地数据组成的输入流,在这种情况下页面调用js获取diffData的时候会将保存的diffData给到页面,让页面执行刷新操作;另一种是由服务器返回的data跟本地模版组成的最新的html包装成的输入流,这种情况下页面展示的就是最新的数据,在获取diffData的时候就不会有返回值了。 ### 3,模版变更 模板变更是本地的数据跟服务器数据相比,本地的模板跟服务器的模板不一样。 代码执行流程为: 左边webview的逻辑跟首次差不多,不一样的地方后面再讲。右边sonic的逻辑前面几个跟数据更新基本一致,不一样的地方开始于服务器的回包数据不同。在模版更新模式下服务器会返回最新的完整的html内容,由于读取网络数据耗时比较长,为了可以让页面更快的刷新,在读取网络数据的时候会不断判断之前load的本地缓存的数据的页面有没有finish(通过SonicSession的wasOnPageFinishInvoked来判断,这个值会在SonicSessionClient在webview onpagefinish的时候设置),如果wasOnPageFinishInvoked为true就不再读取网络数据了,而是将已读的数据和未读的数据组成桥接流SonicSessionStream,然后在主线程中发起loadUrl。同时在webview资源拦截的时候将刚才建立的桥接流交给内核渲染。 如果整个网络数据读取过程wasOnPageFinishInvoked都没有被设置为true的话sonic就会将读取完的最新的数据包装成一个输入流放在pendingWebResourceStream里。接下来判断wevbiew是否有发起资源拦截。如果没有的话就执行最后的保存数据操作,因为这时已经将pendingWebResourceStream更新为最新的数据了,当webview发起资源拦截的时候sonic给到内核的就是最新的数据了;如果此时webview的资源拦截已经发起了,就是说webview已经加载过之前本地的数据了,那么这时候sonic会主动再调一次webview的loadUrl方法进行刷新页面,等到webview第二次发起资源拦截请求的时候再把最新的数据给到内核去渲染,这种情况sonic在发起webview的loadUrl之后就会继续在子线程执行文件保存等收尾的工作。 这里解释下为什么在模版更新的时候需要判读之前load的本地页面是否有pagefinish。假设本地的页面已经展示完了,而sonic这边还在读取网络的数据,如果没有这个逻辑的话就会等sonic这边读完网络数据之后才能刷新页面;而有了这个逻辑之后就可以在pageFinish的时候直接发起loadUrl,利用webview边下载边解析的功能减少内核的等待时间,从而减少整个页面刷新的耗时。 以上就是sonic在Standard模式下的的大概流程 ================================================ FILE: sonic-android/docs/Sonic接入指引.md ================================================ # 终端接入指引-Android版本 ---- ## 1.Sdk引入配置 在模块的build.gradle文件里面加入 ``` compile 'com.tencent.sonic:sdk:3.0.0-alpha' ``` ## 2.代码接入 ### (1).创建一个类继承SonicRuntime SonicRuntime类主要提供sonic运行时环境,包括Context、用户UA、ID(用户唯一标识,存放数据时唯一标识对应用户)等等信息。以下代码展示了SonicRuntime的几个方法。 ```java public class HostSonicRuntime extends SonicRuntime { public HostSonicRuntime(Context context) { super(context); } /** * 获取用户UA信息 * @return */ @Override public String getUserAgent() { return ""; } /** * 获取用户ID信息 * @return */ @Override public String getCurrentUserAccount() { return ""; } /** * 创建sonic文件存放的路径 * @return */ @Override public File getSonicCacheDir() { String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sonic/"; File file = new File(path.trim()); if(!file.exists()){ file.mkdir(); } return file; } } ``` ### (2).创建一个类继承SonicSessionClient SonicSessionClient主要负责跟webView的通信,比如调用webView的loadUrl、loadDataWithBaseUrl等方法。 ```java public class SonicSessionClientImpl extends SonicSessionClient { private WebView webView; public void bindWebView(WebView webView) { this.webView = webView; } /** * 调用webView的loadUrl */ @Override public void loadUrl(String url, Bundle extraData) { webView.loadUrl(url); } /** * 调用webView的loadDataWithBaseUrl方法 */ @Override public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) { webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); } } ``` ### (3).新建包含webView的Activity(或者Fragment等),在activity中完成sonic的接入。这里通过简单的demo展示如何接入 ```java public class SonicTestActivity extends Activity { public final static String PARAM_URL = "param_url"; public final static String PARAM_MODE = "param_mode"; private SonicSession sonicSession; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); String url = intent.getStringExtra(PARAM_URL); getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); // init sonic engine if necessary, or maybe u can do this when application created if (!SonicEngine.isGetInstanceAllowed()) { SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build()); } SonicSessionClientImpl sonicSessionClient = null; // if it's sonic mode , startup sonic session at first time SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); // create sonic session and run sonic flow sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build()); if (null != sonicSession) { sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl()); } else { // this only happen when a same sonic session is already running, // u can comment following code to feedback for default mode to throw new UnknownError("create session fail!"); } // start init flow ... in the real world, the init flow may cost a long time as startup // runtime、init configs.... setContentView(R.layout.activity_browser); // init webview WebView webView = (WebView) findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (sonicSession != null) { sonicSession.getSessionClient().pageFinish(url); } } @TargetApi(21) @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return shouldInterceptRequest(view, request.getUrl().toString()); } @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (sonicSession != null) { return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url); } return null; } }); WebSettings webSettings = webView.getSettings(); // add java script interface // note:if api level if lower than 17(android 4.2), addJavascriptInterface has security // issue, please use x5 or see https://developer.android.com/reference/android/webkit/ // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String) webSettings.setJavaScriptEnabled(true); webView.removeJavascriptInterface("searchBoxJavaBridge_"); intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis()); webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic"); // init webview settings webSettings.setAllowContentAccess(true); webSettings.setDatabaseEnabled(true); webSettings.setDomStorageEnabled(true); webSettings.setAppCacheEnabled(true); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); // webview is ready now, just tell session client to bind if (sonicSessionClient != null) { sonicSessionClient.bindWebView(webView); sonicSessionClient.clientReady(); } else { // default mode webView.loadUrl(url); } } @Override public void onBackPressed() { super.onBackPressed(); } @Override protected void onDestroy() { if (null != sonicSession) { sonicSession.destroy(); sonicSession = null; } super.onDestroy(); } } ``` SonicTestActivity是一个含有webView的demo代码,里面展示了sonic的整体流程。主要分为6个步骤: **Step1**:在activity onCreate的时候创建SonicRuntime并且初始化SonicEngine。为sonic初始化运行时需要的环境 ```java if (!SonicEngine.isGetInstanceAllowed()) { SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build()); } ``` **Setp2**:通过SonicEngine.getInstance().createSession来为要加载的url创建一个SonicSession对象,同时为session绑定client。session创建之后sonic就会异步加载数据了。 ```java SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); // create sonic session and run sonic flow sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build()); if (null != sonicSession) { sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl()); } ``` **Step3**:设置javascript,这个主要是设置页面跟终端的js交互方式。 按照sonic的规范,webView打开页面之后页面会通过js来获取sonic提供的一些数据(比如页面需要刷新的数据)。Demo里使用的是标准的js交互代码,第三方可以替换为自己的js交互实现方式(比如提供jsbridge伪协议等)。 ```java webSettings.setJavaScriptEnabled(true); webView.removeJavascriptInterface("searchBoxJavaBridge_"); webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic"); ``` **Step4**:为clinet绑定webview,在webView准备发起loadUrl的时候通过SonicSession的onClientReady方法通知sonicSession: webView ready可以开始loadUrl了。这时sonic内部就会根据本地的数据情况执行webView相应的逻辑(执行loadUrl或者loadData等)。 ```java if (sonicSessionClient != null) { sonicSessionClient.bindWebView(webView); sonicSessionClient.clientReady(); } ``` **Step5**:在webView资源拦截的回调中调用session.onClientRequestResource(url)。通过这个方法向sonic获取url对应的WebResourceResponse数据。这样内核就可以根据这个返回的response的内容进行渲染了。(如果sonic在webView ready的时候执行的是loadData的话,是不会走到资源拦截这里的) ```java public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (sonicSession != null) { return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url); } return null; } ``` ================================================ FILE: sonic-android/docs/Sonic框架介绍.md ================================================ # Sonic框架介绍 --- 本文主要介绍sonic的整个框架设置,包括这个框架的类图结构以及各个类的主要职责介绍。 sonicSdk类图结构: sonic类职责说明: SonicSession:负责sonic的核心逻辑:包括缓存数据的获取,服务器回包数据的处理,页面展示数据的生成以及数据模版的拆分、拼接等。 QuickSonicSession:SonicSession的子类,这种类型的session会使用webview的loadData方式来加载页面。这种方式加载速度比较快,但是由于不能带header(例如csp等),可能会有一些安全问题。 StandardSonicSession:SonicSession的子类,这种类型的session只是通过loadUrl,并且在资源拦截的时候返回数据。这种类型相比于QuickSonicSession速度上可能会慢一些(因为资源拦截需要内核底层派发,再到终端进行拦截)。但是这种方式支持在数据返回的时候添加header,所以不存在安全问题。 SonicEngine:sonic引擎初始化,主要初始化sonic运行需要的runtime和context等信息。 SonicRuntime:提供sonic运行环境需要的一些数据,比如context,文件的保存路径,页面的cookie等信息。 SonicSessionClient:提供sonic与webview交互需要的功能,例如loadUrl,loadDataWithBaseUrl等 SonicCacheInterceptor:sonic缓存数据的提供者,第三方可以提供自定义的缓存内容,也可以使用sonic默认提供的缓存数据。 SonicSessionConnection:sonic底层连接的提供者,通过SonicSessionConnection去获取服务器的回包数据。 SonicSessionStream:为sonic提供数据流,SonicSessionStream会将已读取的网络数据和未读取的网络数据组合成一个桥接流,将这个桥接的数据提供给webview内核进行渲染。利用webview流式加载功能减少耗时。 SonicUtils:sonic工具类,主要负责sonic数据的模版分割,数据重组,diffdata计算等 SonicFileUtils:sonic文件操作工具类,主要负责文件的读写 SonicDataHelper:sonic数据帮助类,主要负责管理sonic除去文件内容之外的其它数据,比如html的md5值,模版的tag等等。 ================================================ FILE: sonic-android/docs/javadoc/allclasses-frame.html ================================================ 所有类 (sdk 3.0.0 API)

所有类

================================================ FILE: sonic-android/docs/javadoc/allclasses-noframe.html ================================================ 所有类 (sdk 3.0.0 API)

所有类

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/QuickSonicSession.html ================================================ QuickSonicSession (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 QuickSonicSession

    • 方法详细资料

      • handleMessage

        public boolean handleMessage(android.os.Message msg)
        从类复制的说明: SonicSession
        Subclasses must implement this to receive messages.
        指定者:
        handleMessage 在接口中 android.os.Handler.Callback
        覆盖:
        handleMessage 在类中 SonicSession
      • handleFlow_LoadLocalCache

        protected void handleFlow_LoadLocalCache(java.lang.String cacheHtml)
        Handle load local cache of html if exist. This handle is called before connection.
        指定者:
        handleFlow_LoadLocalCache 在类中 SonicSession
        参数:
        cacheHtml - local cache of html
      • onWebReady

        public boolean onWebReady(SonicDiffDataCallback callback)
        从类复制的说明: SonicSession
        Client will call this method to obtain the update data when the page shows the content.
        覆盖:
        onWebReady 在类中 SonicSession
        参数:
        callback - Sonic provides the latest data to the page through this callback
        返回:
        The result
      • onClientReady

        public boolean onClientReady()
        从类复制的说明: SonicSession
        Client informs sonic that it is ready. Client ready means it's webview has been initialized, can start load url or load data.
        覆盖:
        onClientReady 在类中 SonicSession
        返回:
        True if it is set for the first time
      • onRequestResource

        protected java.lang.Object onRequestResource(java.lang.String url)
        从类复制的说明: SonicSession
        When the webview initiates a main resource interception, the client invokes this method to retrieve the data
        覆盖:
        onRequestResource 在类中 SonicSession
        参数:
        url - The url of this session
        返回:
        Return the data to kernel
      • handleFlow_TemplateChange

        protected void handleFlow_TemplateChange(java.lang.String newHtml)
        In this case sonic will always read the new data from the server until the local page finish. If the server data is read finished, sonic will send a CLIENT_CORE_MSG_TEMPLATE_CHANGE message. If the server data is not read finished sonic will split the read and unread data into a bridgedStreamSonicSessionStream. When the client initiates a resource interception, sonic will provide the bridgedStream to the kernel.

        If need save and separate data, sonic will save the server data and separate the server data to template and data.

        指定者:
        handleFlow_TemplateChange 在类中 SonicSession
        参数:
        newHtml - html content from server
      • handleFlow_FirstLoad

        protected void handleFlow_FirstLoad()
        In this case sonic will always read the new data from the server until the client initiates a resource interception. If the server data is read finished, sonic will send CLIENT_CORE_MSG_FIRST_LOAD message with the new html content from server. If the server data is not read finished sonic will split the read and unread data into a bridgedStreamSonicSessionStream.When client initiates a resource interception, sonic will provide the bridgedStream to the kernel.

        If need save and separate data, sonic will save the server data and separate the server data to template and data.

        指定者:
        handleFlow_FirstLoad 在类中 SonicSession
      • handleFlow_DataUpdate

        protected void handleFlow_DataUpdate(java.lang.String serverRsp)
        In this case sonic obtains the difference data between the server and the local data first,then sonic will build the template and server data into html, then send a CLIENT_CORE_MSG_DATA_UPDATE message.
        指定者:
        handleFlow_DataUpdate 在类中 SonicSession
        参数:
        serverRsp - Server response data
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicCacheInterceptor.html ================================================ SonicCacheInterceptor (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicCacheInterceptor

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicCacheInterceptor
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConfig.Builder.html ================================================ SonicConfig.Builder (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicConfig.Builder

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicConfig.Builder
  • 封闭类:
    SonicConfig


    public static class SonicConfig.Builder
    extends java.lang.Object
    Builder for SonicConfig
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConfig.html ================================================ SonicConfig (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicConfig

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicConfig


  • public class SonicConfig
    extends java.lang.Object
    Sonic global config
    • 嵌套类概要

      嵌套类 
      限定符和类型 类和说明
      static class  SonicConfig.Builder
      Builder for SonicConfig
    • 方法概要

      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • SONIC_MAX_NUM_OF_DOWNLOADING_TASK

        public int SONIC_MAX_NUM_OF_DOWNLOADING_TASK
        The max number of tasks which is downloading in the same time.
      • VERIFY_CACHE_FILE_WITH_SHA1

        public boolean VERIFY_CACHE_FILE_WITH_SHA1
        Whether verify file by compare SHA1. If this value is false, sonic will verify file by file's size. Verify the file size is less time consuming than checking SHA1.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConstants.html ================================================ SonicConstants (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicConstants

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicConstants


  • public class SonicConstants
    extends java.lang.Object
    Sonic constants
    • 字段详细资料

      • SONIC_SDK_LOG_PREFIX

        public static final java.lang.String SONIC_SDK_LOG_PREFIX
        SonicSDK log prefix
        另请参阅:
        常量字段值
      • SONIC_VERSION_NUM

        public static final java.lang.String SONIC_VERSION_NUM
        SonicSDK version
        另请参阅:
        常量字段值
      • SONIC_PARAMETER_NAME_PREFIX

        public static final java.lang.String SONIC_PARAMETER_NAME_PREFIX
        Sonic parameter prefix
        另请参阅:
        常量字段值
      • SONIC_REMAIN_PARAMETER_NAMES

        public static final java.lang.String SONIC_REMAIN_PARAMETER_NAMES
        This parameter in url will be as part of session id,and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.
        另请参阅:
        常量字段值
      • SONIC_REMAIN_PARAMETER_SPLIT_CHAR

        public static final java.lang.String SONIC_REMAIN_PARAMETER_SPLIT_CHAR
        另请参阅:
        常量字段值
      • SESSION_MODE_DEFAULT

        public static final int SESSION_MODE_DEFAULT
        SonicSession mode : StandardSonicSession
        另请参阅:
        常量字段值
      • SESSION_MODE_QUICK

        public static final int SESSION_MODE_QUICK
        SonicSession mode : QuickSonicSession
        另请参阅:
        常量字段值
      • ERROR_CODE_UNKNOWN

        public static final int ERROR_CODE_UNKNOWN
        Unknown
        另请参阅:
        常量字段值
      • ERROR_CODE_SUCCESS

        public static final int ERROR_CODE_SUCCESS
        Success
        另请参阅:
        常量字段值
      • ERROR_CODE_CONNECT_IOE

        public static final int ERROR_CODE_CONNECT_IOE
        Http(s) connection error : IO Exception
        另请参阅:
        常量字段值
      • ERROR_CODE_CONNECT_TOE

        public static final int ERROR_CODE_CONNECT_TOE
        Http(s) connection error : time out
        另请参阅:
        常量字段值
      • ERROR_CODE_CONNECT_NPE

        public static final int ERROR_CODE_CONNECT_NPE
        Http(s) connection error : nullPointer in native
        另请参阅:
        常量字段值
      • ERROR_CODE_DATA_VERIFY_FAIL

        public static final int ERROR_CODE_DATA_VERIFY_FAIL
        Verify local file failed
        另请参阅:
        常量字段值
      • ERROR_CODE_MAKE_DIR_ERROR

        public static final int ERROR_CODE_MAKE_DIR_ERROR
        Failed to create sonic directory
        另请参阅:
        常量字段值
      • ERROR_CODE_WRITE_FILE_FAIL

        public static final int ERROR_CODE_WRITE_FILE_FAIL
        File save failed
        另请参阅:
        常量字段值
      • ERROR_CODE_SPLIT_HTML_FAIL

        public static final int ERROR_CODE_SPLIT_HTML_FAIL
        Separate html to template and data failed
        另请参阅:
        常量字段值
      • ERROR_CODE_MERGE_DIFF_DATA_FAIL

        public static final int ERROR_CODE_MERGE_DIFF_DATA_FAIL
        Obtain difference data between server and local data failed
        另请参阅:
        常量字段值
      • ERROR_CODE_SERVER_DATA_EXCEPTION

        public static final int ERROR_CODE_SERVER_DATA_EXCEPTION
        Server data exception
        另请参阅:
        常量字段值
      • ERROR_CODE_BUILD_HTML_ERROR

        public static final int ERROR_CODE_BUILD_HTML_ERROR
        Build template and data to html failed
        另请参阅:
        常量字段值
    • 构造器详细资料

      • SonicConstants

        public SonicConstants()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicDBHelper.html ================================================ SonicDBHelper (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicDBHelper

  • java.lang.Object
    • android.database.sqlite.SQLiteOpenHelper
      • com.tencent.sonic.sdk.SonicDBHelper


  • public class SonicDBHelper
    extends android.database.sqlite.SQLiteOpenHelper
    SonicDBHelper interacts with the database, such as managing database creation and the version management.
    • 方法概要

      所有方法 静态方法 实例方法 具体方法 
      限定符和类型 方法和说明
      static SonicDBHelper getInstance() 
      boolean isUpgrading()
      Indicates whether is upgrading or not.
      void onCreate(android.database.sqlite.SQLiteDatabase db)
      Called when the database is created for the first time.
      void onUpgrade(android.database.sqlite.SQLiteDatabase db, int oldVersion, int newVersion) 
      • 从类继承的方法 android.database.sqlite.SQLiteOpenHelper

        close, getDatabaseName, getReadableDatabase, getWritableDatabase, onConfigure, onDowngrade, onOpen, setWriteAheadLoggingEnabled
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 方法详细资料

      • onCreate

        public void onCreate(android.database.sqlite.SQLiteDatabase db)
        Called when the database is created for the first time. This is where the creation of tables and the initial population of the tables should happen.
        指定者:
        onCreate 在类中 android.database.sqlite.SQLiteOpenHelper
        参数:
        db - The database.
      • onUpgrade

        public void onUpgrade(android.database.sqlite.SQLiteDatabase db,
                              int oldVersion,
                              int newVersion)
        指定者:
        onUpgrade 在类中 android.database.sqlite.SQLiteOpenHelper
      • isUpgrading

        public boolean isUpgrading()
        Indicates whether is upgrading or not. If return true, It will fail to create session.
        返回:
        is Upgrading or not
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicDiffDataCallback.html ================================================ SonicDiffDataCallback (sdk 3.0.0 API)
com.tencent.sonic.sdk

接口 SonicDiffDataCallback



  • public interface SonicDiffDataCallback
    This interface is used to call the difference data between local and server data to the client.
    • 方法概要

      所有方法 实例方法 抽象方法 
      限定符和类型 方法和说明
      void callback(java.lang.String resultData)
      Called when sonic processes the local data and the server data.
    • 方法详细资料

      • callback

        void callback(java.lang.String resultData)
        Called when sonic processes the local data and the server data. When the page requests the latest data, sonic will send the latest data to page by this method.
        参数:
        resultData - The result to page.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicEngine.html ================================================ SonicEngine (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicEngine

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicEngine


  • public class SonicEngine
    extends java.lang.Object
    Interacts with the overall SonicSessions running in the system. Instances of this class can be used to query or fetch the information, such as SonicSession SonicRuntime.
    • 方法详细资料

      • createInstance

        public static SonicEngine createInstance(@NonNull
                                                 SonicRuntime runtime,
                                                 @NonNull
                                                 SonicConfig config)
        Create SonicEngine instance. Meanwhile it will initialize engine and SonicRuntime.
        参数:
        runtime - SonicRuntime
        config - SonicConfig
        返回:
        SonicEngine object
      • initSonicDB

        public void initSonicDB()
        Init sonic DB which will upgrade to new version of database.
      • getRuntime

        public SonicRuntime getRuntime()
        返回:
        SonicRuntime object
      • getConfig

        public SonicConfig getConfig()
        返回:
        SonicConfig object
      • isSonicAvailable

        public boolean isSonicAvailable()
        Whether Sonic Service is available or not
        返回:
        return true if Sonic Service is available , false else others.
      • makeSessionId

        public static java.lang.String makeSessionId(java.lang.String url,
                                                     boolean isAccountRelated)
        Create session ID
        参数:
        url - session url
        isAccountRelated - Session Id will contain SonicRuntime.getCurrentUserAccount() if isAccountRelated is true.
        返回:
        String Object of session ID
      • preCreateSession

        public boolean preCreateSession(@NonNull
                                        java.lang.String url,
                                        @NonNull
                                        SonicSessionConfig sessionConfig)
        This method will preCreate sonic session . And maps the specified session id to the specified value in this table preloadSessionPool if there is no same sonic session. At the same time, if the number of preloadSessionPool exceeds SonicConfig.MAX_PRELOAD_SESSION_COUNT, preCreateSession will return false and not create any sonic session.

        Note: this method is intended for preload scene.

        参数:
        url - url for preCreate sonic session
        sessionConfig - SonicSession config
        返回:
        If this method preCreate sonic session and associated with sessionId in this table preloadSessionPool successfully, it will return true, false otherwise.
      • createSession

        public SonicSession createSession(@NonNull
                                          java.lang.String url,
                                          @NonNull
                                          SonicSessionConfig sessionConfig)
        参数:
        url - url for SonicSession Object
        sessionConfig - SSonicSession config
        返回:
        This method will create and return SonicSession Object when url is legal.
      • cleanCache

        public boolean cleanCache()
        Removes all of the cache from preloadSessionPool and deletes file caches from SDCard.
        返回:
        Returns false if runningSessionHashMap is not empty. Returns true if all of the local file cache has been deleted, false otherwise
      • removeSessionCache

        public boolean removeSessionCache(@NonNull
                                          java.lang.String sessionId)
        Removes the sessionId and its corresponding SonicSession from preloadSessionPool.
        参数:
        sessionId - A unique session id
        返回:
        Return true If there is no specified sessionId in runningSessionHashMap, false otherwise.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicFileUtils.html ================================================ SonicFileUtils (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicFileUtils

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicFileUtils


  • public class SonicFileUtils
    extends java.lang.Object
    Interact with the overall file operations.
    • 方法概要

      所有方法 静态方法 具体方法 
      限定符和类型 方法和说明
      static java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaderFromLocalCache(java.lang.String headerPath)
      Get headers from local cache file
      static java.lang.String getSonicResourceHeaderPath(java.lang.String resourceName) 
      static java.lang.String getSonicResourcePath(java.lang.String resourceName) 
      static byte[] readFileToBytes(java.io.File file) 
      static boolean verifyData(byte[] content, java.lang.String targetSha1)
      This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 构造器详细资料

      • SonicFileUtils

        public SonicFileUtils()
    • 方法详细资料

      • getSonicResourcePath

        public static java.lang.String getSonicResourcePath(java.lang.String resourceName)
        参数:
        resourceName - resource file name
        返回:
        The path of the resource file.
      • getSonicResourceHeaderPath

        public static java.lang.String getSonicResourceHeaderPath(java.lang.String resourceName)
        参数:
        resourceName - resource file name
        返回:
        The path of the resource header file.
      • verifyData

        public static boolean verifyData(byte[] content,
                                         java.lang.String targetSha1)
        This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.
        参数:
        content - Data bytes
        targetSha1 - The specified hash value
        返回:
        true if the given hash value equivalent to computed hash value, false otherwise
      • readFileToBytes

        public static byte[] readFileToBytes(java.io.File file)
        参数:
        file - path of the file to read
        返回:
        Returns the content bytes read from the file.
      • getHeaderFromLocalCache

        public static java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaderFromLocalCache(java.lang.String headerPath)
        Get headers from local cache file
        参数:
        headerPath - header file path
        返回:
        The last http response headers from local cache.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html ================================================ SonicResourceDataHelper.ResourceData (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicResourceDataHelper.ResourceData

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
  • 封闭类:
    SonicResourceDataHelper


    public static class SonicResourceDataHelper.ResourceData
    extends java.lang.Object
    resource data structure
    • 字段概要

      字段 
      限定符和类型 字段和说明
      long expiredTime
      Indicates when local resource cache is expired.
      java.lang.String resourceSha1
      The sha1 of resource
      long resourceSize
      The size of resource
    • 构造器概要

      构造器 
      构造器和说明
      ResourceData() 
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      void reset()
      Reset data
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • resourceSha1

        public java.lang.String resourceSha1
        The sha1 of resource
      • resourceSize

        public long resourceSize
        The size of resource
      • expiredTime

        public long expiredTime
        Indicates when local resource cache is expired. If It is expired, the record of database and file on SDCard will be removed.
    • 构造器详细资料

      • ResourceData

        public ResourceData()
    • 方法详细资料

      • reset

        public void reset()
        Reset data
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicResourceDataHelper.html ================================================ SonicResourceDataHelper (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicResourceDataHelper

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicResourceDataHelper


  • public class SonicResourceDataHelper
    extends java.lang.Object
    SonicResourceDataHelper manages the resource database.
    • 字段详细资料

      • CREATE_TABLE_SQL

        public static final java.lang.String CREATE_TABLE_SQL
        The create table sql
        另请参阅:
        常量字段值
    • 构造器详细资料

      • SonicResourceDataHelper

        public SonicResourceDataHelper()
    • 方法详细资料

      • getResourceData

        @NonNull
        public static SonicResourceDataHelper.ResourceData getResourceData(java.lang.String resourceId)
        Get sonic ResourceData by unique resource id
        参数:
        resourceId - a unique resource id
        返回:
        ResourceData
      • getAllResourceDataColumn

        public static java.lang.String[] getAllResourceDataColumn()
        返回:
        all of the column in Sonic_RESOURCE_TABLE_NAME
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicRuntime.html ================================================ SonicRuntime (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicRuntime

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicRuntime


  • public abstract class SonicRuntime
    extends java.lang.Object
    SonicRuntime is a class which interacts with the overall running information in the system, including Context, UA, ID (which is the unique identification for the saved data) and other information.
    • 字段概要

      字段 
      限定符和类型 字段和说明
      protected android.content.Context context
      A context for this runtime, it's expected to be ApplicationContext
      protected static android.os.HandlerThread fileHandlerThread
      This handle thread use to save sonic cache.
    • 构造器概要

      构造器 
      构造器和说明
      SonicRuntime(android.content.Context context) 
    • 方法概要

      所有方法 实例方法 抽象方法 具体方法 
      限定符和类型 方法和说明
      abstract java.lang.Object createWebResourceResponse(java.lang.String mimeType, java.lang.String encoding, java.io.InputStream data, java.util.Map<java.lang.String,java.lang.String> headers)
      We add this method to decoupling webview since some application may use x5 webview or others.
      android.content.Context getContext() 
      abstract java.lang.String getCookie(java.lang.String url)
      Get cookies of the input url, this method will be called before sonic session make a session connection to request data.
      abstract java.lang.String getCurrentUserAccount()
      Get the current user account, this method will be called when makeSessionId's params is account related.
      android.os.Looper getFileThreadLooper()
      Return the looper of HandleThread which use to save sonic cache.
      java.lang.String getHostDirectAddress(java.lang.String url)
      Get the direct address of a url(host),format as[ip:port],the default http port is 80 and 443 for https.
      java.util.Set<java.lang.String> getQueryParameterNames(android.net.Uri uri)
      Returns a set of the unique names of all query parameters.
      java.io.File getSonicCacheDir()
      The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.
      java.io.File getSonicResourceCacheDir()
      The resource cache root dir which resource cache will be storage.
      android.content.SharedPreferences getSonicSharedPreferences()
      get SharedPreferences of sonic.
      abstract java.lang.String getUserAgent()
      Get user agent of current runtime, this method will be called before sonic session make a session connection to request data.
      abstract boolean isNetworkValid()
      This method is used to judge is network valid or not
      abstract boolean isSonicUrl(java.lang.String url)
      This method is used to judge the input url is support sonic or not, when this method return true, it means it's allow to create a sonic session for this url.
      abstract void log(java.lang.String tag, int level, java.lang.String message) 
      java.lang.String makeSessionId(java.lang.String url, boolean isAccountRelated)
      Make a unique session id for the url, it can be account related.
      abstract void notifyError(SonicSessionClient client, java.lang.String url, int errorCode)
      Notify error for host application to do report or statics
      void postTaskToMainThread(java.lang.Runnable task, long delayMillis)
      Post a task in main thread
      void postTaskToSessionThread(java.lang.Runnable task)
      Post a task to session thread(a high priority thread is better)
      abstract void postTaskToThread(java.lang.Runnable task, long delayMillis)
      Post a task to the thread(a io thread is better) which used to separate template and data.
      abstract boolean setCookie(java.lang.String url, java.util.List<java.lang.String> cookies)
      Set cookies to webview after session connection response with cookies in it's headers.
      boolean shouldLog(int level)
      Logger function
      abstract void showToast(java.lang.CharSequence text, int duration)
      Show toast
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • context

        protected final android.content.Context context
        A context for this runtime, it's expected to be ApplicationContext
      • fileHandlerThread

        protected static volatile android.os.HandlerThread fileHandlerThread
        This handle thread use to save sonic cache.
    • 构造器详细资料

      • SonicRuntime

        public SonicRuntime(android.content.Context context)
    • 方法详细资料

      • getContext

        public android.content.Context getContext()
      • makeSessionId

        public java.lang.String makeSessionId(java.lang.String url,
                                              boolean isAccountRelated)
        Make a unique session id for the url, it can be account related.
        参数:
        url - Url which need to make session id
        isAccountRelated - Is account related or not
        返回:
        A unique session id
      • getQueryParameterNames

        public java.util.Set<java.lang.String> getQueryParameterNames(android.net.Uri uri)
        Returns a set of the unique names of all query parameters. Iterating over the set will return the names in order of their first occurrence.
        参数:
        uri - The uri
        返回:
        A set of decoded names
        抛出:
        java.lang.UnsupportedOperationException - if this isn't a hierarchical URI
      • shouldLog

        public boolean shouldLog(int level)
        Logger function
        参数:
        level - Level of this log,such like Log.DEBUG.
        返回:
        Should log or not
      • log

        public abstract void log(java.lang.String tag,
                                 int level,
                                 java.lang.String message)
      • getCookie

        public abstract java.lang.String getCookie(java.lang.String url)
        Get cookies of the input url, this method will be called before sonic session make a session connection to request data.
        参数:
        url - The url which need to get cookies
        返回:
        The cookies for current input url
      • setCookie

        public abstract boolean setCookie(java.lang.String url,
                                          java.util.List<java.lang.String> cookies)
        Set cookies to webview after session connection response with cookies in it's headers.
        参数:
        url - The url which need to set cookies
        cookies - The cookies for current input url
        返回:
        Set cookie success or not
      • getUserAgent

        public abstract java.lang.String getUserAgent()
        Get user agent of current runtime, this method will be called before sonic session make a session connection to request data.(sonic sdk info such like "sonic-sdk-version/2.0.0" will be added to this user agent.)
        返回:
        The user agent
      • getSonicCacheDir

        public java.io.File getSonicCacheDir()
        The sonic cache root dir which sonic cache such like .html/.template/.data will be storage. it's expected to be a dir in /data dir for security.
        返回:
        The root cache dir.
      • getSonicResourceCacheDir

        public java.io.File getSonicResourceCacheDir()
        The resource cache root dir which resource cache will be storage. it's expected to be a dir in /sdcard dir for security.
        返回:
        The root cache dir.
      • getSonicSharedPreferences

        public android.content.SharedPreferences getSonicSharedPreferences()
        get SharedPreferences of sonic.
        返回:
        the sp
      • getCurrentUserAccount

        public abstract java.lang.String getCurrentUserAccount()
        Get the current user account, this method will be called when makeSessionId's params is account related.
        返回:
        Current user account
      • isSonicUrl

        public abstract boolean isSonicUrl(java.lang.String url)
        This method is used to judge the input url is support sonic or not, when this method return true, it means it's allow to create a sonic session for this url. e.g. In mobile QQ, it will judge url params contain sonic=1 or not, if contains it will return true, others return false.
        参数:
        url - The url which need to judge
        返回:
        Return is sonic url or not
      • createWebResourceResponse

        public abstract java.lang.Object createWebResourceResponse(java.lang.String mimeType,
                                                                   java.lang.String encoding,
                                                                   java.io.InputStream data,
                                                                   java.util.Map<java.lang.String,java.lang.String> headers)
        We add this method to decoupling webview since some application may use x5 webview or others. e.g. If u use a system webview, just call new android.webkit.WebResourceResponse Constructs a resource response with the given MIME type, encoding, and input stream. Callers must implement InputStream.read(byte[]) for the input stream.
        参数:
        mimeType - The resource response's MIME type, for example text/html
        encoding - The resource response's encoding
        data - The input stream that provides the resource response's data. Must not be a StringBufferInputStream.
        headers - The headers
        返回:
        The response to kernel
      • isNetworkValid

        public abstract boolean isNetworkValid()
        This method is used to judge is network valid or not
        返回:
        Network valid or not
      • getHostDirectAddress

        public java.lang.String getHostDirectAddress(java.lang.String url)
        Get the direct address of a url(host),format as[ip:port],the default http port is 80 and 443 for https.
        参数:
        url - The input url which need to get direct address
        返回:
        Return a valid direct address or null.
      • showToast

        public abstract void showToast(java.lang.CharSequence text,
                                       int duration)
        Show toast
        参数:
        text - Content
        duration - See Toast.LENGTH_SHORT/Toast.LENGTH_LONG
      • postTaskToThread

        public abstract void postTaskToThread(java.lang.Runnable task,
                                              long delayMillis)
        Post a task to the thread(a io thread is better) which used to separate template and data.
        参数:
        task - A runnable task
        delayMillis - The delay (in milliseconds) until the Runnable will be executed.
      • postTaskToSessionThread

        public void postTaskToSessionThread(java.lang.Runnable task)
        Post a task to session thread(a high priority thread is better)
        参数:
        task - A runnable task
      • postTaskToMainThread

        public void postTaskToMainThread(java.lang.Runnable task,
                                         long delayMillis)
        Post a task in main thread
        参数:
        task - A runnable task
        delayMillis - Delay millis
      • getFileThreadLooper

        public android.os.Looper getFileThreadLooper()
        Return the looper of HandleThread which use to save sonic cache.
        返回:
        The looper of HandleThread which use to save sonic cache.
      • notifyError

        public abstract void notifyError(SonicSessionClient client,
                                         java.lang.String url,
                                         int errorCode)
        Notify error for host application to do report or statics
        参数:
        client - The error client
        url - The error url
        errorCode - Error code
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicServer.html ================================================ SonicServer (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicServer

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicServer
  • 所有已实现的接口:
    SonicSessionStream.Callback


    public class SonicServer
    extends java.lang.Object
    implements SonicSessionStream.Callback
    Instances of this class can be used to read server response from SonicSessionConnection. If this request support Local Sonic Server, it will separate html into template and data file.
    • 构造器概要

      构造器 
      构造器和说明
      SonicServer(SonicSession session, android.content.Intent requestIntent) 
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      protected int connect()
      Opens a communications link to the resource referenced by Sonic session.
      void disconnect()
      Disconnect the communications link to the resource referenced by Sonic session
      int getResponseCode() 
      java.lang.String getResponseData(boolean readUntilEnd)
      Return current cached server response data.
      java.lang.String getResponseHeaderField(java.lang.String key) 
      java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResponseHeaderFields()
      return response headers which contains response headers from server and custom response headers from com.tencent.sonic.sdk.SonicSessionConfig note: server response headers have high priority than custom headers!
      java.io.InputStream getResponseStream(java.util.concurrent.atomic.AtomicBoolean breakConditions)
      Read all of data from SonicSessionConnection.getResponseStream() into byte array output stream outputStream until breakCondition is true when breakCondition is not null.
      java.lang.String getTemplate()
      If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.
      java.lang.String getUpdatedData()
      If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.
      void onClose(boolean readComplete, java.io.ByteArrayOutputStream outputStream)
      Close callback
      protected void separateTemplateAndData() 
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • TAG

        public static final java.lang.String TAG
        另请参阅:
        常量字段值
      • serverRsp

        protected java.lang.String serverRsp
      • templateString

        protected java.lang.String templateString
      • dataString

        protected java.lang.String dataString
      • responseCode

        protected int responseCode
      • requestIntent

        protected final android.content.Intent requestIntent
      • cachedResponseHeaders

        protected java.util.Map<java.lang.String,java.util.List<java.lang.String>> cachedResponseHeaders
        Cached response headers which contains response headers from server and custom response headers from com.tencent.sonic.sdk.SonicSessionConfig
    • 构造器详细资料

      • SonicServer

        public SonicServer(SonicSession session,
                           android.content.Intent requestIntent)
    • 方法详细资料

      • connect

        protected int connect()
        Opens a communications link to the resource referenced by Sonic session. If this request support Local Sonic Server, it will separate html into template and data file.
        返回:
        Returns the response code of connection
      • getResponseCode

        public int getResponseCode()
      • disconnect

        public void disconnect()
        Disconnect the communications link to the resource referenced by Sonic session
      • getResponseHeaderFields

        public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResponseHeaderFields()
        return response headers which contains response headers from server and custom response headers from com.tencent.sonic.sdk.SonicSessionConfig note: server response headers have high priority than custom headers!
        返回:
        a Map of header fields
      • getResponseHeaderField

        public java.lang.String getResponseHeaderField(java.lang.String key)
        参数:
        key - the name of a header field.
        返回:
        Returns the value of the named header field from SonicSessionConnection.
      • getResponseStream

        public java.io.InputStream getResponseStream(java.util.concurrent.atomic.AtomicBoolean breakConditions)
        Read all of data from SonicSessionConnection.getResponseStream() into byte array output stream outputStream until breakCondition is true when breakCondition is not null. Then return a SonicSessionStream obtains input bytes from outputStream and a netStream when there is unread data from network.
        参数:
        breakConditions - This method won't read any data from SonicSessionConnection.getResponseStream() if breakCondition is true.
        返回:
        Returns a SonicSessionStream obtains input bytes from outputStream and a netStream when there is unread data from network.
      • getResponseData

        public java.lang.String getResponseData(boolean readUntilEnd)
        Return current cached server response data. If @{code readUntilEnd} is true and current cached response data is empty, read all of data from SonicSessionConnection.getResponseStream() into byte array output stream outputStream. And then this method convert outputStream into response string serverRsp.

        Note: This method blocks until the end of the input stream has been reached or breakCondition has been reset to true.

        参数:
        readUntilEnd - This method won't read any data from SonicSessionConnection.getResponseStream() if readUntilEnd is false.
        返回:
        Returns serverRsp current cached server response data.
      • getTemplate

        public java.lang.String getTemplate()
        If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.
        返回:
        The template.
      • getUpdatedData

        public java.lang.String getUpdatedData()
        If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.
        返回:
        the JSONObject String which represent data.
      • separateTemplateAndData

        protected void separateTemplateAndData()
      • onClose

        public void onClose(boolean readComplete,
                            java.io.ByteArrayOutputStream outputStream)
        从接口复制的说明: SonicSessionStream.Callback
        Close callback
        指定者:
        onClose 在接口中 SonicSessionStream.Callback
        参数:
        readComplete - SonicSessionStream data has read completed
        outputStream - outputStream include memStream data and netStream data
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSession.Callback.html ================================================ SonicSession.Callback (sdk 3.0.0 API)
com.tencent.sonic.sdk

接口 SonicSession.Callback

  • 封闭类:
    SonicSession


    public static interface SonicSession.Callback
    The interface is used to inform the listeners that the state of the session has changed.
    • 方法详细资料

      • onSessionStateChange

        void onSessionStateChange(SonicSession session,
                                  int oldState,
                                  int newState,
                                  android.os.Bundle extraData)
        When the session's state changes, this method will be invoked.
        参数:
        session - Current session.
        oldState - The old state.
        newState - The next state.
        extraData - Extra data.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSession.html ================================================ SonicSession (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSession

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSession
  • 所有已实现的接口:
    android.os.Handler.Callback
    直接已知子类:
    QuickSonicSession, StandardSonicSession


    public abstract class SonicSession
    extends java.lang.Object
    implements android.os.Handler.Callback
    In Sonic, SonicSessions are used to manage the entire process,include obtain the latest data from the server, provide local and latest data to kernel, separate html to template and data, build template and data to html and so on. Each url involves one session at a time, that session will be destroyed when the page is destroyed.
    • 字段详细资料

      • TAG

        public static final java.lang.String TAG
        Log filter
        另请参阅:
        常量字段值
      • WEB_RESPONSE_SRC_CODE

        public static final java.lang.String WEB_RESPONSE_SRC_CODE
        The result keyword to page : the value is srcResultCode
        另请参阅:
        常量字段值
      • WEB_RESPONSE_CODE

        public static final java.lang.String WEB_RESPONSE_CODE
        The result keyword to page : the value is finalResultCode
        另请参阅:
        常量字段值
      • WEB_RESPONSE_EXTRA

        public static final java.lang.String WEB_RESPONSE_EXTRA
        另请参阅:
        常量字段值
      • WEB_RESPONSE_DATA

        public static final java.lang.String WEB_RESPONSE_DATA
        The all data keyword to page
        另请参阅:
        常量字段值
      • DATA_UPDATE_BUNDLE_PARAMS_DIFF

        public static final java.lang.String DATA_UPDATE_BUNDLE_PARAMS_DIFF
        另请参阅:
        常量字段值
      • WEB_RESPONSE_LOCAL_REFRESH_TIME

        public static final java.lang.String WEB_RESPONSE_LOCAL_REFRESH_TIME
        另请参阅:
        常量字段值
      • CHROME_FILE_THREAD

        public static final java.lang.String CHROME_FILE_THREAD
        Name of chrome file thread
        另请参阅:
        常量字段值
      • STATE_NONE

        public static final int STATE_NONE
        Session state : original.

        This state means session has not start.

        另请参阅:
        常量字段值
      • STATE_RUNNING

        public static final int STATE_RUNNING
        Session state : running.

        This state means session has begun to request data from the server and is processing the data.

        另请参阅:
        常量字段值
      • STATE_READY

        public static final int STATE_READY
        Session state : ready.

        This state means session data is available when the page initiates a resource interception. In other stats the client(kernel) will wait.

        另请参阅:
        常量字段值
      • STATE_DESTROY

        public static final int STATE_DESTROY
        Session state : destroyed.

        This state means the session is destroyed.

        另请参阅:
        常量字段值
      • OFFLINE_MODE_HTTP

        public static final java.lang.String OFFLINE_MODE_HTTP
        The value of "cache-offline" in http(s) response headers.

        This value means sonic server unavailable, the terminal does not take sonic logic for the next period of time,the value of time is defined in SonicConfig.SONIC_UNAVAILABLE_TIME

        另请参阅:
        常量字段值
      • OFFLINE_MODE_STORE

        public static final java.lang.String OFFLINE_MODE_STORE
        The value of "cache-offline" in http(s) response headers.

        This value means sonic will save the latest data, but not refresh page.For example, when sonic mode is data update, sonic will not provide the difference data between local and server to page to refresh the content.

        另请参阅:
        常量字段值
      • OFFLINE_MODE_TRUE

        public static final java.lang.String OFFLINE_MODE_TRUE
        The value of "cache-offline" in http(s) response headers.

        This value means sonic will save the latest data and refresh page content.

        另请参阅:
        常量字段值
      • OFFLINE_MODE_FALSE

        public static final java.lang.String OFFLINE_MODE_FALSE
        The value of "cache-offline" in http(s) response headers.

        This value means sonic will refresh page content but not save date, sonic will remove the local data also.

        另请参阅:
        常量字段值
      • SONIC_RESULT_CODE_UNKNOWN

        public static final int SONIC_RESULT_CODE_UNKNOWN
        Sonic mode : unknown.
        另请参阅:
        常量字段值
      • SONIC_RESULT_CODE_FIRST_LOAD

        public static final int SONIC_RESULT_CODE_FIRST_LOAD
        Sonic mode : first load.
        另请参阅:
        常量字段值
      • SONIC_RESULT_CODE_TEMPLATE_CHANGE

        public static final int SONIC_RESULT_CODE_TEMPLATE_CHANGE
        Sonic mode : template change.
        另请参阅:
        常量字段值
      • SONIC_RESULT_CODE_DATA_UPDATE

        public static final int SONIC_RESULT_CODE_DATA_UPDATE
        Sonic mode : data update.
        另请参阅:
        常量字段值
      • SONIC_RESULT_CODE_HIT_CACHE

        public static final int SONIC_RESULT_CODE_HIT_CACHE
        Sonic mode : 304.
        另请参阅:
        常量字段值
      • srcResultCode

        protected int srcResultCode
        Sonic original mode.

        For example, when local data does not exist, the value is SONIC_RESULT_CODE_FIRST_LOAD

      • finalResultCode

        protected int finalResultCode
        Sonic final mode.

        For example, when local data does not exist, the srcResultCode value is SONIC_RESULT_CODE_FIRST_LOAD. If the server data is read finished, sonic will provide the latest data to kernel when the kernel initiates a resource interception.This effect is the same as loading local data, so the sonic mode will be set as SONIC_RESULT_CODE_HIT_CACHE

      • COMMON_MSG_BEGIN

        protected static final int COMMON_MSG_BEGIN
        另请参阅:
        常量字段值
      • CLIENT_MSG_NOTIFY_RESULT

        protected static final int CLIENT_MSG_NOTIFY_RESULT
        The message to record sonic mode.
        另请参阅:
        常量字段值
      • CLIENT_MSG_ON_WEB_READY

        protected static final int CLIENT_MSG_ON_WEB_READY
        The message of page ready, its means page want to get the latest session data.
        另请参阅:
        常量字段值
      • SESSION_MSG_FORCE_DESTROY

        protected static final int SESSION_MSG_FORCE_DESTROY
        The message of forced to destroy the session.
        另请参阅:
        常量字段值
      • COMMON_MSG_END

        protected static final int COMMON_MSG_END
        另请参阅:
        常量字段值
      • FILE_THREAD_MSG_BEGIN

        protected static final int FILE_THREAD_MSG_BEGIN
        另请参阅:
        常量字段值
      • FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE

        protected static final int FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE
        The message of saving sonic cache while server close.
        另请参阅:
        常量字段值
      • FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED

        protected static final int FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED
        The message of saving sonic cache while session finish.
        另请参阅:
        常量字段值
      • RESOURCE_INTERCEPT_STATE_NONE

        protected static final int RESOURCE_INTERCEPT_STATE_NONE
        Resource Intercept State : none
        另请参阅:
        常量字段值
      • RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD

        protected static final int RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD
        Resource Intercept State : intercepting in file thread
        另请参阅:
        常量字段值
      • RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD

        protected static final int RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD
        Resource Intercept State : intercepting in other thread(may be IOThread or other else)
        另请参阅:
        常量字段值
      • sessionState

        protected final java.util.concurrent.atomic.AtomicInteger sessionState
        Session state, include STATE_NONE, STATE_RUNNING, STATE_READY and STATE_DESTROY.
      • wasInterceptInvoked

        protected final java.util.concurrent.atomic.AtomicBoolean wasInterceptInvoked
        Whether the client initiates a resource interception.
      • clientIsReady

        protected final java.util.concurrent.atomic.AtomicBoolean clientIsReady
        Whether the client is ready.
      • isWaitingForSaveFile

        protected final java.util.concurrent.atomic.AtomicBoolean isWaitingForSaveFile
        Whether it is waiting for the file to be saved. If it is true, the session can not be destroyed.
      • isWaitingForDestroy

        protected final java.util.concurrent.atomic.AtomicBoolean isWaitingForDestroy
        Whether the session is waiting for destroy.
      • isWaitingForSessionThread

        protected final java.util.concurrent.atomic.AtomicBoolean isWaitingForSessionThread
        Whether the session is waiting for data. If it is true, the session can not be destroyed.
      • wasOnPageFinishInvoked

        protected final java.util.concurrent.atomic.AtomicBoolean wasOnPageFinishInvoked
        Whether the local html is loaded, it is used only the template changes.
      • resourceInterceptState

        protected final java.util.concurrent.atomic.AtomicInteger resourceInterceptState
        Resource intercept state, include RESOURCE_INTERCEPT_STATE_NONE, RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD, RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD More about it at {https://codereview.chromium.org/1350553005/#ps20001}
      • clientIsReload

        protected final java.util.concurrent.atomic.AtomicBoolean clientIsReload
        Indicate current session is reload or not.
      • server

        protected volatile SonicServer server
        Sonic server
      • resourceDownloaderEngine

        protected volatile SonicDownloadEngine resourceDownloaderEngine
        Sonic sub resource downloader
      • pendingWebResourceStream

        protected volatile java.io.InputStream pendingWebResourceStream
        The response for client interception.
      • pendingDiffData

        protected java.lang.String pendingDiffData
        The difference data between local and server data.
      • sNextSessionLogId

        protected static long sNextSessionLogId
        Log id
      • id

        public final java.lang.String id
      • isPreload

        protected boolean isPreload
        Whether current session is preload.
      • createdTime

        public long createdTime
        The time of current session created.
      • sId

        public final long sId
        The integer id of current session
      • srcUrl

        public java.lang.String srcUrl
        The original url
      • mainHandler

        protected final android.os.Handler mainHandler
      • stateChangedCallbackList

        protected final java.util.concurrent.CopyOnWriteArrayList<java.lang.ref.WeakReference<SonicSession.Callback>> stateChangedCallbackList
      • fileHandler

        protected final android.os.Handler fileHandler
      • preloadLinks

        protected java.util.List<java.lang.String> preloadLinks
      • sessionCallbackList

        protected final java.util.concurrent.CopyOnWriteArrayList<java.lang.ref.WeakReference<com.tencent.sonic.sdk.SonicSessionCallback>> sessionCallbackList
      • intent

        protected final android.content.Intent intent
        This intent saves all of the initialization param.
    • 方法详细资料

      • handleMessage

        public boolean handleMessage(android.os.Message msg)
        Subclasses must implement this to receive messages.
        指定者:
        handleMessage 在接口中 android.os.Handler.Callback
      • start

        public void start()
        Start the sonic process
      • refresh

        public boolean refresh()
      • createConnectionIntent

        protected android.content.Intent createConnectionIntent(com.tencent.sonic.sdk.SonicDataHelper.SessionData sessionData)
      • handleFlow_Connection

        protected void handleFlow_Connection(boolean hasCache,
                                             com.tencent.sonic.sdk.SonicDataHelper.SessionData sessionData)
        Initiate a network request to obtain server data.
        参数:
        hasCache - Indicates local sonic cache is exist or not.
        sessionData - SessionData holds eTag templateTag
      • handleFlow_LoadLocalCache

        protected abstract void handleFlow_LoadLocalCache(java.lang.String cacheHtml)
      • handleFlow_DataUpdate

        protected abstract void handleFlow_DataUpdate(java.lang.String serverRsp)
        Handle data update SONIC_RESULT_CODE_DATA_UPDATE logic.
        参数:
        serverRsp - Server response data.
      • handleFlow_TemplateChange

        protected abstract void handleFlow_TemplateChange(java.lang.String newHtml)
        Handle template update SONIC_RESULT_CODE_TEMPLATE_CHANGE logic.
        参数:
        newHtml - new Html string from web-server
      • handleFlow_HttpError

        protected abstract void handleFlow_HttpError(int responseCode)
      • handleFlow_ServiceUnavailable

        protected abstract void handleFlow_ServiceUnavailable()
      • handleFlow_NotModified

        protected void handleFlow_NotModified()
      • isPreload

        public boolean isPreload()
      • addSessionStateChangedCallback

        protected boolean addSessionStateChangedCallback(SonicSession.Callback callback)
      • removeSessionStateChangedCallback

        protected boolean removeSessionStateChangedCallback(SonicSession.Callback callback)
      • addSessionCallback

        public boolean addSessionCallback(com.tencent.sonic.sdk.SonicSessionCallback callback)
      • removeSessionCallback

        public boolean removeSessionCallback(com.tencent.sonic.sdk.SonicSessionCallback callback)
      • getCurrentUrl

        public java.lang.String getCurrentUrl()
      • getFinalResultCode

        public int getFinalResultCode()
      • getSrcResultCode

        public int getSrcResultCode()
      • isDestroyedOrWaitingForDestroy

        public boolean isDestroyedOrWaitingForDestroy()
      • postForceDestroyIfNeed

        protected boolean postForceDestroyIfNeed()
        Destroy the session if it is waiting for destroy and it is can be destroyed.
        返回:
        Return true if the session is waiting for destroy and it is can be destroyed.
      • canDestroy

        protected boolean canDestroy()
      • switchState

        protected boolean switchState(int fromState,
                                      int toState,
                                      boolean notify)
      • onServerClosed

        public void onServerClosed(SonicServer sonicServer,
                                   boolean readComplete)
        If the kernel obtain inputStream from a SonicSessionStream, the inputStream will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream close.

        If the html is read complete, sonic will separate the html to template and data, and save these data.

        参数:
        sonicServer - The actual server connection of current SonicSession.
        readComplete - Whether the html is read complete.
      • postTaskToSaveSonicCache

        protected void postTaskToSaveSonicCache(java.lang.String htmlString)
      • doSaveSonicCache

        protected void doSaveSonicCache(SonicServer sonicServer,
                                        java.lang.String htmlString)
      • notifyStateChange

        protected void notifyStateChange(int oldState,
                                         int newState,
                                         android.os.Bundle extraData)
        When the session state changes, notify the listeners.
        参数:
        oldState - The old state.
        newState - The nex state.
        extraData - The extra data.
      • setResult

        protected void setResult(int srcCode,
                                 int finalCode,
                                 boolean notify)
        Record the sonic mode, notify the result to page if necessary.
        参数:
        srcCode - The original mode.
        finalCode - The final mode.
        notify - Whether notify te result to page.
      • onClientReady

        public boolean onClientReady()
        Client informs sonic that it is ready. Client ready means it's webview has been initialized, can start load url or load data.
        返回:
        True if it is set for the first time
      • onClientRequestResource

        public final java.lang.Object onClientRequestResource(java.lang.String url)
        When the webview initiates a resource interception, the client invokes the method to retrieve the data
        参数:
        url - The url of this session
        返回:
        Return the data to kernel
      • shouldSetCookieAsynchronous

        protected boolean shouldSetCookieAsynchronous()
        Whether should set cookie asynchronous or not , if onClientRequestResource is calling in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may cause deadlock More about it see {https://issuetracker.google.com/issues/36989494#c8} Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}
        返回:
        Return the data to kernel
      • setCookiesFromHeaders

        protected boolean setCookiesFromHeaders(java.util.Map<java.lang.String,java.util.List<java.lang.String>> headers,
                                                boolean executeInNewThread)
        Set cookies to webview from headers
        参数:
        headers - headers from server response
        executeInNewThread - whether execute in new thread or not
        返回:
        Set cookie success or not
      • onRequestResource

        protected java.lang.Object onRequestResource(java.lang.String url)
        When the webview initiates a main resource interception, the client invokes this method to retrieve the data
        参数:
        url - The url of this session
        返回:
        Return the data to kernel
      • onWebReady

        public boolean onWebReady(SonicDiffDataCallback diffDataCallback)
        Client will call this method to obtain the update data when the page shows the content.
        参数:
        diffDataCallback - Sonic provides the latest data to the page through this callback
        返回:
        The result
      • onClientPageFinished

        public boolean onClientPageFinished(java.lang.String url)
      • isMatchCurrentUrl

        public boolean isMatchCurrentUrl(java.lang.String url)
        Whether the incoming url matches the current url,it will ignore url parameters
        参数:
        url - The incoming url.
        返回:
        Whether the incoming url matches the current url.
      • getHeaders

        protected java.util.HashMap<java.lang.String,java.lang.String> getHeaders()
        Get header info with the original url of current session.
        返回:
        The header info.
      • getCharsetFromHeaders

        protected java.lang.String getCharsetFromHeaders()
        Get the charset from the latest response http header.
        返回:
        The charset.
      • getCharsetFromHeaders

        public java.lang.String getCharsetFromHeaders(java.util.Map<java.lang.String,java.lang.String> headers)
      • getCacheHeaders

        protected java.util.HashMap<java.lang.String,java.lang.String> getCacheHeaders()
        Get header info from local cache headers
        返回:
        The header info.
      • destroy

        public void destroy()
      • destroy

        protected void destroy(boolean force)
      • clearSessionData

        protected void clearSessionData()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionClient.html ================================================ SonicSessionClient (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionClient

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionClient


  • public abstract class SonicSessionClient
    extends java.lang.Object
    SonicSessionClient is a thin API class that delegates its public API to a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.
    • 方法概要

      所有方法 实例方法 抽象方法 具体方法 
      限定符和类型 方法和说明
      void bindSession(SonicSession session)
      Bind a sonic session to current client
      void clearHistory()
      We add this method to decoupling webview since some application may use x5 webview or others.
      void clientReady()
      Notify client is ready to accept data
      void getDiffData(SonicDiffDataCallback callback)
      The page execute a java script function to invoke a native method by javascript interface, this callback will be called when sonic has finished diff data.
      abstract void loadDataWithBaseUrl(java.lang.String baseUrl, java.lang.String data, java.lang.String mimeType, java.lang.String encoding, java.lang.String historyUrl)
      We add this method to decoupling webview since some application may use x5 webview or others.
      abstract void loadDataWithBaseUrlAndHeader(java.lang.String baseUrl, java.lang.String data, java.lang.String mimeType, java.lang.String encoding, java.lang.String historyUrl, java.util.HashMap<java.lang.String,java.lang.String> headers)
      We add this method to decoupling webview since some application may use x5 webview or others.
      abstract void loadUrl(java.lang.String url, android.os.Bundle extraData)
      We add this method to decoupling webview since some application may use x5 webview or others.
      void pageFinish(java.lang.String url)
      We need to tell the session when onPageFinished is called by WebViewClient since to make a better reload when current hit template-changed case.
      java.lang.Object requestResource(java.lang.String url)
      Webview ask the host client to intercept request, this method should be called when webview call shouldInterceptRequest.
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 构造器详细资料

      • SonicSessionClient

        public SonicSessionClient()
    • 方法详细资料

      • clientReady

        public void clientReady()
        Notify client is ready to accept data
      • requestResource

        public java.lang.Object requestResource(java.lang.String url)
        Webview ask the host client to intercept request, this method should be called when webview call shouldInterceptRequest.
        参数:
        url - The target url which need to request web response
        返回:
        The data to kernel.
      • getDiffData

        public void getDiffData(SonicDiffDataCallback callback)
        The page execute a java script function to invoke a native method by javascript interface, this callback will be called when sonic has finished diff data.
        参数:
        callback - A callback of web page
      • pageFinish

        public void pageFinish(java.lang.String url)
        We need to tell the session when onPageFinished is called by WebViewClient since to make a better reload when current hit template-changed case.
        参数:
        url - The target url which is page finished
      • bindSession

        public void bindSession(SonicSession session)
        Bind a sonic session to current client
        参数:
        session - A sonic session
      • loadUrl

        public abstract void loadUrl(java.lang.String url,
                                     android.os.Bundle extraData)
        We add this method to decoupling webview since some application may use x5 webview or others.
        参数:
        url - Url which need to load
        extraData - Extra data
      • loadDataWithBaseUrl

        public abstract void loadDataWithBaseUrl(java.lang.String baseUrl,
                                                 java.lang.String data,
                                                 java.lang.String mimeType,
                                                 java.lang.String encoding,
                                                 java.lang.String historyUrl)
        We add this method to decoupling webview since some application may use x5 webview or others.
        参数:
        baseUrl - The URL to use as the page's base URL. If null defaults to 'about:blank'.
        data - A String of data in the given encoding
        mimeType - the MIMEType of the data, e.g. 'text/html'. If null, defaults to 'text/html'.
        encoding - The encoding of the data
        historyUrl - The URL to use as the history entry. If null defaults to 'about:blank'. If non-null, this must be a valid URL.
      • loadDataWithBaseUrlAndHeader

        public abstract void loadDataWithBaseUrlAndHeader(java.lang.String baseUrl,
                                                          java.lang.String data,
                                                          java.lang.String mimeType,
                                                          java.lang.String encoding,
                                                          java.lang.String historyUrl,
                                                          java.util.HashMap<java.lang.String,java.lang.String> headers)
        We add this method to decoupling webview since some application may use x5 webview or others.
        参数:
        baseUrl - The URL to use as the page's base URL. If null defaults to 'about:blank'.
        data - A String of data in the given encoding
        mimeType - The MIMEType of the data, e.g. 'text/html'. If null, defaults to 'text/html'.
        encoding - The encoding of the data
        historyUrl - The URL to use as the history entry. If null defaults to 'about:blank'. If non-null, this must be a valid URL.
        headers - The headers
      • clearHistory

        public void clearHistory()
        We add this method to decoupling webview since some application may use x5 webview or others. When we hit template-change case, webview may load twice(first load:local cache second load:new page) when user press back button, if we do not clear history,it will return to the first load case which will make user feel unsure about the action. So we need to clear history if need.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConfig.Builder.html ================================================ SonicSessionConfig.Builder (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionConfig.Builder

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionConfig.Builder
  • 封闭类:
    SonicSessionConfig


    public static class SonicSessionConfig.Builder
    extends java.lang.Object
    Builder for SonicSessionConfig
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConfig.html ================================================ SonicSessionConfig (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionConfig

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionConfig


  • public class SonicSessionConfig
    extends java.lang.Object
    The sonicSession configurations. A sonicSession configuration describes the http(s) connection time out, the way sonicSession's id be generated and so on
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      boolean equals(java.lang.Object other) 
      • 从类继承的方法 java.lang.Object

        clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 方法详细资料

      • equals

        public boolean equals(java.lang.Object other)
        覆盖:
        equals 在类中 java.lang.Object
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html ================================================ SonicSessionConnection.SessionConnectionDefaultImpl (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionConnection.SessionConnectionDefaultImpl

    • 字段详细资料

      • connectionImpl

        protected final java.net.URLConnection connectionImpl
        A default http connection referred to by the com.tencent.sonic.sdk.SonicSession#currUrl.
    • 构造器详细资料

      • SessionConnectionDefaultImpl

        public SessionConnectionDefaultImpl(SonicSession session,
                                            android.content.Intent intent)
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnection.html ================================================ SonicSessionConnection (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionConnection

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionConnection
  • 直接已知子类:
    SonicSessionConnection.SessionConnectionDefaultImpl


    public abstract class SonicSessionConnection
    extends java.lang.Object
    The abstract class SonicSessionConnection is the superclass of all classes that represent a communications link between the application and a URL. Instances of this class can be used both to read from and to write to the resource referenced by the URL
    • 字段详细资料

      • CUSTOM_HEAD_FILED_ETAG

        public static final java.lang.String CUSTOM_HEAD_FILED_ETAG
        HTTP header:eTag.
        This header represents SHA1 value of the whole website, including template and data.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_ACCEPT_DIFF

        public static final java.lang.String CUSTOM_HEAD_FILED_ACCEPT_DIFF
        HTTP header:accept-diff.
        This header represents that client accepts data incremental scene updates or not.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_TEMPLATE_TAG

        public static final java.lang.String CUSTOM_HEAD_FILED_TEMPLATE_TAG
        HTTP header:template_tag.
        This header represents SHA1 value of the template file.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_TEMPLATE_CHANGE

        public static final java.lang.String CUSTOM_HEAD_FILED_TEMPLATE_CHANGE
        HTTP header:template_change.
        This header indicates whether the template file has changed or not.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_CACHE_OFFLINE

        public static final java.lang.String CUSTOM_HEAD_FILED_CACHE_OFFLINE
        HTTP header:cache-offline.
        This header indicates whether the website needs to be refreshed or not.
        另请参阅:
        常量字段值
      • DNS_PREFETCH_ADDRESS

        public static final java.lang.String DNS_PREFETCH_ADDRESS
        HTTP header:dns-prefetch-address
        This header represents the ip address of the server.
        Sonic Connection will use this ip to connect to server to avoid the cost time of DNS resolution.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_SDK_VERSION

        public static final java.lang.String CUSTOM_HEAD_FILED_SDK_VERSION
        HTTP Header:sdk_version.
        This header represents the version of SDK.
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_DNS_PREFETCH

        public static final java.lang.String CUSTOM_HEAD_FILED_DNS_PREFETCH
        HTTP Header:dns-prefetch.
        This header indicates that Sonic connection has used the ip represented by DNS_PREFETCH_ADDRESS
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_HTML_SHA1

        public static final java.lang.String CUSTOM_HEAD_FILED_HTML_SHA1
        HTTP header: .
        另请参阅:
        常量字段值
      • HTTP_HEAD_CSP

        public static final java.lang.String HTTP_HEAD_CSP
        HTTP Header:Content-Security-Policy.
        This header represents the HTML CSP.
        另请参阅:
        常量字段值
      • HTTP_HEAD_CSP_REPORT_ONLY

        public static final java.lang.String HTTP_HEAD_CSP_REPORT_ONLY
        HTTP Header:Content-Security-Policy-Report-Only.
        This header represents the HTML Content-Security-Policy-Report-Only.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FILED_SET_COOKIE

        public static final java.lang.String HTTP_HEAD_FILED_SET_COOKIE
        HTTP Header:Set-Cookie.
        This header represents the HTML Set-Cookie.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_CACHE_CONTROL

        public static final java.lang.String HTTP_HEAD_FIELD_CACHE_CONTROL
        HTTP Header : Cache-Control.
        This header represents the strategy of cache control.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_EXPIRES

        public static final java.lang.String HTTP_HEAD_FIELD_EXPIRES
        HTTP Header : Expires.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_PRAGMA

        public static final java.lang.String HTTP_HEAD_FIELD_PRAGMA
        HTTP 1.0 Header : Pragma.
        This old header represents the old strategy of cache control.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_CONTENT_TYPE

        public static final java.lang.String HTTP_HEAD_FIELD_CONTENT_TYPE
        HTTP Header : Content-Type.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_CONTENT_LENGTH

        public static final java.lang.String HTTP_HEAD_FIELD_CONTENT_LENGTH
        HTTP Header : Content-Length.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FIELD_COOKIE

        public static final java.lang.String HTTP_HEAD_FIELD_COOKIE
        HTTP Request Header : Cookie.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FILED_USER_AGENT

        public static final java.lang.String HTTP_HEAD_FILED_USER_AGENT
        HTTP Request Header:User-Agent.
        另请参阅:
        常量字段值
      • HTTP_HEAD_FILED_IF_NOT_MATCH

        public static final java.lang.String HTTP_HEAD_FILED_IF_NOT_MATCH
        另请参阅:
        常量字段值
      • CUSTOM_HEAD_FILED_LINK

        public static final java.lang.String CUSTOM_HEAD_FILED_LINK
        HTTP Response Header: Link.
        另请参阅:
        常量字段值
      • session

        protected final SonicSession session
        SonicSession Object used by SonicSessionConnection.
      • intent

        protected final android.content.Intent intent
        This intent saves all of the initialization param.
      • responseStream

        protected java.io.BufferedInputStream responseStream
        The input stream that reads from this open connection.
    • 构造器详细资料

      • SonicSessionConnection

        public SonicSessionConnection(SonicSession session,
                                      android.content.Intent intent)
        Constructor
        参数:
        session - The SonicSession instance
        intent - The intent
    • 方法详细资料

      • connect

        public int connect()
        Opens a communications link to the resource referenced by Sonic session
        返回:
        Returns the response code of connection
      • disconnect

        public abstract void disconnect()
        Disconnect the communications link to the resource referenced by Sonic session
      • getResponseCode

        public abstract int getResponseCode()
      • getResponseHeaderFields

        public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResponseHeaderFields()
      • getResponseHeaderField

        public abstract java.lang.String getResponseHeaderField(java.lang.String key)
        参数:
        key - the name of a header field.
        返回:
        Returns the value of the named header field.
      • getResponseStream

        public java.io.BufferedInputStream getResponseStream()
        返回:
        Returns an input stream that reads from this open connection.
      • internalConnect

        protected abstract int internalConnect()
      • internalGetResponseStream

        protected abstract java.io.BufferedInputStream internalGetResponseStream()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html ================================================ SonicSessionConnectionInterceptor (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionConnectionInterceptor

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionConnectionInterceptor
    • 构造器详细资料

      • SonicSessionConnectionInterceptor

        public SonicSessionConnectionInterceptor()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStatistics.html ================================================ SonicSessionStatistics (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionStatistics

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicSessionStatistics


  • public class SonicSessionStatistics
    extends java.lang.Object
    The Statistic model specifies the data models which are required to be used to provide the performance data described by the specific attributes in a SonicSession.
    • 字段详细资料

      • srcUrl

        public java.lang.String srcUrl
        Original url
      • cacheVerifyTime

        public long cacheVerifyTime
        The time that sonic begin verify local data
      • connectionFlowStartTime

        public long connectionFlowStartTime
        The time sonic initiate the http(s) request
      • connectionConnectTime

        public long connectionConnectTime
        The http(s) connectURLConnection.connect() response time
      • connectionRespondTime

        public long connectionRespondTime
        The http(s) getResponseCodeHttpURLConnection.getResponseCode() response time
      • connectionFlowFinishTime

        public long connectionFlowFinishTime
        Sonic flow end time
      • isDirectAddress

        public boolean isDirectAddress
        Is IP direct
      • diffDataCallbackTime

        public long diffDataCallbackTime
        The time when website try get diff data.
    • 构造器详细资料

      • SonicSessionStatistics

        public SonicSessionStatistics()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStream.Callback.html ================================================ SonicSessionStream.Callback (sdk 3.0.0 API)
com.tencent.sonic.sdk

接口 SonicSessionStream.Callback

    • 方法概要

      所有方法 实例方法 抽象方法 
      限定符和类型 方法和说明
      void onClose(boolean readComplete, java.io.ByteArrayOutputStream outputStream)
      Close callback
    • 方法详细资料

      • onClose

        void onClose(boolean readComplete,
                     java.io.ByteArrayOutputStream outputStream)
        Close callback
        参数:
        readComplete - SonicSessionStream data has read completed
        outputStream - outputStream include memStream data and netStream data
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStream.html ================================================ SonicSessionStream (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicSessionStream

  • java.lang.Object
    • java.io.InputStream
      • com.tencent.sonic.sdk.SonicSessionStream
  • 所有已实现的接口:
    java.io.Closeable, java.lang.AutoCloseable


    public class SonicSessionStream
    extends java.io.InputStream
    A SonicSessionStream obtains input bytes from a memStream and a netStream. memStreamis read data from network, netStreamis unread data from network.
    • 嵌套类概要

      嵌套类 
      限定符和类型 类和说明
      static interface  SonicSessionStream.Callback
      When SonicSessionStream close the stream will invoke the Callback
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      void close()
      Closes this input stream and releases any system resources associated with the stream and invoke the callback's onClose method
      int read()
      Reads a single byte from this stream and returns it as an integer in the range from 0 to 255.
      int read(byte[] buffer)
      Reads a byte of data from this input stream Equivalent to read(buffer, 0, buffer.length).
      int read(byte[] buffer, int byteOffset, int byteCount)
      Reads up to byteCount bytes from this stream and stores them in the byte array buffer starting at byteOffset.
      • 从类继承的方法 java.io.InputStream

        available, mark, markSupported, reset, skip
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 构造器详细资料

      • SonicSessionStream

        public SonicSessionStream(SonicSessionStream.Callback callback,
                                  java.io.ByteArrayOutputStream outputStream,
                                  java.io.BufferedInputStream netStream)
        Constructor
        参数:
        callback - Callback
        outputStream - Read data from network
        netStream - Unread data from network
    • 方法详细资料

      • close

        public void close()
                   throws java.io.IOException
        Closes this input stream and releases any system resources associated with the stream and invoke the callback's onClose method
        指定者:
        close 在接口中 java.io.Closeable
        指定者:
        close 在接口中 java.lang.AutoCloseable
        覆盖:
        close 在类中 java.io.InputStream
        抛出:
        java.io.IOException
      • read

        public int read()
                 throws java.io.IOException

        Reads a single byte from this stream and returns it as an integer in the range from 0 to 255. Returns -1 if the end of the stream has been reached. Blocks until one byte has been read, the end of the source stream is detected or an exception is thrown.

        指定者:
        read 在类中 java.io.InputStream
        抛出:
        java.io.IOException - if the stream is closed or another IOException occurs.
      • read

        public int read(@NonNull
                        byte[] buffer)
                 throws java.io.IOException
        Reads a byte of data from this input stream Equivalent to read(buffer, 0, buffer.length).
        覆盖:
        read 在类中 java.io.InputStream
        抛出:
        java.io.IOException
      • read

        public int read(@NonNull
                        byte[] buffer,
                        int byteOffset,
                        int byteCount)
                 throws java.io.IOException
        Reads up to byteCount bytes from this stream and stores them in the byte array buffer starting at byteOffset. Returns the number of bytes actually read or -1 if the end of the stream has been reached.
        覆盖:
        read 在类中 java.io.InputStream
        抛出:
        java.lang.IndexOutOfBoundsException - if byteOffset < 0 || byteCount < 0 || byteOffset + byteCount > buffer.length.
        java.io.IOException - if the stream is closed or another IOException occurs.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicUtils.html ================================================ SonicUtils (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 SonicUtils

  • java.lang.Object
    • com.tencent.sonic.sdk.SonicUtils


  • public class SonicUtils
    extends java.lang.Object
    Sonic Utils
    • 字段概要

      字段 
      限定符和类型 字段和说明
      static java.lang.String DEFAULT_CHARSET
      the default charset is UTF-8.
    • 构造器概要

      构造器 
      构造器和说明
      SonicUtils() 
    • 方法概要

      所有方法 静态方法 具体方法 
      限定符和类型 方法和说明
      static java.util.HashMap<java.lang.String,java.lang.String> getFilteredHeaders(java.util.Map<java.lang.String,java.util.List<java.lang.String>> srcHeaders)
      Get filtered headers by session id, this method will return a map of header(k-v) which will not contains "Set-Cookie", "Cache-Control", "Expires".
      static java.lang.String getMD5(java.lang.String content) 
      static java.lang.String getMime(java.lang.String url)
      Get mime type for url simply.
      static java.lang.String getSHA1(byte[] contentBytes) 
      static void log(java.lang.String tag, int level, java.lang.String message)
      Logger function
      static void removeResourceCache(java.lang.String resourceId)
      Remove a unique resource cache.
      static boolean saveResourceFiles(java.lang.String resourceName, byte[] resourceBytes, java.util.Map<java.lang.String,java.util.List<java.lang.String>> headers)
      save resource files, including resource and headers.
      static void saveSonicResourceData(java.lang.String resourceUrl, java.lang.String resourceSha1, long resourceSize)
      save resource data to database, such as resource sha1, resource size etc.
      static boolean shouldLog(int level)
      Logger function
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • DEFAULT_CHARSET

        public static final java.lang.String DEFAULT_CHARSET
        the default charset is UTF-8.
    • 构造器详细资料

      • SonicUtils

        public SonicUtils()
    • 方法详细资料

      • shouldLog

        public static boolean shouldLog(int level)
        Logger function
        参数:
        level - Level of this log,such like Log.DEBUG.
        返回:
        Should log or not
      • log

        public static void log(java.lang.String tag,
                               int level,
                               java.lang.String message)
        Logger function
        参数:
        tag - Used to identify the source of a log message. It usually identifies the class or activity where the log call occurs.
        level - Level of this log,such like Log.DEBUG.
        message - The message you would like logged.
      • saveSonicResourceData

        public static void saveSonicResourceData(java.lang.String resourceUrl,
                                                 java.lang.String resourceSha1,
                                                 long resourceSize)
        save resource data to database, such as resource sha1, resource size etc.
        参数:
        resourceUrl - the resource url
        resourceSha1 - the resource sha1
        resourceSize - the resource size
      • saveResourceFiles

        public static boolean saveResourceFiles(java.lang.String resourceName,
                                                byte[] resourceBytes,
                                                java.util.Map<java.lang.String,java.util.List<java.lang.String>> headers)
        save resource files, including resource and headers.
        参数:
        resourceName - resource file name
        resourceBytes - resource bytes content
        headers - resource headers
        返回:
        The result of save files. true if all data is saved successfully.
      • getFilteredHeaders

        public static java.util.HashMap<java.lang.String,java.lang.String> getFilteredHeaders(java.util.Map<java.lang.String,java.util.List<java.lang.String>> srcHeaders)
        Get filtered headers by session id, this method will return a map of header(k-v) which will not contains "Set-Cookie", "Cache-Control", "Expires".
        参数:
        srcHeaders - The source headers
        返回:
        The headers of sessionId
      • removeResourceCache

        public static void removeResourceCache(java.lang.String resourceId)
        Remove a unique resource cache.
        参数:
        resourceId - a unique resource id
      • getMime

        public static java.lang.String getMime(java.lang.String url)
        Get mime type for url simply. (Maybe android.webkit.MimeTypeMap.getMimeTypeFromExtension is better.)
        参数:
        url - target url
        返回:
        mime type
      • getSHA1

        public static java.lang.String getSHA1(byte[] contentBytes)
      • getMD5

        public static java.lang.String getMD5(java.lang.String content)
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/StandardSonicSession.html ================================================ StandardSonicSession (sdk 3.0.0 API)
com.tencent.sonic.sdk

类 StandardSonicSession

  • 所有已实现的接口:
    android.os.Handler.Callback


    public class StandardSonicSession
    extends SonicSession
    implements android.os.Handler.Callback
    A subclass of SonicSession. StandardSonicSession only uses the way of SonicSessionClient.loadUrl(String, Bundle) (not loadData). When client initiates a resource interception, the user can set response and header information (such as csp) for the kernel.

    See also QuickSonicSession

    • 方法详细资料

      • handleMessage

        public boolean handleMessage(android.os.Message msg)
        从类复制的说明: SonicSession
        Subclasses must implement this to receive messages.
        指定者:
        handleMessage 在接口中 android.os.Handler.Callback
        覆盖:
        handleMessage 在类中 SonicSession
      • onClientReady

        public boolean onClientReady()
        从类复制的说明: SonicSession
        Client informs sonic that it is ready. Client ready means it's webview has been initialized, can start load url or load data.
        覆盖:
        onClientReady 在类中 SonicSession
        返回:
        True if it is set for the first time
      • onWebReady

        public boolean onWebReady(SonicDiffDataCallback callback)
        从类复制的说明: SonicSession
        Client will call this method to obtain the update data when the page shows the content.
        覆盖:
        onWebReady 在类中 SonicSession
        参数:
        callback - Sonic provides the latest data to the page through this callback
        返回:
        The result
      • onRequestResource

        protected java.lang.Object onRequestResource(java.lang.String url)
        从类复制的说明: SonicSession
        When the webview initiates a main resource interception, the client invokes this method to retrieve the data
        覆盖:
        onRequestResource 在类中 SonicSession
        参数:
        url - The url of this session
        返回:
        Return the data to kernel
      • handleFlow_TemplateChange

        protected void handleFlow_TemplateChange(java.lang.String newHtml)
        Sonic will always read the new data from the server until the local page finish. If the server data is not read finished sonic will split the read and unread data into a bridgedStreamSonicSessionStream, otherwise all the read data will be encapsulated as an inputStreamByteArrayInputStream. When client initiates a resource interception, sonic will provide the bridgedStream or inputStream to the kernel.

        If need save and separate data, sonic will save the server data and separate the server data to template and data.

        指定者:
        handleFlow_TemplateChange 在类中 SonicSession
        参数:
        newHtml - new Html string from web-server
      • handleFlow_FirstLoad

        protected void handleFlow_FirstLoad()
        Sonic will always read the new data from the server until client initiates a resource interception If the server data is not read finished sonic will split the read and unread data into a bridgedStreamSonicSessionStream, otherwise all the read data will be encapsulated as an inputStreamByteArrayInputStream. When client initiates a resource interception, sonic will provide the bridgedStream or inputStream to the kernel.

        If need save and separate data, sonic will save the server data and separate the server data to template and data

        指定者:
        handleFlow_FirstLoad 在类中 SonicSession
      • handleFlow_DataUpdate

        protected void handleFlow_DataUpdate(java.lang.String serverRsp)
        Sonic obtains the difference data between the server and the local data first,then sonic will build the template and server data into html.If client did not load url before, the new html will be encapsulated as an inputStreamByteArrayInputStream,When client initiates a resource interception, sonic provides the inputStream to the kernel. If client did load url before, sonic provides the diff data to page when page obtains the diff data.
        指定者:
        handleFlow_DataUpdate 在类中 SonicSession
        参数:
        serverRsp - Server response data.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html ================================================ SonicDownloadCache.SonicResourceCache (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadCache.SonicResourceCache

    • 字段详细资料

      • TAG

        public static final java.lang.String TAG
        log filter
        另请参阅:
        常量字段值
    • 构造器详细资料

      • SonicResourceCache

        public SonicResourceCache()
    • 方法详细资料

      • getResourceCache

        public byte[] getResourceCache(java.lang.String resourceUrl)
        从类复制的说明: SonicDownloadCache
        get the cached content according to the url
        指定者:
        getResourceCache 在类中 SonicDownloadCache
        参数:
        resourceUrl - the download url
        返回:
        bytes of cached content of the url
      • getResourceCacheHeader

        public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResourceCacheHeader(java.lang.String resourceUrl)
        从类复制的说明: SonicDownloadCache
        get the cached response headers according to the url
        指定者:
        getResourceCacheHeader 在类中 SonicDownloadCache
        参数:
        resourceUrl - the download url
        返回:
        cached headers of the url
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCache.html ================================================ SonicDownloadCache (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadCache

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadCache
    • 构造器详细资料

      • SonicDownloadCache

        public SonicDownloadCache()
    • 方法详细资料

      • getResourceCache

        public abstract byte[] getResourceCache(java.lang.String url)
        get the cached content according to the url
        参数:
        url - the download url
        返回:
        bytes of cached content of the url
      • getResourceCacheHeader

        public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> getResourceCacheHeader(java.lang.String url)
        get the cached response headers according to the url
        参数:
        url - the download url
        返回:
        cached headers of the url
      • getSubResourceCache

        public static SonicDownloadCache getSubResourceCache()
        返回:
        Sub resource cache
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html ================================================ SonicDownloadCallback.SimpleDownloadCallback (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadCallback.SimpleDownloadCallback

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      void onError(int errorCode)
      notify download failed.
      void onFinish()
      notify download finish.
      void onProgress(int pro, int total)
      notify the download progress.
      void onStart()
      notify the download start.
      void onSuccess(byte[] content, java.util.Map<java.lang.String,java.util.List<java.lang.String>> rspHeaders)
      notify download success.
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCallback.html ================================================ SonicDownloadCallback (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

接口 SonicDownloadCallback

    • 方法详细资料

      • onStart

        void onStart()
        notify the download start.
      • onProgress

        void onProgress(int pro,
                        int total)
        notify the download progress.
        参数:
        pro - downloaded size
        total - total size
      • onSuccess

        void onSuccess(byte[] content,
                       java.util.Map<java.lang.String,java.util.List<java.lang.String>> rspHeaders)
        notify download success.
        参数:
        content - downloaded content bytes
        rspHeaders - http response headers
      • onError

        void onError(int errorCode)
        notify download failed.
        参数:
        errorCode - error code
      • onFinish

        void onFinish()
        notify download finish. onSuccess or onError
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html ================================================ SonicDownloadClient.DownloadTask (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadClient.DownloadTask

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
  • 封闭类:
    SonicDownloadClient


    public static class SonicDownloadClient.DownloadTask
    extends java.lang.Object
    Task which record the download info
    • 字段概要

      字段 
      限定符和类型 字段和说明
      java.util.List<SonicDownloadCallback> mCallbacks
      list of download callback
      java.lang.String mCookie
      cookie to be set in the http download request
      java.io.InputStream mInputStream
      the network stream or memory stream or the bridge stream
      java.lang.String mIpAddress
      ip address instead of host to launch a http request
      java.lang.String mResourceUrl
      url of the resource to be download
      java.util.Map<java.lang.String,java.util.List<java.lang.String>> mRspHeaders
      the download request's response headers
      java.util.concurrent.atomic.AtomicInteger mState
      the task's download state
      java.util.concurrent.atomic.AtomicBoolean mWasInterceptInvoked
      whether the task's responding resource was intercepted by kernel
      static int STATE_DOWNLOADED
      the task is in download complete state.
      static int STATE_DOWNLOADING
      the task is in downloading state.
      static int STATE_INITIATE
      download in initiate state.
      static int STATE_LOAD_FROM_CACHE
      the task is load from cache, not from network.
      static int STATE_QUEUEING
      download in queueing state.
    • 构造器概要

      构造器 
      构造器和说明
      DownloadTask() 
    • 方法概要

      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 字段详细资料

      • STATE_INITIATE

        public static final int STATE_INITIATE
        download in initiate state.
        另请参阅:
        常量字段值
      • STATE_QUEUEING

        public static final int STATE_QUEUEING
        download in queueing state.
        另请参阅:
        常量字段值
      • STATE_DOWNLOADING

        public static final int STATE_DOWNLOADING
        the task is in downloading state.
        另请参阅:
        常量字段值
      • STATE_DOWNLOADED

        public static final int STATE_DOWNLOADED
        the task is in download complete state.
        另请参阅:
        常量字段值
      • STATE_LOAD_FROM_CACHE

        public static final int STATE_LOAD_FROM_CACHE
        the task is load from cache, not from network.
        另请参阅:
        常量字段值
      • mResourceUrl

        public java.lang.String mResourceUrl
        url of the resource to be download
      • mIpAddress

        public java.lang.String mIpAddress
        ip address instead of host to launch a http request
      • mCookie

        public java.lang.String mCookie
        cookie to be set in the http download request
      • mRspHeaders

        public java.util.Map<java.lang.String,java.util.List<java.lang.String>> mRspHeaders
        the download request's response headers
      • mInputStream

        public java.io.InputStream mInputStream
        the network stream or memory stream or the bridge stream
      • mState

        public java.util.concurrent.atomic.AtomicInteger mState
        the task's download state
      • mWasInterceptInvoked

        public final java.util.concurrent.atomic.AtomicBoolean mWasInterceptInvoked
        whether the task's responding resource was intercepted by kernel
    • 构造器详细资料

      • DownloadTask

        public DownloadTask()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html ================================================ SonicDownloadClient.SonicDownloadConnection (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadClient.SonicDownloadConnection

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadClient.SonicDownloadConnection
  • 封闭类:
    SonicDownloadClient


    public class SonicDownloadClient.SonicDownloadConnection
    extends java.lang.Object
    • 方法概要

      所有方法 实例方法 具体方法 
      限定符和类型 方法和说明
      void disconnect() 
      • 从类继承的方法 java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 构造器详细资料

      • SonicDownloadConnection

        public SonicDownloadConnection(java.lang.String url)
    • 方法详细资料

      • disconnect

        public void disconnect()
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html ================================================ SonicDownloadClient.SubResourceDownloadCallback (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadClient.SubResourceDownloadCallback

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.html ================================================ SonicDownloadClient (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadClient

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadClient
    • 字段详细资料

      • TAG

        public static final java.lang.String TAG
        log filter
        另请参阅:
        常量字段值
    • 方法详细资料

      • download

        public int download()
        download the resource and notify download progress
        返回:
        response code
      • onClose

        public void onClose(boolean readComplete,
                            java.io.ByteArrayOutputStream outputStream)
        从接口复制的说明: SonicSessionStream.Callback
        Close callback
        指定者:
        onClose 在接口中 SonicSessionStream.Callback
        参数:
        readComplete - SonicSessionStream data has read completed
        outputStream - outputStream include memStream data and netStream data
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadEngine.html ================================================ SonicDownloadEngine (sdk 3.0.0 API)
com.tencent.sonic.sdk.download

类 SonicDownloadEngine

  • java.lang.Object
    • com.tencent.sonic.sdk.download.SonicDownloadEngine
  • 所有已实现的接口:
    android.os.Handler.Callback


    public class SonicDownloadEngine
    extends java.lang.Object
    implements android.os.Handler.Callback
    an download initiator
    • 字段详细资料

      • TAG

        public static final java.lang.String TAG
        log filter
        另请参阅:
        常量字段值
    • 方法详细资料

      • handleMessage

        public boolean handleMessage(android.os.Message msg)
        指定者:
        handleMessage 在接口中 android.os.Handler.Callback
      • download

        public SonicDownloadClient.DownloadTask download(java.lang.String resourceUrl,
                                                         java.lang.String ipAddress,
                                                         java.lang.String cookie,
                                                         SonicDownloadCallback callback)
        start downloading one resource. if the responding cache exists and isn't expire, will use the cache directly and won't launch a http request; if the number of downloading tasks is bigger than config, the task will be delayed before downloading pool is free.
        参数:
        resourceUrl - the resource's url
        ipAddress - if dns prefetch the ip address, will use the ip instead of host
        cookie - set the cookie for the download http request
        callback - a callback used for notify the download progress and result
        返回:
        the download task info
      • onRequestSubResource

        public java.lang.Object onRequestSubResource(java.lang.String url,
                                                     SonicSession session)
        When the webview initiates a sub resource interception, the client invokes this method to retrieve the data
        参数:
        url - The url of sub resource
        session - current sonic session
        返回:
        Return the data to kernel
      • addSubResourcePreloadTask

        public void addSubResourcePreloadTask(java.util.List<java.lang.String> preloadLinks)
        preload the sub resource in the "sonic-link" header.
        参数:
        preloadLinks - The links which need to be preloaded.
================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-frame.html ================================================ com.tencent.sonic.sdk.download (sdk 3.0.0 API)

com.tencent.sonic.sdk.download

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-summary.html ================================================ com.tencent.sonic.sdk.download (sdk 3.0.0 API)

程序包 com.tencent.sonic.sdk.download

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-tree.html ================================================ com.tencent.sonic.sdk.download 类分层结构 (sdk 3.0.0 API)

程序包com.tencent.sonic.sdk.download的分层结构

程序包分层结构:

类分层结构

接口分层结构

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-frame.html ================================================ com.tencent.sonic.sdk (sdk 3.0.0 API)

com.tencent.sonic.sdk

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-summary.html ================================================ com.tencent.sonic.sdk (sdk 3.0.0 API)

程序包 com.tencent.sonic.sdk

================================================ FILE: sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-tree.html ================================================ com.tencent.sonic.sdk 类分层结构 (sdk 3.0.0 API)

程序包com.tencent.sonic.sdk的分层结构

程序包分层结构:

类分层结构

接口分层结构

================================================ FILE: sonic-android/docs/javadoc/constant-values.html ================================================ 常量字段值 (sdk 3.0.0 API)

常量字段值

目录

com.tencent.*

================================================ FILE: sonic-android/docs/javadoc/deprecated-list.html ================================================ 已过时的列表 (sdk 3.0.0 API)

已过时的 API

目录

================================================ FILE: sonic-android/docs/javadoc/help-doc.html ================================================ API 帮助 (sdk 3.0.0 API)

此 API 文档的组织方式

此 API (应用程序编程接口) 文档包含对应于导航栏中的项目的页面, 如下所述。
  • 概览

    概览 页面是此 API 文档的首页, 提供了所有程序包的列表及其概要。此页面也可能包含这些程序包的总体说明。

  • 程序包

    每个程序包都有一个页面, 其中包含它的类和接口的列表及其概要。此页面可以包含六个类别:

    • 接口 (斜体)
    • 枚举
    • 异常错误
    • 错误
    • 注释类型
  • 类/接口

    每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:

    • 类继承图
    • 直接子类
    • 所有已知子接口
    • 所有已知实现类
    • 类/接口声明
    • 类/接口说明
    • 嵌套类概要
    • 字段概要
    • 构造器概要
    • 方法概要
    • 字段详细资料
    • 构造器详细资料
    • 方法详细资料

    每个概要条目都包含该项目的详细说明的第一句。概要条目按字母顺序排列, 而详细说明则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。

  • 注释类型

    每个注释类型都有各自的页面, 其中包含以下部分:

    • 注释类型声明
    • 注释类型说明
    • 必需元素概要
    • 可选元素概要
    • 元素详细资料
  • 枚举

    每个枚举都有各自的页面, 其中包含以下部分:

    • 枚举声明
    • 枚举说明
    • 枚举常量概要
    • 枚举常量详细资料
  • 树 (类分层结构)

    对于所有程序包, 有一个类分层结构页面, 以及每个程序包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从java.lang.Object开始, 按继承结构对类进行排列。接口不从java.lang.Object继承。

    • 查看“概览”页面时, 单击 "树" 将显示所有程序包的分层结构。
    • 查看特定程序包, 类或接口页面时, 单击 "树" 将仅显示该程序包的分层结构。
  • 已过时的 API

    已过时的 API 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API, 所以建议不要使用已过时的 API。在将来的实现过程中, 可能会删除已过时的 API。

  • 索引

    索引 包含按字母顺序排列的所有类, 接口, 构造器, 方法和字段的列表。

  • 上一个/下一个

    这些链接使您可以转至下一个或上一个类, 接口, 程序包或相关页面。

  • 框架/无框架

    这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。

  • 所有类

    所有类链接显示所有类和接口 (除了非静态嵌套类型)。

  • 序列化表格

    每个可序列化或可外部化的类都有其序列化字段和方法的说明。此信息对重新实现者有用, 而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接, 但您可以通过下列方式获取此信息: 转至任何序列化类, 然后单击类说明的 "另请参阅" 部分中的 "序列化表格"。

  • 常量字段值

    常量字段值页面列出了静态最终字段及其值。

此帮助文件适用于使用标准 doclet 生成的 API 文档。
================================================ FILE: sonic-android/docs/javadoc/index-all.html ================================================ 索引 (sdk 3.0.0 API)
A B C D E F G H I L M N O P Q R S T V W 

A

addSessionCallback(SonicSessionCallback) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
addSessionStateChangedCallback(SonicSession.Callback) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
addSubResourcePreloadTask(List<String>) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadEngine
preload the sub resource in the "sonic-link" header.

B

bindClient(SonicSessionClient) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
bindSession(SonicSession) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
Bind a sonic session to current client
build() - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
build() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
Builder() - 类 的构造器com.tencent.sonic.sdk.SonicConfig.Builder
 
Builder() - 类 的构造器com.tencent.sonic.sdk.SonicSessionConfig.Builder
 

C

cachedResponseHeaders - 类 中的变量com.tencent.sonic.sdk.SonicServer
Cached response headers which contains response headers from server and custom response headers from com.tencent.sonic.sdk.SonicSessionConfig
cacheVerifyTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
The time that sonic begin verify local data
callback(String) - 接口 中的方法com.tencent.sonic.sdk.SonicDiffDataCallback
Called when sonic processes the local data and the server data.
canDestroy() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
CHROME_FILE_THREAD - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Name of chrome file thread
cleanCache() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
Removes all of the cache from SonicEngine.preloadSessionPool and deletes file caches from SDCard.
clearHistory() - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
We add this method to decoupling webview since some application may use x5 webview or others.
clearSessionData() - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
clearSessionData() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
CLIENT_MSG_NOTIFY_RESULT - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The message to record sonic mode.
CLIENT_MSG_ON_WEB_READY - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The message of page ready, its means page want to get the latest session data.
clientIsReady - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether the client is ready.
clientIsReload - 类 中的变量com.tencent.sonic.sdk.SonicSession
Indicate current session is reload or not.
clientReady() - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
Notify client is ready to accept data
close() - 类 中的方法com.tencent.sonic.sdk.SonicSessionStream
Closes this input stream and releases any system resources associated with the stream and invoke the callback's onClose method
com.tencent.sonic.sdk - 程序包 com.tencent.sonic.sdk
 
com.tencent.sonic.sdk.download - 程序包 com.tencent.sonic.sdk.download
 
COMMON_MSG_BEGIN - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
COMMON_MSG_END - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
config - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
connect() - 类 中的方法com.tencent.sonic.sdk.SonicServer
Opens a communications link to the resource referenced by Sonic session.
connect() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
Opens a communications link to the resource referenced by Sonic session
connectionConnectTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
The http(s) connectURLConnection.connect() response time
connectionFlowFinishTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
Sonic flow end time
connectionFlowStartTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
The time sonic initiate the http(s) request
connectionImpl - 类 中的变量com.tencent.sonic.sdk.SonicServer
A session connection implement.
connectionImpl - 类 中的变量com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
A default http connection referred to by the com.tencent.sonic.sdk.SonicSession#currUrl.
connectionRespondTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
The http(s) getResponseCodeHttpURLConnection.getResponseCode() response time
context - 类 中的变量com.tencent.sonic.sdk.SonicRuntime
A context for this runtime, it's expected to be ApplicationContext
CREATE_TABLE_SQL - 类 中的静态变量com.tencent.sonic.sdk.SonicResourceDataHelper
The create table sql
createConnection() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
createConnectionIntent(SonicDataHelper.SessionData) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
createdTime - 类 中的变量com.tencent.sonic.sdk.SonicSession
The time of current session created.
createInstance(SonicRuntime, SonicConfig) - 类 中的静态方法com.tencent.sonic.sdk.SonicEngine
Create SonicEngine instance.
createSession(String, SonicSessionConfig) - 类 中的方法com.tencent.sonic.sdk.SonicEngine
 
createWebResourceResponse(String, String, InputStream, Map<String, String>) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
We add this method to decoupling webview since some application may use x5 webview or others.
CUSTOM_HEAD_FILED_ACCEPT_DIFF - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:accept-diff.
CUSTOM_HEAD_FILED_CACHE_OFFLINE - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:cache-offline.
CUSTOM_HEAD_FILED_DNS_PREFETCH - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header:dns-prefetch.
CUSTOM_HEAD_FILED_ETAG - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:eTag.
CUSTOM_HEAD_FILED_HTML_SHA1 - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header: .
CUSTOM_HEAD_FILED_LINK - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Response Header: Link.
CUSTOM_HEAD_FILED_SDK_VERSION - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header:sdk_version.
CUSTOM_HEAD_FILED_TEMPLATE_CHANGE - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:template_change.
CUSTOM_HEAD_FILED_TEMPLATE_TAG - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:template_tag.

D

DATA_UPDATE_BUNDLE_PARAMS_DIFF - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
dataString - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
DEFAULT_CHARSET - 类 中的静态变量com.tencent.sonic.sdk.SonicUtils
the default charset is UTF-8.
destroy() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
destroy(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
diffDataCallback - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
diffDataCallbackTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
The time when website try get diff data.
disconnect() - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient.SonicDownloadConnection
 
disconnect() - 类 中的方法com.tencent.sonic.sdk.SonicServer
Disconnect the communications link to the resource referenced by Sonic session
disconnect() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
Disconnect the communications link to the resource referenced by Sonic session
disconnect() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
DNS_PREFETCH_ADDRESS - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP header:dns-prefetch-address
This header represents the ip address of the server.
doSaveSonicCache(SonicServer, String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
download() - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient
download the resource and notify download progress
download(String, String, String, SonicDownloadCallback) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadEngine
start downloading one resource.
DownloadTask() - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
 

E

equals(Object) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig
 
ERROR_CODE_BUILD_HTML_ERROR - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Build template and data to html failed
ERROR_CODE_CONNECT_IOE - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Http(s) connection error : IO Exception
ERROR_CODE_CONNECT_NPE - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Http(s) connection error : nullPointer in native
ERROR_CODE_CONNECT_TOE - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Http(s) connection error : time out
ERROR_CODE_DATA_VERIFY_FAIL - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Verify local file failed
ERROR_CODE_MAKE_DIR_ERROR - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Failed to create sonic directory
ERROR_CODE_MERGE_DIFF_DATA_FAIL - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Obtain difference data between server and local data failed
ERROR_CODE_SERVER_DATA_EXCEPTION - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Server data exception
ERROR_CODE_SPLIT_HTML_FAIL - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Separate html to template and data failed
ERROR_CODE_SUCCESS - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Success
ERROR_CODE_UNKNOWN - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Unknown
ERROR_CODE_WRITE_FILE_FAIL - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
File save failed
expiredTime - 类 中的变量com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
Indicates when local resource cache is expired.

F

FILE_THREAD_MSG_BEGIN - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The message of saving sonic cache while server close.
FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The message of saving sonic cache while session finish.
fileHandler - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
fileHandlerThread - 类 中的静态变量com.tencent.sonic.sdk.SonicRuntime
This handle thread use to save sonic cache.
finalMode - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
finalResultCode - 类 中的变量com.tencent.sonic.sdk.SonicSession
Sonic final mode.

G

getAllResourceDataColumn() - 类 中的静态方法com.tencent.sonic.sdk.SonicResourceDataHelper
 
getCacheData(SonicSession) - 类 中的方法com.tencent.sonic.sdk.SonicCacheInterceptor
 
getCacheHeaders() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Get header info from local cache headers
getCharsetFromHeaders() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Get the charset from the latest response http header.
getCharsetFromHeaders(Map<String, String>) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getConfig() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
 
getConnection(SonicSession, Intent) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnectionInterceptor
 
getContext() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
 
getCookie(String) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Get cookies of the input url, this method will be called before sonic session make a session connection to request data.
getCurrentUrl() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getCurrentUserAccount() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Get the current user account, this method will be called when makeSessionId's params is account related.
getDiffData(SonicDiffDataCallback) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
The page execute a java script function to invoke a native method by javascript interface, this callback will be called when sonic has finished diff data.
getFileThreadLooper() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Return the looper of HandleThread which use to save sonic cache.
getFilteredHeaders(Map<String, List<String>>) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
Get filtered headers by session id, this method will return a map of header(k-v) which will not contains "Set-Cookie", "Cache-Control", "Expires".
getFinalResultCode() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getHeaderFromLocalCache(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicFileUtils
Get headers from local cache file
getHeaders() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Get header info with the original url of current session.
getHostDirectAddress(String) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Get the direct address of a url(host),format as[ip:port],the default http port is 80 and 443 for https.
getInstance() - 类 中的静态方法com.tencent.sonic.sdk.SonicDBHelper
 
getInstance() - 类 中的静态方法com.tencent.sonic.sdk.SonicEngine
Returns a SonicEngine instance Make sure SonicEngine.createInstance(SonicRuntime, SonicConfig) has been called.
getMD5(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
 
getMime(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
Get mime type for url simply.
getQueryParameterNames(Uri) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Returns a set of the unique names of all query parameters.
getResourceCache(String) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCache
get the cached content according to the url
getResourceCache(String) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache
 
getResourceCacheHeader(String) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCache
get the cached response headers according to the url
getResourceCacheHeader(String) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache
 
getResourceData(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicResourceDataHelper
Get sonic ResourceData by unique resource id
getResponseCode() - 类 中的方法com.tencent.sonic.sdk.SonicServer
 
getResponseCode() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
getResponseCode() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
getResponseData(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicServer
Return current cached server response data.
getResponseHeaderField(String) - 类 中的方法com.tencent.sonic.sdk.SonicServer
 
getResponseHeaderField(String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
getResponseHeaderField(String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
getResponseHeaderFields() - 类 中的方法com.tencent.sonic.sdk.SonicServer
return response headers which contains response headers from server and custom response headers from com.tencent.sonic.sdk.SonicSessionConfig note: server response headers have high priority than custom headers!
getResponseHeaderFields() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
getResponseHeaderFields() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
getResponseStream(AtomicBoolean) - 类 中的方法com.tencent.sonic.sdk.SonicServer
Read all of data from SonicSessionConnection.getResponseStream() into byte array output stream outputStream until breakCondition is true when breakCondition is not null.
getResponseStream() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
getRuntime() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
 
getSessionClient() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getSHA1(byte[]) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
 
getSonicCacheDir() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.
getSonicResourceCacheDir() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
The resource cache root dir which resource cache will be storage.
getSonicResourceHeaderPath(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicFileUtils
 
getSonicResourcePath(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicFileUtils
 
getSonicSessionConnection(SonicSession, Intent) - 类 中的静态方法com.tencent.sonic.sdk.SonicSessionConnectionInterceptor
 
getSonicSharedPreferences() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
get SharedPreferences of sonic.
getSrcResultCode() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getSrcResultCode() - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
getStatistics() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
getSubResourceCache() - 类 中的静态方法com.tencent.sonic.sdk.download.SonicDownloadCache
 
getTemplate() - 类 中的方法com.tencent.sonic.sdk.SonicServer
If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.
getUpdatedData() - 类 中的方法com.tencent.sonic.sdk.SonicServer
If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.
getUserAgent() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Get user agent of current runtime, this method will be called before sonic session make a session connection to request data.

H

handleFlow_Connection(boolean, SonicDataHelper.SessionData) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Initiate a network request to obtain server data.
handleFlow_DataUpdate(String) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
In this case sonic obtains the difference data between the server and the local data first,then sonic will build the template and server data into html, then send a CLIENT_CORE_MSG_DATA_UPDATE message.
handleFlow_DataUpdate(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
handleFlow_DataUpdate(String) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
Sonic obtains the difference data between the server and the local data first,then sonic will build the template and server data into html.If client did not load url before, the new html will be encapsulated as an inputStreamByteArrayInputStream,When client initiates a resource interception, sonic provides the inputStream to the kernel.
handleFlow_FirstLoad() - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
In this case sonic will always read the new data from the server until the client initiates a resource interception.
handleFlow_FirstLoad() - 类 中的方法com.tencent.sonic.sdk.SonicSession
handleFlow_FirstLoad() - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
Sonic will always read the new data from the server until client initiates a resource interception If the server data is not read finished sonic will split the read and unread data into a bridgedStreamSonicSessionStream, otherwise all the read data will be encapsulated as an inputStreamByteArrayInputStream.
handleFlow_HttpError(int) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
handleFlow_HttpError(int) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
handleFlow_HttpError(int) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
handleFlow_LoadLocalCache(String) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
Handle load local cache of html if exist.
handleFlow_LoadLocalCache(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
handleFlow_LoadLocalCache(String) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
handleFlow_NotModified() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
handleFlow_ServiceUnavailable() - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
handleFlow_ServiceUnavailable() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
handleFlow_ServiceUnavailable() - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
handleFlow_TemplateChange(String) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
In this case sonic will always read the new data from the server until the local page finish.
handleFlow_TemplateChange(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
handleFlow_TemplateChange(String) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
Sonic will always read the new data from the server until the local page finish.
handleMessage(Message) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadEngine
 
handleMessage(Message) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
handleMessage(Message) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Subclasses must implement this to receive messages.
handleMessage(Message) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
HTTP_HEAD_CSP - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header:Content-Security-Policy.
HTTP_HEAD_CSP_REPORT_ONLY - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header:Content-Security-Policy-Report-Only.
HTTP_HEAD_FIELD_CACHE_CONTROL - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header : Cache-Control.
HTTP_HEAD_FIELD_CONTENT_LENGTH - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header : Content-Length.
HTTP_HEAD_FIELD_CONTENT_TYPE - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header : Content-Type.
HTTP_HEAD_FIELD_COOKIE - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Request Header : Cookie.
HTTP_HEAD_FIELD_EXPIRES - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header : Expires.
HTTP_HEAD_FIELD_PRAGMA - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP 1.0 Header : Pragma.
HTTP_HEAD_FILED_IF_NOT_MATCH - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
 
HTTP_HEAD_FILED_SET_COOKIE - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Header:Set-Cookie.
HTTP_HEAD_FILED_USER_AGENT - 类 中的静态变量com.tencent.sonic.sdk.SonicSessionConnection
HTTP Request Header:User-Agent.

I

id - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
initConnection(URLConnection) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
initSonicDB() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
Init sonic DB which will upgrade to new version of database.
intent - 类 中的变量com.tencent.sonic.sdk.SonicSession
This intent saves all of the initialization param.
intent - 类 中的变量com.tencent.sonic.sdk.SonicSessionConnection
This intent saves all of the initialization param.
internalConnect() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
internalConnect() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
internalGetResponseStream() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection
 
internalGetResponseStream() - 类 中的方法com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
isDestroyedOrWaitingForDestroy() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
isDirectAddress - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
Is IP direct
isGetInstanceAllowed() - 类 中的静态方法com.tencent.sonic.sdk.SonicEngine
Check if SonicEngine.getInstance() is ready or not.
isMatchCurrentUrl(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Whether the incoming url matches the current url,it will ignore url parameters
isNetworkValid() - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
This method is used to judge is network valid or not
isPreload - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether current session is preload.
isPreload() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
isSonicAvailable() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
Whether Sonic Service is available or not
isSonicUrl(String) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
This method is used to judge the input url is support sonic or not, when this method return true, it means it's allow to create a sonic session for this url.
isUpgrading() - 类 中的方法com.tencent.sonic.sdk.SonicDBHelper
Indicates whether is upgrading or not.
isWaitingForDestroy - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether the session is waiting for destroy.
isWaitingForSaveFile - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether it is waiting for the file to be saved.
isWaitingForSessionThread - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether the session is waiting for data.

L

loadDataWithBaseUrl(String, String, String, String, String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
We add this method to decoupling webview since some application may use x5 webview or others.
loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap<String, String>) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
We add this method to decoupling webview since some application may use x5 webview or others.
loadUrl(String, Bundle) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
We add this method to decoupling webview since some application may use x5 webview or others.
log(String, int, String) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
 
log(String, int, String) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
Logger function

M

mainHandler - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
makeSessionId(String, boolean) - 类 中的静态方法com.tencent.sonic.sdk.SonicEngine
Create session ID
makeSessionId(String, boolean) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Make a unique session id for the url, it can be account related.
mCallbacks - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
list of download callback
mCookie - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
cookie to be set in the http download request
mInputStream - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the network stream or memory stream or the bridge stream
mIpAddress - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
ip address instead of host to launch a http request
mResourceUrl - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
url of the resource to be download
mRspHeaders - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the download request's response headers
mState - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the task's download state
mWasInterceptInvoked - 类 中的变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
whether the task's responding resource was intercepted by kernel

N

next() - 类 中的方法com.tencent.sonic.sdk.SonicCacheInterceptor
 
notifyError(SonicSessionClient, String, int) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Notify error for host application to do report or statics
notifyStateChange(int, int, Bundle) - 类 中的方法com.tencent.sonic.sdk.SonicSession
When the session state changes, notify the listeners.

O

OFFLINE_MODE_FALSE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The value of "cache-offline" in http(s) response headers.
OFFLINE_MODE_HTTP - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The value of "cache-offline" in http(s) response headers.
OFFLINE_MODE_STORE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The value of "cache-offline" in http(s) response headers.
OFFLINE_MODE_TRUE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The value of "cache-offline" in http(s) response headers.
onClientPageFinished(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
onClientReady() - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
onClientReady() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Client informs sonic that it is ready.
onClientReady() - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
onClientRequestResource(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
When the webview initiates a resource interception, the client invokes the method to retrieve the data
onClose(boolean, ByteArrayOutputStream) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient
 
onClose(boolean, ByteArrayOutputStream) - 类 中的方法com.tencent.sonic.sdk.SonicServer
 
onClose(boolean, ByteArrayOutputStream) - 接口 中的方法com.tencent.sonic.sdk.SonicSessionStream.Callback
Close callback
onCreate(SQLiteDatabase) - 类 中的方法com.tencent.sonic.sdk.SonicDBHelper
Called when the database is created for the first time.
onError(int) - 接口 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback
notify download failed.
onError(int) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
onError(int) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient.SubResourceDownloadCallback
 
onFinish() - 接口 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback
notify download finish.
onFinish() - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
onProgress(int, int) - 接口 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback
notify the download progress.
onProgress(int, int) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
onRequestResource(String) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
onRequestResource(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
When the webview initiates a main resource interception, the client invokes this method to retrieve the data
onRequestResource(String) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
onRequestSubResource(String, SonicSession) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadEngine
When the webview initiates a sub resource interception, the client invokes this method to retrieve the data
onServerClosed(SonicServer, boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSession
If the kernel obtain inputStream from a SonicSessionStream, the inputStream will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream close.
onSessionStateChange(SonicSession, int, int, Bundle) - 接口 中的方法com.tencent.sonic.sdk.SonicSession.Callback
When the session's state changes, this method will be invoked.
onStart() - 接口 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback
notify the download start.
onStart() - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
onStart() - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient.SubResourceDownloadCallback
 
onSuccess(byte[], Map<String, List<String>>) - 接口 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback
notify download success.
onSuccess(byte[], Map<String, List<String>>) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
onSuccess(byte[], Map<String, List<String>>) - 类 中的方法com.tencent.sonic.sdk.download.SonicDownloadClient.SubResourceDownloadCallback
 
onUpgrade(SQLiteDatabase, int, int) - 类 中的方法com.tencent.sonic.sdk.SonicDBHelper
 
onWebReady(SonicDiffDataCallback) - 类 中的方法com.tencent.sonic.sdk.QuickSonicSession
 
onWebReady(SonicDiffDataCallback) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Client will call this method to obtain the update data when the page shows the content.
onWebReady(SonicDiffDataCallback) - 类 中的方法com.tencent.sonic.sdk.StandardSonicSession
 
originalMode - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
Sonic original modeSonicSession.srcResultCode

P

pageFinish(String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
We need to tell the session when onPageFinished is called by WebViewClient since to make a better reload when current hit template-changed case.
pendingDiffData - 类 中的变量com.tencent.sonic.sdk.SonicSession
The difference data between local and server data.
pendingWebResourceStream - 类 中的变量com.tencent.sonic.sdk.SonicSession
The response for client interception.
postForceDestroyIfNeed() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Destroy the session if it is waiting for destroy and it is can be destroyed.
postTaskToMainThread(Runnable, long) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Post a task in main thread
postTaskToSaveSonicCache(String) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
postTaskToSessionThread(Runnable) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Post a task to session thread(a high priority thread is better)
postTaskToThread(Runnable, long) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Post a task to the thread(a io thread is better) which used to separate template and data.
preCreateSession(String, SonicSessionConfig) - 类 中的方法com.tencent.sonic.sdk.SonicEngine
This method will preCreate sonic session .
preloadLinks - 类 中的变量com.tencent.sonic.sdk.SonicSession
 

Q

QuickSonicSession - com.tencent.sonic.sdk中的类
A subclass of SonicSession.

R

read() - 类 中的方法com.tencent.sonic.sdk.SonicSessionStream
Reads a single byte from this stream and returns it as an integer in the range from 0 to 255.
read(byte[]) - 类 中的方法com.tencent.sonic.sdk.SonicSessionStream
Reads a byte of data from this input stream Equivalent to read(buffer, 0, buffer.length).
read(byte[], int, int) - 类 中的方法com.tencent.sonic.sdk.SonicSessionStream
Reads up to byteCount bytes from this stream and stores them in the byte array buffer starting at byteOffset.
readFileToBytes(File) - 类 中的静态方法com.tencent.sonic.sdk.SonicFileUtils
 
refresh() - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
removeResourceCache(String) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
Remove a unique resource cache.
removeSessionCache(String) - 类 中的方法com.tencent.sonic.sdk.SonicEngine
Removes the sessionId and its corresponding SonicSession from SonicEngine.preloadSessionPool.
removeSessionCallback(SonicSessionCallback) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
removeSessionStateChangedCallback(SonicSession.Callback) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 
requestIntent - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
requestResource(String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionClient
Webview ask the host client to intercept request, this method should be called when webview call shouldInterceptRequest.
reset() - 类 中的方法com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
Reset data
RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Resource Intercept State : intercepting in file thread
RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Resource Intercept State : intercepting in other thread(may be IOThread or other else)
RESOURCE_INTERCEPT_STATE_NONE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Resource Intercept State : none
ResourceData() - 类 的构造器com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
 
resourceDownloaderEngine - 类 中的变量com.tencent.sonic.sdk.SonicSession
Sonic sub resource downloader
resourceInterceptState - 类 中的变量com.tencent.sonic.sdk.SonicSession
Resource intercept state, include RESOURCE_INTERCEPT_STATE_NONE, RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD, RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD More about it at {https://codereview.chromium.org/1350553005/#ps20001}
resourceSha1 - 类 中的变量com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
The sha1 of resource
resourceSize - 类 中的变量com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData
The size of resource
responseCode - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
responseStream - 类 中的变量com.tencent.sonic.sdk.SonicSessionConnection
The input stream that reads from this open connection.

S

saveResourceFiles(String, byte[], Map<String, List<String>>) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
save resource files, including resource and headers.
saveSonicResourceData(String, String, long) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
save resource data to database, such as resource sha1, resource size etc.
separateTemplateAndData() - 类 中的方法com.tencent.sonic.sdk.SonicServer
 
server - 类 中的变量com.tencent.sonic.sdk.SonicSession
Sonic server
serverRsp - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
session - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
session - 类 中的变量com.tencent.sonic.sdk.SonicSessionConnection
SonicSession Object used by SonicSessionConnection.
SESSION_MODE_DEFAULT - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
SonicSession mode : StandardSonicSession
SESSION_MODE_QUICK - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
SonicSession mode : QuickSonicSession
SESSION_MSG_FORCE_DESTROY - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The message of forced to destroy the session.
sessionCallbackList - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
sessionClient - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
SessionConnectionDefaultImpl(SonicSession, Intent) - 类 的构造器com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl
 
sessionState - 类 中的变量com.tencent.sonic.sdk.SonicSession
Session state, include STATE_NONE, STATE_RUNNING, STATE_READY and STATE_DESTROY.
setAcceptDiff(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setAutoInitDBWhenCreate(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setAutoStartWhenCreate(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setCacheCheckTimeInterval(long) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setCacheInterceptor(SonicCacheInterceptor) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setCacheMaxSize(long) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setCacheVerifyWithSha1(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setConnectionInterceptor(SonicSessionConnectionInterceptor) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setConnectTimeoutMillis(int) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setCookie(String, List<String>) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Set cookies to webview after session connection response with cookies in it's headers.
setCookiesFromHeaders(Map<String, List<String>>, boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Set cookies to webview from headers
setCustomRequestHeaders(Map<String, String>) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setCustomResponseHeaders(Map<String, String>) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setGetCookieWhenSessionCreate(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setIsAccountRelated(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setMaxNumOfDownloadingTasks(int) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setMaxPreloadSessionCount(int) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setPreloadSessionExpiredTimeMillis(long) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setReadBufferSize(int) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setReadTimeoutMillis(int) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setReloadInBadNetwork(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setResourceCacheMaxSize(long) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setResult(int, int, boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSession
Record the sonic mode, notify the result to page if necessary.
setSessionMode(int) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setSonicCacheMaxAge(int) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setSupportCacheControl(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setSupportLocalServer(boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
setUnavailableTime(long) - 类 中的方法com.tencent.sonic.sdk.SonicConfig.Builder
 
setUseSonicCacheInBadNetworkToastMessage(String) - 类 中的方法com.tencent.sonic.sdk.SonicSessionConfig.Builder
 
shouldLog(int) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Logger function
shouldLog(int) - 类 中的静态方法com.tencent.sonic.sdk.SonicUtils
Logger function
shouldSetCookieAsynchronous() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Whether should set cookie asynchronous or not , if onClientRequestResource is calling in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may cause deadlock More about it see {https://issuetracker.google.com/issues/36989494#c8} Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}
showToast(CharSequence, int) - 类 中的方法com.tencent.sonic.sdk.SonicRuntime
Show toast
sId - 类 中的变量com.tencent.sonic.sdk.SonicSession
The integer id of current session
SimpleDownloadCallback() - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback
 
sNextSessionLogId - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Log id
SONIC_MAX_NUM_OF_DOWNLOADING_TASK - 类 中的变量com.tencent.sonic.sdk.SonicConfig
The max number of tasks which is downloading in the same time.
SONIC_PARAMETER_NAME_PREFIX - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
Sonic parameter prefix
SONIC_REMAIN_PARAMETER_NAMES - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
This parameter in url will be as part of session id,and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.
SONIC_REMAIN_PARAMETER_SPLIT_CHAR - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
 
SONIC_RESULT_CODE_DATA_UPDATE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Sonic mode : data update.
SONIC_RESULT_CODE_FIRST_LOAD - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Sonic mode : first load.
SONIC_RESULT_CODE_HIT_CACHE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Sonic mode : 304.
SONIC_RESULT_CODE_TEMPLATE_CHANGE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Sonic mode : template change.
SONIC_RESULT_CODE_UNKNOWN - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Sonic mode : unknown.
SONIC_SDK_LOG_PREFIX - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
SonicSDK log prefix
SONIC_VERSION_NUM - 类 中的静态变量com.tencent.sonic.sdk.SonicConstants
SonicSDK version
SonicCacheInterceptor - com.tencent.sonic.sdk中的类
SonicCacheInterceptor provide local data.
SonicCacheInterceptor(SonicCacheInterceptor) - 类 的构造器com.tencent.sonic.sdk.SonicCacheInterceptor
 
SonicConfig - com.tencent.sonic.sdk中的类
Sonic global config
SonicConfig.Builder - com.tencent.sonic.sdk中的类
Builder for SonicConfig
SonicConstants - com.tencent.sonic.sdk中的类
Sonic constants
SonicConstants() - 类 的构造器com.tencent.sonic.sdk.SonicConstants
 
SonicDBHelper - com.tencent.sonic.sdk中的类
SonicDBHelper interacts with the database, such as managing database creation and the version management.
SonicDiffDataCallback - com.tencent.sonic.sdk中的接口
This interface is used to call the difference data between local and server data to the client.
SonicDownloadCache - com.tencent.sonic.sdk.download中的类
Sonic download cache manager
SonicDownloadCache() - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadCache
 
SonicDownloadCache.SonicResourceCache - com.tencent.sonic.sdk.download中的类
An sub resource cache implementation SonicDownloadCache
SonicDownloadCallback - com.tencent.sonic.sdk.download中的接口
download callback.
SonicDownloadCallback.SimpleDownloadCallback - com.tencent.sonic.sdk.download中的类
an empty implementation of SonicDownloadCallback
SonicDownloadClient - com.tencent.sonic.sdk.download中的类
Handles a single HTTP resource download
SonicDownloadClient(SonicDownloadClient.DownloadTask) - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadClient
 
SonicDownloadClient.DownloadTask - com.tencent.sonic.sdk.download中的类
Task which record the download info
SonicDownloadClient.SonicDownloadConnection - com.tencent.sonic.sdk.download中的类
 
SonicDownloadClient.SubResourceDownloadCallback - com.tencent.sonic.sdk.download中的类
sub resource download callback.
SonicDownloadConnection(String) - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadClient.SonicDownloadConnection
 
SonicDownloadEngine - com.tencent.sonic.sdk.download中的类
an download initiator
SonicDownloadEngine(SonicDownloadCache) - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadEngine
 
SonicEngine - com.tencent.sonic.sdk中的类
Interacts with the overall SonicSessions running in the system.
SonicFileUtils - com.tencent.sonic.sdk中的类
Interact with the overall file operations.
SonicFileUtils() - 类 的构造器com.tencent.sonic.sdk.SonicFileUtils
 
sonicFlowStartTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
SonicResourceCache() - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache
 
SonicResourceDataHelper - com.tencent.sonic.sdk中的类
SonicResourceDataHelper manages the resource database.
SonicResourceDataHelper() - 类 的构造器com.tencent.sonic.sdk.SonicResourceDataHelper
 
SonicResourceDataHelper.ResourceData - com.tencent.sonic.sdk中的类
resource data structure
SonicRuntime - com.tencent.sonic.sdk中的类
SonicRuntime is a class which interacts with the overall running information in the system, including Context, UA, ID (which is the unique identification for the saved data) and other information.
SonicRuntime(Context) - 类 的构造器com.tencent.sonic.sdk.SonicRuntime
 
SonicServer - com.tencent.sonic.sdk中的类
Instances of this class can be used to read server response from SonicSessionConnection.
SonicServer(SonicSession, Intent) - 类 的构造器com.tencent.sonic.sdk.SonicServer
 
SonicSession - com.tencent.sonic.sdk中的类
In Sonic, SonicSessions are used to manage the entire process,include obtain the latest data from the server, provide local and latest data to kernel, separate html to template and data, build template and data to html and so on.
SonicSession.Callback - com.tencent.sonic.sdk中的接口
The interface is used to inform the listeners that the state of the session has changed.
SonicSessionClient - com.tencent.sonic.sdk中的类
SonicSessionClient is a thin API class that delegates its public API to a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.
SonicSessionClient() - 类 的构造器com.tencent.sonic.sdk.SonicSessionClient
 
SonicSessionConfig - com.tencent.sonic.sdk中的类
The sonicSession configurations.
SonicSessionConfig.Builder - com.tencent.sonic.sdk中的类
Builder for SonicSessionConfig
SonicSessionConnection - com.tencent.sonic.sdk中的类
The abstract class SonicSessionConnection is the superclass of all classes that represent a communications link between the application and a URL.
SonicSessionConnection(SonicSession, Intent) - 类 的构造器com.tencent.sonic.sdk.SonicSessionConnection
Constructor
SonicSessionConnection.SessionConnectionDefaultImpl - com.tencent.sonic.sdk中的类
 
SonicSessionConnectionInterceptor - com.tencent.sonic.sdk中的类
SonicSessionConnectionInterceptor provide a SonicSessionConnection.
SonicSessionConnectionInterceptor() - 类 的构造器com.tencent.sonic.sdk.SonicSessionConnectionInterceptor
 
SonicSessionStatistics - com.tencent.sonic.sdk中的类
The Statistic model specifies the data models which are required to be used to provide the performance data described by the specific attributes in a SonicSession.
SonicSessionStatistics() - 类 的构造器com.tencent.sonic.sdk.SonicSessionStatistics
 
SonicSessionStream - com.tencent.sonic.sdk中的类
A SonicSessionStream obtains input bytes from a memStream and a netStream.
SonicSessionStream(SonicSessionStream.Callback, ByteArrayOutputStream, BufferedInputStream) - 类 的构造器com.tencent.sonic.sdk.SonicSessionStream
Constructor
SonicSessionStream.Callback - com.tencent.sonic.sdk中的接口
When SonicSessionStream close the stream will invoke the Callback
sonicStartTime - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
Sonic start SonicSession.start() time
SonicUtils - com.tencent.sonic.sdk中的类
Sonic Utils
SonicUtils() - 类 的构造器com.tencent.sonic.sdk.SonicUtils
 
srcResultCode - 类 中的变量com.tencent.sonic.sdk.SonicSession
Sonic original mode.
srcUrl - 类 中的变量com.tencent.sonic.sdk.SonicSession
The original url
srcUrl - 类 中的变量com.tencent.sonic.sdk.SonicSessionStatistics
Original url
StandardSonicSession - com.tencent.sonic.sdk中的类
A subclass of SonicSession.
start() - 类 中的方法com.tencent.sonic.sdk.SonicSession
Start the sonic process
STATE_DESTROY - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Session state : destroyed.
STATE_DOWNLOADED - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the task is in download complete state.
STATE_DOWNLOADING - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the task is in downloading state.
STATE_INITIATE - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
download in initiate state.
STATE_LOAD_FROM_CACHE - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
the task is load from cache, not from network.
STATE_NONE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Session state : original.
STATE_QUEUEING - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask
download in queueing state.
STATE_READY - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Session state : ready.
STATE_RUNNING - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Session state : running.
stateChangedCallbackList - 类 中的变量com.tencent.sonic.sdk.SonicSession
 
statistics - 类 中的变量com.tencent.sonic.sdk.SonicSession
Session statics var
SubResourceDownloadCallback(String) - 类 的构造器com.tencent.sonic.sdk.download.SonicDownloadClient.SubResourceDownloadCallback
 
switchState(int, int, boolean) - 类 中的方法com.tencent.sonic.sdk.SonicSession
 

T

TAG - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache
log filter
TAG - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadClient
log filter
TAG - 类 中的静态变量com.tencent.sonic.sdk.download.SonicDownloadEngine
log filter
TAG - 类 中的静态变量com.tencent.sonic.sdk.SonicCacheInterceptor
 
TAG - 类 中的静态变量com.tencent.sonic.sdk.SonicServer
 
TAG - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
Log filter
templateString - 类 中的变量com.tencent.sonic.sdk.SonicServer
 
trimSonicCache() - 类 中的方法com.tencent.sonic.sdk.SonicEngine
It will Post a task to trim sonic cache if the last time of check sonic cache exceed SonicConfig.SONIC_CACHE_CHECK_TIME_INTERVAL.

V

VERIFY_CACHE_FILE_WITH_SHA1 - 类 中的变量com.tencent.sonic.sdk.SonicConfig
Whether verify file by compare SHA1.
verifyData(byte[], String) - 类 中的静态方法com.tencent.sonic.sdk.SonicFileUtils
This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.

W

wasInterceptInvoked - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether the client initiates a resource interception.
wasOnPageFinishInvoked - 类 中的变量com.tencent.sonic.sdk.SonicSession
Whether the local html is loaded, it is used only the template changes.
WEB_RESPONSE_CODE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The result keyword to page : the value is finalResultCode
WEB_RESPONSE_DATA - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The all data keyword to page
WEB_RESPONSE_EXTRA - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
WEB_RESPONSE_LOCAL_REFRESH_TIME - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
 
WEB_RESPONSE_SRC_CODE - 类 中的静态变量com.tencent.sonic.sdk.SonicSession
The result keyword to page : the value is srcResultCode
A B C D E F G H I L M N O P Q R S T V W 
================================================ FILE: sonic-android/docs/javadoc/index.html ================================================ sdk 3.0.0 API <noscript> <div>您的浏览器已禁用 JavaScript。</div> </noscript> <h2>框架预警</h2> <p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href="overview-summary.html">非框架版本</a>。</p> ================================================ FILE: sonic-android/docs/javadoc/overview-frame.html ================================================ 概览列表 (sdk 3.0.0 API)

 

================================================ FILE: sonic-android/docs/javadoc/overview-summary.html ================================================ 概览 (sdk 3.0.0 API)

sdk 3.0.0 API

程序包 
程序包 说明
com.tencent.sonic.sdk  
com.tencent.sonic.sdk.download  
================================================ FILE: sonic-android/docs/javadoc/overview-tree.html ================================================ 类分层结构 (sdk 3.0.0 API)

所有程序包的分层结构

程序包分层结构:

类分层结构

接口分层结构

================================================ FILE: sonic-android/docs/javadoc/package-list ================================================ com.tencent.sonic.sdk com.tencent.sonic.sdk.download ================================================ FILE: sonic-android/docs/javadoc/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: sonic-android/docs/javadoc/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: sonic-android/gradle/wrapper/gradle-wrapper.properties ================================================ #Mon Jun 19 17:11:15 CST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip ================================================ FILE: sonic-android/gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: sonic-android/gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: sonic-android/sample/.gitignore ================================================ .gradle /build # Ignore Gradle GUI config gradle-app.setting # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar # Cache of project .gradletasknamecache .DS_Store node_modules # Built application files *.apk *.ap_ # Java class files *.class # Generated files bin/ gen/ # Gradle files .gradle/ *.iml /*/*.iml .idea /*/.idea/ # Local configuration file (sdk path, etc) local.properties gradle.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log /*/.idea /buildSdk ================================================ FILE: sonic-android/sample/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.tencent.sonic" minSdkVersion 19 targetSdkVersion 25 versionCode 3 versionName "3.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) // compile sdk from jcenter compile 'com.tencent.sonic:sdk:3.1.0' // compile sonic-sdk from local path // compile project(path: ':sdk') compile 'com.android.support:appcompat-v7:25.2.0' compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7' compile 'com.android.support:design:25.3.1' testCompile 'junit:junit:4.12' } ================================================ FILE: sonic-android/sample/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/lovekidchen/Library/Android/sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: sonic-android/sample/src/main/AndroidManifest.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/assets/sonic-demo-index.html ================================================ SONIC

Sonic:轻量级的高性能的Hybrid框架

Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架,专注于提升H5页面首屏加载速度,让H5页面的体验更加接近原生,提升用户体验及用户留存率。

示例:

非Sonic模式 点击到页面打开耗时:

普通直出的方式

首次访问 点击到页面打开耗时:

用户第一次访问,本地无缓存;使用直出的方式,终端生成缓存。

模版更新 点击到页面打开耗时:

本地模版跟服务器模版不一样;缓存失效,清除缓存,重新加载页面。

数据更新 点击到页面打开耗时:

模板一致,数据变更;针对页面局部数据变化的场景,Sonic会预先加载本地缓存再将变化部分的数据异步更新,提升用户体验。

完全缓存 点击到页面打开耗时:

本地数据与服务器数据完全一样;直接使用缓存,页面秒开。

页面打开速度效果对比

以手机QQ-VIP中心首页为例,在接入Sonic框架之后,页面打开速度在数据更新场景下优化提升42%,页面内容不变的场景下(完全cache模式)优化提升50%以上。

原有直出页面: Sonic改造页面:

Sonic实现原理简介

Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源,在移动终端初始化的同时并行请求页面主资源并做到流式拦截,减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据),该框架能做到智能地对页面内容进行动态缓存和增量更新,减少对网络的依赖,节省用户流量,加快页面打开速度。

================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/BrowserActivity.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.text.TextUtils; import android.view.View; import android.view.WindowManager; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import com.tencent.sonic.R; import com.tencent.sonic.sdk.SonicCacheInterceptor; import com.tencent.sonic.sdk.SonicConfig; import com.tencent.sonic.sdk.SonicConstants; import com.tencent.sonic.sdk.SonicEngine; import com.tencent.sonic.sdk.SonicSession; import com.tencent.sonic.sdk.SonicSessionConfig; import com.tencent.sonic.sdk.SonicSessionConnection; import com.tencent.sonic.sdk.SonicSessionConnectionInterceptor; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.List; import java.util.Map; /** * A demo browser activity * In this demo there are three modes, * sonic mode: sonic mode means webview loads html by sonic, * offline mode: offline mode means webview loads html from local offline packages, * default mode: default mode means webview loads html in the normal way. * */ public class BrowserActivity extends Activity { public final static String PARAM_URL = "param_url"; public final static String PARAM_MODE = "param_mode"; private SonicSession sonicSession; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); String url = intent.getStringExtra(PARAM_URL); int mode = intent.getIntExtra(PARAM_MODE, -1); if (TextUtils.isEmpty(url) || -1 == mode) { finish(); return; } getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); // init sonic engine if necessary, or maybe u can do this when application created if (!SonicEngine.isGetInstanceAllowed()) { SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build()); } SonicSessionClientImpl sonicSessionClient = null; // if it's sonic mode , startup sonic session at first time if (MainActivity.MODE_DEFAULT != mode) { // sonic mode SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); sessionConfigBuilder.setSupportLocalServer(true); // if it's offline pkg mode, we need to intercept the session connection if (MainActivity.MODE_SONIC_WITH_OFFLINE_CACHE == mode) { sessionConfigBuilder.setCacheInterceptor(new SonicCacheInterceptor(null) { @Override public String getCacheData(SonicSession session) { return null; // offline pkg does not need cache } }); sessionConfigBuilder.setConnectionInterceptor(new SonicSessionConnectionInterceptor() { @Override public SonicSessionConnection getConnection(SonicSession session, Intent intent) { return new OfflinePkgSessionConnection(BrowserActivity.this, session, intent); } }); } // create sonic session and run sonic flow sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build()); if (null != sonicSession) { sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl()); } else { // this only happen when a same sonic session is already running, // u can comment following codes to feedback as a default mode. // throw new UnknownError("create session fail!"); Toast.makeText(this, "create sonic session fail!", Toast.LENGTH_LONG).show(); } } // start init flow ... // in the real world, the init flow may cost a long time as startup // runtime、init configs.... setContentView(R.layout.activity_browser); FloatingActionButton btnFab = (FloatingActionButton) findViewById(R.id.btn_refresh); btnFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (sonicSession != null) { sonicSession.refresh(); } } }); // init webview WebView webView = (WebView) findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (sonicSession != null) { sonicSession.getSessionClient().pageFinish(url); } } @TargetApi(21) @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return shouldInterceptRequest(view, request.getUrl().toString()); } @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { if (sonicSession != null) { return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url); } return null; } }); WebSettings webSettings = webView.getSettings(); // add java script interface // note:if api level lower than 17(android 4.2), addJavascriptInterface has security // issue, please use x5 or see https://developer.android.com/reference/android/webkit/ // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String) webSettings.setJavaScriptEnabled(true); webView.removeJavascriptInterface("searchBoxJavaBridge_"); intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis()); webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic"); // init webview settings webSettings.setAllowContentAccess(true); webSettings.setDatabaseEnabled(true); webSettings.setDomStorageEnabled(true); webSettings.setAppCacheEnabled(true); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); // webview is ready now, just tell session client to bind if (sonicSessionClient != null) { sonicSessionClient.bindWebView(webView); sonicSessionClient.clientReady(); } else { // default mode webView.loadUrl(url); } } @Override public void onBackPressed() { super.onBackPressed(); } @Override protected void onDestroy() { if (null != sonicSession) { sonicSession.destroy(); sonicSession = null; } super.onDestroy(); } private static class OfflinePkgSessionConnection extends SonicSessionConnection { private final WeakReference context; public OfflinePkgSessionConnection(Context context, SonicSession session, Intent intent) { super(session, intent); this.context = new WeakReference(context); } @Override protected int internalConnect() { Context ctx = context.get(); if (null != ctx) { try { InputStream offlineHtmlInputStream = ctx.getAssets().open("sonic-demo-index.html"); responseStream = new BufferedInputStream(offlineHtmlInputStream); return SonicConstants.ERROR_CODE_SUCCESS; } catch (Throwable e) { e.printStackTrace(); } } return SonicConstants.ERROR_CODE_UNKNOWN; } @Override protected BufferedInputStream internalGetResponseStream() { return responseStream; } @Override protected String internalGetCustomHeadFieldEtag() { return SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG; } @Override public void disconnect() { if (null != responseStream) { try { responseStream.close(); } catch (IOException e) { e.printStackTrace(); } } } @Override public int getResponseCode() { return 200; } @Override public Map> getResponseHeaderFields() { return new HashMap<>(0); } @Override public String getResponseHeaderField(String key) { return ""; } } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/MainActivity.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.Toast; import com.tencent.sonic.R; import com.tencent.sonic.sdk.SonicConfig; import com.tencent.sonic.sdk.SonicEngine; import com.tencent.sonic.sdk.SonicSessionConfig; /** * main activity of this sample */ public class MainActivity extends Activity { public static final int MODE_DEFAULT = 0; public static final int MODE_SONIC = 1; public static final int MODE_SONIC_WITH_OFFLINE_CACHE = 2; private static final int PERMISSION_REQUEST_CODE_STORAGE = 1; private String DEMO_URL; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // full screen requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); // clean up cache btn Button btnReset = (Button) findViewById(R.id.btn_reset); btnReset.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SonicEngine.getInstance().cleanCache(); } }); // default btn Button btnDefault = (Button) findViewById(R.id.btn_default_mode); btnDefault.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startBrowserActivity(MODE_DEFAULT); } }); // preload btn Button btnSonicPreload = (Button) findViewById(R.id.btn_sonic_preload); btnSonicPreload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder(); sessionConfigBuilder.setSupportLocalServer(true); // preload session boolean preloadSuccess = SonicEngine.getInstance().preCreateSession(DEMO_URL, sessionConfigBuilder.build()); Toast.makeText(getApplicationContext(), preloadSuccess ? "Preload start up success!" : "Preload start up fail!", Toast.LENGTH_LONG).show(); } }); // sonic mode load btn Button btnSonic = (Button) findViewById(R.id.btn_sonic); btnSonic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startBrowserActivity(MODE_SONIC); } }); // load sonic with offline cache Button btnSonicWithOfflineCache = (Button) findViewById(R.id.btn_sonic_with_offline); btnSonicWithOfflineCache.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startBrowserActivity(MODE_SONIC_WITH_OFFLINE_CACHE); } }); if (hasPermission()) { init(); } else { requestPermission(); } final UrlListAdapter urlListAdapter = new UrlListAdapter(MainActivity.this); FloatingActionButton btnFab = (FloatingActionButton) findViewById(R.id.btn_fab); btnFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { UrlSelector.launch(MainActivity.this, urlListAdapter, new UrlSelector.OnUrlChangedListener() { @Override public void urlChanged(String url) { DEMO_URL = url; } }); } }); DEMO_URL = urlListAdapter.getCheckedUrl(); } private void init() { // init sonic engine if (!SonicEngine.isGetInstanceAllowed()) { SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build()); } } private boolean hasPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; } return true; } private void requestPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_STORAGE); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (PERMISSION_REQUEST_CODE_STORAGE == requestCode) { if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { requestPermission(); } else { init(); } return; } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } private void startBrowserActivity(int mode) { Intent intent = new Intent(this, BrowserActivity.class); intent.putExtra(BrowserActivity.PARAM_URL, DEMO_URL); intent.putExtra(BrowserActivity.PARAM_MODE, mode); intent.putExtra(SonicJavaScriptInterface.PARAM_CLICK_TIME, System.currentTimeMillis()); startActivityForResult(intent, -1); } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicJavaScriptInterface.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.content.Intent; import android.os.Handler; import android.os.Looper; import android.webkit.JavascriptInterface; import com.tencent.sonic.sdk.SonicDiffDataCallback; import org.json.JSONObject; /** * Sonic javaScript Interface (Android API Level >= 17) */ public class SonicJavaScriptInterface { private final SonicSessionClientImpl sessionClient; private final Intent intent; public static final String PARAM_CLICK_TIME = "clickTime"; public static final String PARAM_LOAD_URL_TIME = "loadUrlTime"; public SonicJavaScriptInterface(SonicSessionClientImpl sessionClient, Intent intent) { this.sessionClient = sessionClient; this.intent = intent; } @JavascriptInterface public void getDiffData() { // the callback function of demo page is hardcode as 'getDiffDataCallback' getDiffData2("getDiffDataCallback"); } @JavascriptInterface public void getDiffData2(final String jsCallbackFunc) { if (null != sessionClient) { sessionClient.getDiffData(new SonicDiffDataCallback() { @Override public void callback(final String resultData) { Runnable callbackRunnable = new Runnable() { @Override public void run() { String jsCode = "javascript:" + jsCallbackFunc + "('"+ toJsString(resultData) + "')"; sessionClient.getWebView().loadUrl(jsCode); } }; if (Looper.getMainLooper() == Looper.myLooper()) { callbackRunnable.run(); } else { new Handler(Looper.getMainLooper()).post(callbackRunnable); } } }); } } @JavascriptInterface public String getPerformance() { long clickTime = intent.getLongExtra(PARAM_CLICK_TIME, -1); long loadUrlTime = intent.getLongExtra(PARAM_LOAD_URL_TIME, -1); try { JSONObject result = new JSONObject(); result.put(PARAM_CLICK_TIME, clickTime); result.put(PARAM_LOAD_URL_TIME, loadUrlTime); return result.toString(); } catch (Exception e) { } return ""; } /* * * From RFC 4627, "All Unicode characters may be placed within the quotation marks except * for the characters that must be escaped: quotation mark, * reverse solidus, and the control characters (U+0000 through U+001F)." */ private static String toJsString(String value) { if (value == null) { return "null"; } StringBuilder out = new StringBuilder(1024); for (int i = 0, length = value.length(); i < length; i++) { char c = value.charAt(i); switch (c) { case '"': case '\\': case '/': out.append('\\').append(c); break; case '\t': out.append("\\t"); break; case '\b': out.append("\\b"); break; case '\n': out.append("\\n"); break; case '\r': out.append("\\r"); break; case '\f': out.append("\\f"); break; default: if (c <= 0x1F) { out.append(String.format("\\u%04x", (int) c)); } else { out.append(c); } break; } } return out.toString(); } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicRuntimeImpl.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.content.Context; import android.os.Build; import android.os.Environment; import android.text.TextUtils; import android.util.Log; import android.webkit.CookieManager; import android.webkit.CookieSyncManager; import android.webkit.WebResourceResponse; import com.tencent.sonic.BuildConfig; import com.tencent.sonic.sdk.SonicRuntime; import com.tencent.sonic.sdk.SonicSessionClient; import java.io.File; import java.io.InputStream; import java.util.List; import java.util.Map; /** * the sonic host application must implement SonicRuntime to do right things. */ public class SonicRuntimeImpl extends SonicRuntime { public SonicRuntimeImpl(Context context) { super(context); } /** * 获取用户UA信息 * @return */ @Override public String getUserAgent() { return "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Mobile Safari/537.36"; } /** * 获取用户ID信息 * @return */ @Override public String getCurrentUserAccount() { return "sonic-demo-master"; } @Override public String getCookie(String url) { CookieManager cookieManager = CookieManager.getInstance(); return cookieManager.getCookie(url); } @Override public void log(String tag, int level, String message) { switch (level) { case Log.ERROR: Log.e(tag, message); break; case Log.INFO: Log.i(tag, message); break; default: Log.d(tag, message); } } @Override public Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map headers) { WebResourceResponse resourceResponse = new WebResourceResponse(mimeType, encoding, data); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { resourceResponse.setResponseHeaders(headers); } return resourceResponse; } @Override public void showToast(CharSequence text, int duration) { } @Override public void notifyError(SonicSessionClient client, String url, int errorCode) { } @Override public boolean isSonicUrl(String url) { return true; } @Override public boolean setCookie(String url, List cookies) { if (!TextUtils.isEmpty(url) && cookies != null && cookies.size() > 0) { CookieManager cookieManager = CookieManager.getInstance(); for (String cookie : cookies) { cookieManager.setCookie(url, cookie); } return true; } return false; } @Override public boolean isNetworkValid() { return true; } @Override public void postTaskToThread(Runnable task, long delayMillis) { Thread thread = new Thread(task, "SonicThread"); thread.start(); } @Override public File getSonicCacheDir() { if (BuildConfig.DEBUG) { String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "sonic/"; File file = new File(path.trim()); if(!file.exists()){ file.mkdir(); } return file; } return super.getSonicCacheDir(); } @Override public String getHostDirectAddress(String url) { return null; } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicSessionClientImpl.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.os.Bundle; import android.webkit.WebView; import com.tencent.sonic.sdk.SonicSessionClient; import java.util.HashMap; /** * a implement of SonicSessionClient which need to connect webview and content data. */ public class SonicSessionClientImpl extends SonicSessionClient { private WebView webView; public void bindWebView(WebView webView) { this.webView = webView; } public WebView getWebView() { return webView; } @Override public void loadUrl(String url, Bundle extraData) { webView.loadUrl(url); } @Override public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) { webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); } @Override public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap headers) { loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl); } public void destroy() { if (null != webView) { webView.destroy(); webView = null; } } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/UrlListAdapter.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.content.Context; import android.content.SharedPreferences; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageButton; import android.widget.RadioButton; import android.widget.TextView; import com.tencent.sonic.R; import java.util.ArrayList; import java.util.Arrays; public class UrlListAdapter extends BaseAdapter { public static final String PREFERENCE_URLS = "urls"; public static final String PREFERENCE_CHECKED_INDEX = "checked_index"; public static final int MODE_NORMAL = 1; public static final int MODE_EDIT = 2; private static final String DEFAULT_URL = "http://mc.vip.qq.com/demo/indexv3"; private ArrayList urls; private LayoutInflater mInflater; private int checkedIndex; private int mode = MODE_NORMAL; private SharedPreferences sharedPreferences; public UrlListAdapter(Context context) { mInflater = LayoutInflater.from(context); sharedPreferences = context.getSharedPreferences("list_adapter", 0); init(); } void init() { restore(); toggleNormalMode(); } private void restore() { urls = deserialize(sharedPreferences.getString(PREFERENCE_URLS, "")); if (urls.isEmpty()) { urls.add(DEFAULT_URL); } checkedIndex = sharedPreferences.getInt(PREFERENCE_CHECKED_INDEX, 0); } private String serialize(ArrayList stringArrayList) { return TextUtils.join(";", stringArrayList); } private ArrayList deserialize(String serializedString) { if (serializedString.isEmpty()) { return new ArrayList<>(); } return new ArrayList<>(Arrays.asList(serializedString.split(";"))); } String getCheckedUrl() { return (checkedIndex >= 0 && checkedIndex < urls.size()) ? urls.get(checkedIndex) : DEFAULT_URL; } void addNewItem(String url) { urls.add(url); notifyDataSetChanged(); } void toggleNormalMode() { mode = MODE_NORMAL; notifyDataSetChanged(); } void toggleEditMode() { mode = MODE_EDIT; notifyDataSetChanged(); } void setChecked(int index) { if (mode == MODE_NORMAL) { checkedIndex = index; notifyDataSetChanged(); } } @Override public int getCount() { return urls.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.list_item_url, null); holder.radioButton = (RadioButton) convertView.findViewById(R.id.radio); holder.textUrl = (TextView) convertView.findViewById(R.id.text_url); holder.btnDelete = (ImageButton) convertView.findViewById(R.id.btn_delete); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } if (mode == MODE_EDIT && position == 0) { holder.btnDelete.setVisibility(View.INVISIBLE); } else { holder.btnDelete.setVisibility(mode == MODE_EDIT ? View.VISIBLE : View.INVISIBLE); } if (mode == MODE_EDIT) { holder.radioButton.setVisibility(View.GONE); } else { holder.radioButton.setChecked(checkedIndex == position); holder.radioButton.setVisibility(View.VISIBLE); } holder.textUrl.setText(urls.get(position)); holder.btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (position == checkedIndex) { checkedIndex = 0; } urls.remove(position); notifyDataSetChanged(); } }); return convertView; } void persist() { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(PREFERENCE_URLS, serialize(urls)); editor.putInt(PREFERENCE_CHECKED_INDEX, checkedIndex); editor.apply(); } private class ViewHolder { RadioButton radioButton; TextView textUrl; ImageButton btnDelete; } } ================================================ FILE: sonic-android/sample/src/main/java/com/tencent/sonic/demo/UrlSelector.java ================================================ /* * Tencent is pleased to support the open source community by making VasSonic available. * * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * */ package com.tencent.sonic.demo; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.text.Editable; import android.text.TextWatcher; import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ListView; import android.widget.Toast; import com.tencent.sonic.R; public class UrlSelector { static void launch(final Context context, final UrlListAdapter urlListAdapter, final OnUrlChangedListener listener) { urlListAdapter.init(); final View view = LayoutInflater.from(context).inflate(R.layout.dialog_url, null); ListView listView = (ListView) view.findViewById(R.id.listView); listView.setAdapter(urlListAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { urlListAdapter.setChecked(position); } }); final ImageButton btnAddItem = (ImageButton) view.findViewById(R.id.btn_add_item); btnAddItem.setActivated(false); final EditText textNewUrl = (EditText) view.findViewById(R.id.text_new_url); textNewUrl.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { btnAddItem.setActivated(Patterns.WEB_URL.matcher(s.toString()).matches()); } }); btnAddItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (btnAddItem.isActivated()) { urlListAdapter.addNewItem(textNewUrl.getText().toString()); textNewUrl.setText(R.string.http_prefix); textNewUrl.setSelection(textNewUrl.getText().length()); } else { Toast.makeText(context, R.string.illegal_url, Toast.LENGTH_SHORT).show(); } } }); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.set_custom_url); builder.setCancelable(false); builder.setView(view); builder.setPositiveButton(R.string.close, null); final AlertDialog alertDialog = builder.create(); final View viewAddItem = view.findViewById(R.id.add_item); final Button btnEdit = (Button) view.findViewById(R.id.btn_edit); btnEdit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { btnEdit.setVisibility(View.INVISIBLE); urlListAdapter.toggleEditMode(); viewAddItem.setVisibility(View.VISIBLE); alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.finish); } }); alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(final DialogInterface dialog) { final Button okButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); okButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (okButton.getText().equals(context.getString(R.string.finish))) { urlListAdapter.toggleNormalMode(); viewAddItem.setVisibility(View.GONE); btnEdit.setVisibility(View.VISIBLE); okButton.setText(R.string.close); } else if (okButton.getText().equals(context.getString(R.string.close))) { urlListAdapter.persist(); listener.urlChanged(urlListAdapter.getCheckedUrl()); dialog.dismiss(); } } }); } }); alertDialog.show(); // prevent keyboard from not showing alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } interface OnUrlChangedListener { void urlChanged(String url); } } ================================================ FILE: sonic-android/sample/src/main/res/drawable/ic_add_circle_accent_24dp.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/drawable/ic_add_circle_black_24dp.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/drawable/ic_add_circle_selector.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/drawable/ic_remove_circle_accent_24dp.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/drawable/sonic_button_round_mask.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/layout/activity_browser.xml ================================================ ================================================ FILE: sonic-android/sample/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: sonic-nodejs/assets/page/tpls/common_body_header.js ================================================ ;(function(){var __a={'&':'&','<':'<','>':'>','"':'"',"'":'''}, __b=/[&<>"']/g, __e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});}; module.exports = function (data, children) { data=typeof data != "undefined"?data:{},children= typeof children != "undefined"?children:{}; var __p=[],_p=function(s){__p.push(s)}; ;_p('\r\n\
\r\n\

sonic demo

\r\n\
'); return __p.join(""); };})(); ================================================ FILE: sonic-nodejs/assets/page/tpls/common_header.ejs ================================================ ================================================ FILE: sonic-nodejs/assets/page/tpls/common_header.js ================================================ ;(function(){var __a={'&':'&','<':'<','>':'>','"':'"',"'":'''}, __b=/[&<>"']/g, __e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});}; module.exports = function (data, children) { data=typeof data != "undefined"?data:{},children= typeof children != "undefined"?children:{}; var __p=[],_p=function(s){__p.push(s)}; ;_p(''); return __p.join(""); };})(); ================================================ FILE: sonic-nodejs/assets/page/tpls/common_meta.ejs ================================================ ================================================ FILE: sonic-nodejs/assets/page/tpls/common_meta.js ================================================ ;(function(){var __a={'&':'&','<':'<','>':'>','"':'"',"'":'''}, __b=/[&<>"']/g, __e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});}; module.exports = function (data, children) { data=typeof data != "undefined"?data:{},children= typeof children != "undefined"?children:{}; var __p=[],_p=function(s){__p.push(s)}; ;_p('\r\n\ \r\n\ \r\n\ \r\n\ \r\n\ '); return __p.join(""); };})(); ================================================ FILE: sonic-nodejs/assets/project.config.js ================================================ let path = require('path'); module.exports = { build: { ejs2js: path.resolve(__dirname, './page') //构建ejs2js的范围 } }; ================================================ FILE: sonic-nodejs/common/diff.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const crypto = require('crypto'); module.exports = function (ctx, buffer, {'sonic-etag-key': sonicEtagKey = 'Etag'}) { let etag = ctx.get('if-none-match'); let now = Date.now(); let md5 = crypto.createHash('sha1').update(buffer).digest('hex'); console.info(`请求头etag = ${etag}`); console.info(`页面md5 = ${md5}`); //sonicMode含义 // 0-非sonic(没有sonicdiff标签) // 1-首次加载(本地无模板和数据) // 2-页面刷新(模板有变) // 3-局部数据刷新(模板不变,数据有变) // 4-完成缓存304(模板不变,数据不变) if (etag && md5 == etag) { ctx.set('Cache-Offline', 'store'); ctx.set('Content-Length', 0); ctx.status = 304; ctx.sonicMode = 4; return { cache: true } } else { let htmlStr = buffer.toString('utf8'); //替换 &&提取 title,body let title = ""; let now2 = Date.now(); let templateHtml = htmlStr.replace(//i, function (titleHtml) { title = titleHtml; return "{title}"; }); //判断是否成功替换wnsdiffbody let flag = false; let tagIndex = 0, tagPrefix = 'auto'; let diffTagNames = {}; templateHtml = templateHtml.replace(/([\s\S]+?)/ig, function (diffhtml, tagName) { flag = true; if (!tagName) { tagName = tagPrefix + tagIndex++; } diffTagNames[tagName] = diffhtml; return '{' + tagName + '}'; }); console.info(`获取sonic diff耗时${Date.now() - now2}`); let now3 = Date.now(); let templateMd5 = crypto.createHash('sha1').update(new Buffer(templateHtml)).digest('hex'); console.info(`获取sonic diff耗时${Date.now() - now3}`); ctx.set('sonic-etag-key', sonicEtagKey); ctx.set(sonicEtagKey, md5); ctx.set('template-tag', templateMd5); ctx.set('Cache-Offline', true); if (flag) { let templateTag = ctx.get('template-tag'); if (templateMd5 == templateTag) { ctx.set('template-change', 'false'); let result = { 'data': { '{title}': title }, 'diff': '', 'html-sha1': md5, "template-tag": templateMd5 }; Object.keys(diffTagNames).forEach(v => { result['data']['{' + v + '}'] = diffTagNames[v]; }); console.info(`数据更新耗时${Date.now() - now}`); ctx.sonicMode = 3; return { data: new Buffer(JSON.stringify(result)) } } else { ctx.set('template-change', 'true'); ctx.sonicMode = templateTag ? 2 : 1; console.info(`模版更新耗时${Date.now() - now}`); return { data: new Buffer(htmlStr) } } } else { ctx.set('template-change', 'true'); ctx.sonicMode = 0; return { data: new Buffer(htmlStr) } } } }; ================================================ FILE: sonic-nodejs/middleware/compress.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const stream = require('stream'); const isJSON = require('koa-is-json'); const differ = require('sonic_differ'); const zlib = require('zlib'); const method = { gzip: zlib.createGzip, deflate: zlib.createDeflate }; module.exports = () => { return async function (ctx, next) { await next(); let body = ctx.body; if (!body) return; if (isJSON(body)) body = ctx.body = JSON.stringify(body); let encoding = ctx.acceptsEncodings('gzip', 'deflate', 'identity'); if (!encoding) ctx.throw(406, 'supported encodings: gzip, deflate, identity'); if (encoding === 'identity') return; if (ctx.response.length < 2048) return; ctx.set('Content-Encoding', encoding); ctx.res.removeHeader('Content-Length'); let zip = ctx.body = method[encoding]({ flush: require('zlib').Z_SYNC_FLUSH }); zip.on('error', err => { console.info(err) }); zip.on('finish', () => { console.info('zip succ') }); let sonic = { buffer: [], write: function (chunk, encoding) { let buffer = chunk; let ecode = encoding || 'utf8'; if (!Buffer.isBuffer(chunk)) { buffer = new Buffer(chunk, ecode); } sonic.buffer.push(buffer); } }; function getDiff() { console.info('sonic 开始拦截返回数据'); body.on('data', (chunk, encoding) => { sonic.write(chunk, encoding) }); body.on('end', () => { let result = differ(ctx, Buffer.concat(sonic.buffer)); sonic.buffer = []; if (result.cache) { console.info('sonic 完全cache'); zip.end() } else { console.info('sonic 非缓存模式'); zip.end(result.data) } }) } try { body instanceof stream ? ctx.get('accept-diff') ? getDiff() : body.pipe(zip) : zip.end(body); } catch (e) { console.info('zip error'); console.error(e) } } }; ================================================ FILE: sonic-nodejs/package.json ================================================ { "name": "koa-example", "version": "1.0.0", "description": "sonic demo with koa", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "sonic" ], "author": "", "license": "ISC", "dependencies": { "sonic_differ": "^1.0.0", "koa": "^2.2.0", "koa-is-json": "^1.0.0", "pm2": "^2.4.6", "through2": "^2.0.3" } } ================================================ FILE: sonic-nodejs/router/config.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const path = require('path'); module.exports = { '/': { template: path.resolve(__dirname, '../assets/page/index.js') }, '/demo1': { template: path.resolve(__dirname, '../assets/page/demo1.js') }, '/demo2': { template: path.resolve(__dirname, '../assets/page/demo2.js'), data: path.resolve(__dirname, '../assets/page/demo2-data.js') }, '/demo3': { template: path.resolve(__dirname, '../assets/page/demo3.js'), data: path.resolve(__dirname, '../assets/page/demo3-data.js') } }; ================================================ FILE: sonic-nodejs/router/index.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const routerConfig = require('./config'); const through2 = require('through2'); module.exports = () => { return async function (ctx, next) { let pathname = (ctx.request.url || '').split('?')[0]; if (routerConfig[pathname]) { console.log(routerConfig[pathname]); try { let tpl = require(routerConfig[pathname].template), data = {}; if (routerConfig[pathname].data) { let dataFn = require(routerConfig[pathname].data); data = dataFn(ctx) || {}; } ctx.body = through2(); ctx.type = 'html'; ctx.body.end(tpl(data)); } catch (e) { console.error(e); } } else { console.log('路由未配置', pathname); } } }; ================================================ FILE: sonic-php/README.md ================================================ ## Getting started with PHP [![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki) --- ## How to use for Server Download and import ```sonic.php```. ```PHP require_once(PATH."/sonic.php"); ``` Then add following code. ``` if (isset($_GET['sonic']) && $_GET['sonic'] == '1') { // Check if Sonic is needed or not util_sonic::start(); $this->_index_v5($uin); util_sonic::end(); } ``` ## How to use for front-end Here is a simple demo shows how to use Sonic for front-end. ```Html demo // step 1: specify template and data by inserting different comment anchor.

here is the data

data3
// step 2: Receives diff data from mobile client through Javascript interface. ``` ### Step 1: Specify template and data by inserting different comment anchor. The data will be wrapped with anchor `````` ``````. The other part of html is template. ```Html

here is the data

data3
``` ### Step 2: Receives diff data from mobile client through JavaScript interface. The JavaScript interface of demo was involved when websites are finish. But the time when inferface was involved is not immutable, websites can decide whenever they want. ```Html ``` ### Step 3: Handle different status received from mobile client. The demo shows how to find and replace the data of specified anchor according to the diff data come from mobile client, then the website is updated. ```Html //step 3 Handle the response from mobile client which include Sonic response code and diff data. function getDiffDataCallback(result){ } //step 3 Handle the response from mobile client which include Sonic response code and diff data. function handleSonicDiffData(sonicStatus, sonicUpdateData){ } ``` ## Support Any problem? 1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sample). 2. Contact us for help. ## License VasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details. [1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif [2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif ================================================ FILE: sonic-php/sample/README.md ================================================ 将sample放在php的web目录 访问入口localhost/sample/index.php ================================================ FILE: sonic-php/sample/controller/demo.php ================================================ 2, 'dataUpdate' => 3, 'cache' => 4 ); $sonicStatus = 0; //1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache if (isset($headers['accept-diff']) && $headers['accept-diff'] == 'true') { if (isset($headers['template-tag']) && !empty($headers['template-tag'])) { //有缓存的情况随机局部刷新、模板变更、完全缓存 $sonicStatusRand = array(3,3,3,3,3,4,4,2,4,4,4); $sonicStatus = isset($_GET['sonicStatus']) && in_array($_GET['sonicStatus'], array_keys($sonicStatusMap)) ? $sonicStatusMap[$_GET['sonicStatus']] : $sonicStatusRand[array_rand($sonicStatusRand)]; switch($sonicStatus) { case 2: //模板变更 数据不变 改模板 if (isset($_COOKIE['dataImg'])) { $dataImg = $_COOKIE['dataImg']; } if (isset($_COOKIE['templateFlag'])) { $templateFlag = !$_COOKIE['templateFlag']; } break; case 3://局部刷新 数据变 模板不变 if (isset($_COOKIE['dataImg'])) { $dataImg = !$_COOKIE['dataImg']; } if (isset($_COOKIE['templateFlag'])) { $templateFlag = $templateFlag; } break; case 4: if (isset($_COOKIE['dataImg'])) { $dataImg = $_COOKIE['dataImg']; } if (isset($_COOKIE['templateFlag'])) { $templateFlag = $_COOKIE['templateFlag']; } break; } } else { //首次 $sonicStatus = 1; } } setcookie('dataImg', intval($dataImg)); setcookie('templateFlag',intval($templateFlag)); /** * 构造随机sonic状态 end */ /** * 模拟后台耗时操作 begin */ sleep(1); /** * 模拟后台耗时操作 end */ require_once 'util/sonic.php'; util_sonic::start(); require 'view/demo_template.php'; util_sonic::end(); } } ================================================ FILE: sonic-php/sample/index.php ================================================ $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value; } } return $headers; } } require_once 'controller/demo.php'; $demo = new controller_demo(); $demo->actionIndex(); ================================================ FILE: sonic-php/sample/js/sonic-3.js ================================================ /** * * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * * @作者 craigchen * @版本 2.0.0 * sonic前端JS类库 */ ;(function(){ function getSonicData(callback) { var sonicStatus = 0, //sonic状态 0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache reportSonicStatus = 0, //sonic上报状态 sonicHadExecute = 0, //sonic执行标志位 sonicUpdateData = {}; //sonic diff数据 window.sonic && window.sonic.getDiffData(); //执行sonicdiff window['getDiffDataCallback'] = function (diffData) { try{ var result = JSON.parse(diffData); } catch (e) {} if(result['code'] == 200){ reportSonicStatus = sonicStatus = 3; sonicUpdateData = JSON.parse(result['result']); //页面完全没有变化 } else if (result['code'] == 1000) { reportSonicStatus = sonicStatus = 1; } else if (result['code'] == 2000) { reportSonicStatus = sonicStatus = 2; } else if(result['code'] == 304) { sonicStatus = 4; switch(parseInt(result['srcCode'])) { //上报状态处理 case 304: reportSonicStatus = 4; break; case 200: //局部刷新也可能返回304 但srcCode是200,当返回的局部数据足够快,终端会组装好页面返回304 reportSonicStatus = 3; break; case 1000: reportSonicStatus = 1; break; case 2000: reportSonicStatus = 2; break; default: reportSonicStatus = sonicStatus; } } if (sonicHadExecute == 0) { callback(sonicStatus, reportSonicStatus, sonicUpdateData); sonicHadExecute = 1; } } /** * sonic超时处理 默认5s */ setTimeout(function(){ if(sonicHadExecute == 0){ sonicHadExecute = 1; callback(sonicStatus, reportSonicStatus, sonicUpdateData); } }, 5000); } if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = getSonicData; } else if (typeof define === 'function') { define("lib/sonic/sonic",[], function(require, exports){ exports.getSonicData = getSonicData; }); } else if (typeof define === 'function' && define.amd) { define(function() { return getSonicData; }); } else { this.moduleName = getSonicData; } }).call(function() { return this || (typeof window !== 'undefined' ? window : global); }); ================================================ FILE: sonic-php/sample/util/sonic.php ================================================ $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value; } } return $headers; } } class TemplateReplace{ public static $shotWnsDiffBodyReplace = false; //判断是否成功替换sonicdiffbody public static $diffIndex = 0; public static $tagPrefix = 'auto'; public static $diffTagNames = array(); //数据块 public function callback($matches) { if(isset($matches) && isset($matches[0])) { self::$shotWnsDiffBodyReplace = true; if(isset($matches[1])) { $tagName = $matches[1]; } else { $tagName = self::$tagPrefix.self::$diffIndex++; } self::$diffTagNames[$tagName] = $matches[0]; return '{'.$tagName.'}'; } } } class util_sonic { public static function start(){ ob_start(); $_SERVER['PHP_SONIC'] = '1'; } public static function end() { $outContent = ob_get_clean(); $headers = getallheaders(); if(isset($headers['accept-diff']) && $headers['accept-diff'] === 'true'){ header('Cache-Control: no-cache'); $offline = 'true'; header("Cache-Offline: $offline"); $Etag = NULL; if(isset($headers['if-none-match']) || isset($headers['If-None-Match'])){ $Etag = isset($headers['if-none-match']) ? $headers['if-none-match'] : $headers['If-None-Match']; } //offline值需要进入离线 if(isset($offline) && $offline !== 'false'){ //取响应内容的md5 $md5 = sha1($outContent); //304命中离线缓存 if($Etag === $md5) { header('Cache-Offline: store'); header('Content-Length: 0'); header('HTTP/1.1 304 Not Modified'); exit; } header('Etag: '.$md5); } $outContent = self::wnsHtmlDiffDivision($outContent); header('Content-Length:'.strlen($outContent)); } echo $outContent; } public static function wnsHtmlDiffDivision($htmlStr){ $htmlMd5 = sha1($htmlStr); $headers = getallheaders(); $clientTemplateTag = NULL; if(isset($headers['template-tag'])){ $clientTemplateTag = $headers['template-tag']; } preg_match('//i', $htmlStr, $titleMatchs); $title = ''; if(isset($titleMatchs[0])) { $title = $titleMatchs[0]; } $templateHtml = preg_replace('//i', '{title}', $htmlStr); $templateReplace = new TemplateReplace(); $templateHtml = preg_replace_callback('/[\s\S]+?/i', array($templateReplace, 'callback'),$templateHtml); //转换模板为buffer,再获取模板md5,作为template-tag $templateMd5 = sha1($templateHtml); //加个头,告诉客户端,我是一个diff结构的响应 //var_dump($clientTemplateTag, $templateMd5); exit; header('template-tag: '.$templateMd5); //结构化数据 $result = array( 'data' =>array(), 'template-tag' => $templateMd5 ); $result['data']['{title}'] = $title; // 设置数据块数据 $diffTagNames = TemplateReplace::$diffTagNames; foreach($diffTagNames as $i => $diffTagName) { if(isset($diffTagNames[$i])) { $result['data']['{'.$i.'}'] = $diffTagNames[$i]; } } $result['html-sha1'] = $htmlMd5; $resultStr = ''; if($templateMd5 === $clientTemplateTag){ header('template-change: false'); //离线模板没有差异,不用更新 $result['diff'] = ''; $resultStr = json_encode($result); } else { if($templateMd5 != $clientTemplateTag){ header('template-change: true'); } //客户端没有带离线版本,直接全量即可 $resultStr = $htmlStr; } return $resultStr; } } ================================================ FILE: sonic-php/sample/view/demo_template.php ================================================ SONIC

Sonic:轻量级的高性能的Hybrid框架

Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架,专注于提升H5页面首屏加载速度,让H5页面的体验更加接近原生,提升用户体验及用户留存率。

示例:

非Sonic模式 点击到页面打开耗时:

普通直出的方式

首次访问 点击到页面打开耗时:

用户第一次访问,本地无缓存;使用直出的方式,终端生成缓存。

模版更新 点击到页面打开耗时:

本地模版跟服务器模版不一样;缓存失效,清除缓存,重新加载页面。

数据更新 点击到页面打开耗时:

模板一致,数据变更;针对页面局部数据变化的场景,Sonic会预先加载本地缓存再将变化部分的数据异步更新,提升用户体验。

完全缓存 点击到页面打开耗时:

本地数据与服务器数据完全一样;直接使用缓存,页面秒开。

页面打开速度效果对比

以手机QQ-VIP中心首页为例,在接入Sonic框架之后,页面打开速度在数据更新场景下优化提升42%,页面内容不变的场景下(完全cache模式)优化提升50%以上。

原有直出页面: Sonic改造页面:

Sonic实现原理简介

Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源,在移动终端初始化的同时并行请求页面主资源并做到流式拦截,减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据),该框架能做到智能地对页面内容进行动态缓存和增量更新,减少对网络的依赖,节省用户流量,加快页面打开速度。

================================================ FILE: sonic-php/sdk/sonic.php ================================================ $value) { if (substr($name, 0, 5) == 'HTTP_') { $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value; } } return $headers; } } class TemplateReplace{ public static $shotWnsDiffBodyReplace = false; //判断是否成功替换sonicdiffbody public static $diffIndex = 0; public static $tagPrefix = 'auto'; public static $diffTagNames = array(); //数据块 public function callback($matches) { if(isset($matches) && isset($matches[0])) { self::$shotWnsDiffBodyReplace = true; if(isset($matches[1])) { $tagName = $matches[1]; } else { $tagName = self::$tagPrefix.self::$diffIndex++; } self::$diffTagNames[$tagName] = $matches[0]; return '{'.$tagName.'}'; } } } class util_sonic { public static function start(){ ob_start(); $_SERVER['PHP_SONIC'] = '1'; } public static function end() { $outContent = ob_get_clean(); $headers = getallheaders(); if(isset($headers['accept-diff']) && $headers['accept-diff'] === 'true'){ header('Cache-Control: no-cache'); $offline = 'true'; header("Cache-Offline: $offline"); $Etag = NULL; if(isset($headers['if-none-match']) || isset($headers['If-None-Match'])){ $Etag = isset($headers['if-none-match']) ? $headers['if-none-match'] : $headers['If-None-Match']; } //offline值需要进入离线 if(isset($offline) && $offline !== 'false'){ //取响应内容的md5 $md5 = sha1($outContent); //304命中离线缓存 if($Etag === $md5) { header('Cache-Offline: store'); header('Content-Length: 0'); header('HTTP/1.1 304 Not Modified'); exit; } header('Etag: '.$md5); } $outContent = self::wnsHtmlDiffDivision($outContent); header('Content-Length:'.strlen($outContent)); } echo $outContent; } public static function wnsHtmlDiffDivision($htmlStr){ $htmlMd5 = sha1($htmlStr); $headers = getallheaders(); $clientTemplateTag = NULL; if(isset($headers['template-tag'])){ $clientTemplateTag = $headers['template-tag']; } preg_match('//i', $htmlStr, $titleMatchs); $title = ''; if(isset($titleMatchs[0])) { $title = $titleMatchs[0]; } $templateHtml = preg_replace('//i', '{title}', $htmlStr); $templateReplace = new TemplateReplace(); $templateHtml = preg_replace_callback('/[\s\S]+?/i', array($templateReplace, 'callback'),$templateHtml); //转换模板为buffer,再获取模板md5,作为template-tag $templateMd5 = sha1($templateHtml); //加个头,告诉客户端,我是一个diff结构的响应 //var_dump($clientTemplateTag, $templateMd5); exit; header('template-tag: '.$templateMd5); //结构化数据 $result = array( 'data' =>array(), 'template-tag' => $templateMd5 ); $result['data']['{title}'] = $title; // 设置数据块数据 $diffTagNames = TemplateReplace::$diffTagNames; foreach($diffTagNames as $i => $diffTagName) { if(isset($diffTagNames[$i])) { $result['data']['{'.$i.'}'] = $diffTagNames[$i]; } } $result['html-sha1'] = $htmlMd5; $resultStr = ''; if($templateMd5 === $clientTemplateTag){ header('template-change: false'); //离线模板没有差异,不用更新 $result['diff'] = ''; $resultStr = json_encode($result); } else { if($templateMd5 != $clientTemplateTag){ header('template-change: true'); } //客户端没有带离线版本,直接全量即可 $resultStr = $htmlStr; } return $resultStr; } } ================================================ FILE: sonic-react/README.md ================================================ ## Getting started with React [![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls) [![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki) --- ## How to use the demo >This demo will give you a quick start for using Sonic with React. ### Dependencies Node Version > 7.0 ### Installation ```bash git clone https://github.com/Tencent/VasSonic.git cd /sonic-react npm install # Install project dependencies ``` ### Usage ```bash npm run build # Builds the application to ./.next npm start # Start the development server ``` Now you can visit http://localhost:3000/demo to view this demo using Mobile Emulation Mode in Chrome dev tools. ## How to use Sonic on server-side >NOTE: This demo using Server Side Rendering (SSR) with [Redux](https://redux.js.org/), [Next.js](https://github.com/zeit/next.js/) and [Koa2](http://koajs.com/). 1. Add comment tags to separate **template** and **data blocks** in html files which will be published from the server. The **data blocks** should begin with a html comment like `` and close with ``(the moduleName is custom). And the other part of the html is called **template** in Sonic. In this demo, it is implemented like the code shown below. - Below is the origin html, we will generate comment tags according to the `data-sonicdiff` attribute and the script block including `__NEXT_DATA__`: ```HTML … …
… …
… … ``` - Then, we have a transform function at server side: ```js function formatHtml(html) { const $ = cheerio.load(html); $('*[data-sonicdiff]').each(function(index, element) { let tagName = $(this).data('sonicdiff'); return $(this).replaceWith('' + $(this).clone() + ''); }); html = $.html(); html = html.replace(/\s*__NEXT_DATA__\s*=([\s\S]+?)<\/script>/ig, function(data1) { return '' + data1 + ''; }); return html; } ``` - After the transform, the latest code user will received will be like: ```HTML … … +
… …
+ … … + + ``` 2. Intercept the html response from server and use [sonic_differ](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/common/diff.js) module to process the response. ```js server.use(async (ctx, next) => { await next(); // only intercept html request if (!ctx.response.is('html')) { return; } // process non-sonic mode if (!ctx.request.header['accept-diff']) { ctx.body = ctx.state.resHtml; return; } // use sonic_differ module to process the response let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml)); if (sonicData.cache) { // 304 Not Modified, return nothing. ctx.body = ''; } else { // other Sonic status. ctx.body = sonicData.data; } }); ``` For more details please refer to [server.js](https://github.com/Tencent/VasSonic/blob/master/sonic-react/server.js). ## How to use Sonic on client-side Handle the response from mobile client which include Sonic response code and diff data in `componentDidMount()`. ```js componentDidMount() { // handle the response from mobile client which include Sonic response code and diff data. this.getSonicData((status, sonicUpdateData) => { switch (status) { // here, we only process the case when data updates case 3: // update the Redux store based on changes from the mobile client let initState = sonicUpdateData['{initState}'] || ''; initState.replace(/\s* * * * * * @param html {string} 原始 HTML 字符串 * @returns {string} 添加注释标签后的 HTML 字符串 */ function formatHtml(html) { const $ = cheerio.load(html); $('*[data-sonicdiff]').each(function(index, element) { let tagName = $(this).data('sonicdiff'); return $(this).replaceWith('' + $(this).clone() + ''); }); html = $.html(); html = html.replace(/\s*__NEXT_DATA__\s*=([\s\S]+?)<\/script>/ig, function(data1) { return '' + data1 + ''; }); return html; } ``` - 服务端使用 [sonic_differ](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/common/diff.js) 模块对数据进行处理后输出给浏览器。 ```js server.use(async (ctx, next) => { await next(); // 只拦截 html 请求 if (!ctx.response.is('html')) { return; } // 非 sonic 模式不做特殊处理 if (!ctx.request.header['accept-diff']) { ctx.body = ctx.state.resHtml; return; } // 使用 sonic_differ 模块对数据进行处理 let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml)); if (sonicData.cache) { // sonic 模式:完全缓存 ctx.body = ''; } else { // 其它 sonic 状态 ctx.body = sonicData.data; } }); ``` - 前端在执行到 componentDidMount() 阶段时,通过 js 调用终端接口来获取 sonic 状态和数据,根据终端返回的不同状态,来决定如何渲染页面。 ```js componentDidMount() { // 获取客户端返回的 sonic 状态和数据,根据终端返回数据做出相应的处理 this.getSonicData((status, sonicUpdateData) => { switch (status) { // sonic 状态:数据更新 case 3: // 使用客户端返回的数据更新页面 Store let initState = sonicUpdateData['{initState}'] || ''; initState.replace(/\s*
); } } const mapDispatchToProps = (dispatch) => { return { setSonicStatus: bindActionCreators(setSonicStatus, dispatch), // set sonic status initImgArr: bindActionCreators(initImgArr, dispatch) // initialize image array }; }; export default withRedux(initStore, null, mapDispatchToProps)(App); ================================================ FILE: sonic-react/redux/duck.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ import { createStore, applyMiddleware } from 'redux'; import { composeWithDevTools } from 'redux-devtools-extension'; import thunkMiddleware from 'redux-thunk'; const defaultInitialState = { sonicStatus: '--', gameArea: { initSeqArr: [], imgArr: [], selImgIndex: [] } }; // ------------------------------------ // Constants // ------------------------------------ export const actionTypes = { GET_SONIC_STATUS: 'GET_SONIC_STATUS', INIT_IMG_ARR: 'INIT_IMG_ARR' }; // ------------------------------------ // Actions // ------------------------------------ const setSonicStatusAct = (res) => ({ type: actionTypes.GET_SONIC_STATUS, sonicStatus: res }); const initImgArrAct = (res) => ({ type: actionTypes.INIT_IMG_ARR, gameArea: res }); // ------------------------------------ // Specialized Action Creator // ------------------------------------ export const setSonicStatus = (sonicStatus) => async (dispatch, getState) => { try { let statusWording = ''; switch (sonicStatus) { case 0: statusWording = '异常'; break; case 1: statusWording = '首次加载'; break; case 2: statusWording = '模板更新'; break; case 3: statusWording = '数据更新'; break; case 4: statusWording = '完全缓存'; break; default: statusWording = '异常'; break; } await dispatch(setSonicStatusAct(statusWording)); } catch (error) { console.log('error: ', error); } }; export const initImgArr = (imgArrState) => async (dispatch, getState) => { try { if (imgArrState) { await dispatch(initImgArrAct(imgArrState)); return; } let initSeqArr = [1, 2, 3, 4]; let initSeqArrTmp = initSeqArr.slice(0); let initImgArr = []; while (initSeqArr.toString() === initSeqArrTmp.toString()) { initSeqArrTmp.sort(() => { return Math.random() - 0.5; }); } initSeqArrTmp.forEach((i) => { initImgArr.push({ 'src': '/static/img/jigsaw/' + i + '.jpg', 'index': i }); }); await dispatch(initImgArrAct({ initSeqArr, imgArr: initImgArr, selImgIndex: [] })); } catch (error) { console.log('error: ', error); } }; // ------------------------------------ // Reducer // ------------------------------------ export const reducer = (state = defaultInitialState, action) => { switch (action.type) { case actionTypes.GET_SONIC_STATUS: return { ...state, sonicStatus: action.sonicStatus }; case actionTypes.INIT_IMG_ARR: return { ...state, gameArea: action.gameArea }; default: return state; } }; export const initStore = (initialState = defaultInitialState) => { return createStore(reducer, initialState, composeWithDevTools(applyMiddleware(thunkMiddleware))); }; ================================================ FILE: sonic-react/server.js ================================================ /** * Tencent is pleased to support the open source community by making VasSonic available. * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://opensource.org/licenses/BSD-3-Clause * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ const Koa = require('koa'); const next = require('next'); const Router = require('koa-router'); const cheerio = require('cheerio'); const sonicDiff = require('sonic_differ'); const port = parseInt(process.env.PORT, 10) || 3000; const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev }); const handle = app.getRequestHandler(); /** * add comment tags to separate template and data blocks from the initial html * * Example: * * * * * … … … … *
=> * … …
*
… … * … …
* * * * * * @param html {string} the initial html * @returns {string} html with comment tags which help sonic to splits the html to template and data */ function formatHtml(html) { const $ = cheerio.load(html); $('*[data-sonicdiff]').each(function(index, element) { let tagName = $(this).data('sonicdiff'); return $(this).replaceWith('' + $(this).clone() + ''); }); html = $.html(); html = html.replace(/\s*__NEXT_DATA__\s*=([\s\S]+?)<\/script>/ig, function(data1) { return '' + data1 + ''; }); return html; } app.prepare().then(() => { const server = new Koa(); const router = new Router(); // intercept request and render html string only if at a given URL router.get('/demo', async ctx => { ctx.set('Content-Type', 'text/html'); ctx.state.resHtml = await app.renderToHTML(ctx.req, ctx.res, ctx.path, ctx.query); }); router.get('*', async ctx => { ctx.set('Cache-Control', 'max-age:30'); await handle(ctx.req, ctx.res); }); server.use(async (ctx, next) => { await next(); // only intercept html request if (!ctx.response.is('html')) { return; } // process non-sonic mode if (!ctx.request.header['accept-diff']) { ctx.body = ctx.state.resHtml; return; } // use sonic_differ module to process the data let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml)); if (sonicData.cache) { // 304 Not Modified, return nothing. ctx.body = ''; } else { // other Sonic status. ctx.body = sonicData.data; } }); server.use(router.routes()); server.listen(port, (err) => { if (err) { throw err; } console.log(`> Ready on http://localhost:${port}`); }); }); ================================================ FILE: sonic-react/static/js/flexible.js ================================================ !function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=a.navigator.userAgent,q=(!!p.match(/android/gi),!!p.match(/iphone/gi)),r=q&&!!p.match(/OS 9_3/),s=a.devicePixelRatio;i=q&&!r?s>=3&&(!i||i>=3)?3:s>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var t=e.createElement("div");t.appendChild(g),e.write(t.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));