[
  {
    "path": ".gitignore",
    "content": "# MacOS\n.DS_Store\n\n# Windows\n*.txt\n.idea/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to VasSonic\nWelcome 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. \n\n## Issues\nWe use Github Issues to track public bugs and feature requests.\n\n### Search Known Issues First\nPlease 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.\n\n### Reporting New Issues\nIf 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.\n\n## Pull Requests\nWe strongly welcome your pull request to make VasSonic better. \n\n### Branch Management\nThere are two main branches here:\n\n1. `master` branch.\n\t1. It is the latest (pre-)release branch. We use `master` for tags, with version number `1.1.0`, `1.2.0`, `1.3.0`...\n\t2. **Don't submit any PR on `master` branch.**\n2. `dev` branch. \n\t1. It is our stable developing branch. After full testing, `dev` will be merged to `master` branch for the next release.\n\t2. **You are recommended to submit bugfix or feature PR on `dev` branch.**\n\nNormal bugfix or feature request should be submitted to `dev` branch. After full testing, we will merge them to `master` branch for the next release. \n\n```\nmaster\n ↑\ndev   \n ↑ \nfeature/bugfix PR\n```  \n\n### Make Pull Requests\nThe 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.\n\nBefore submitting a pull request, please make sure the followings are done:\n\n1. Fork the repo and create your branch from `master`.\n2. Update code or documentation if you have changed APIs.\n3. Add the copyright notice to the top of any new files you've added.\n4. Check your code lints and checkstyles.\n5. Test and test again your code.\n6. Now, you can submit your pull request on `dev`.\n\n## Code Style Guide\nUse [Code Style](https://github.com/Tencent/VasSonic/blob/master/checkstyle.xml) for Java and Android.\n\n* 4 spaces for indentation rather than tabs\n\n## License\nBy contributing to VasSonic, you agree that your contributions will be licensed\nunder its [BSD LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n"
  },
  {
    "path": "ISSUE_TEMPLATE",
    "content": "What steps will reproduce the problem? \n该问题的重现步骤是什么？\n1. \n2. \n3. \n\n\nWhat is the expected output? What do you see instead? \n你期待的结果是什么？实际看到的又是什么？\n\n\nWhat version of the product are you using? On what operating system? \n你正在使用产品的哪个版本？在什么操作系统上？\n\n\nPlease provide any additional information below.\n如果有的话，请在下面提供更多信息。\n"
  },
  {
    "path": "LICENSE",
    "content": "Tencent is pleased to support the open source community by making VasSonic available.  \nCopyright (C) 2017 THL A29 Limited, a Tencent company.  All rights reserved.\nIf you have downloaded a copy of the VasSonic binary from Tencent, please note that the VasSonic binary is licensed under the \nBSD 3-Clause License.\nIf you have downloaded a copy of the VasSonic source code from Tencent, please note that VasSonic source code is licensed under\nthe BSD 3-Clause License, except for the third-party components listed below which are subject to different license terms.\nYour integration of VasSonic into your own projects may require compliance with the BSD 3-Clause License, as well as the other \nlicenses applicable to the third-party components included within VasSonic.\nA copy of the BSD 3-Clause License is included in this file.\n\nOther dependencies and licenses:\n\nOpen Source Software Licensed Under the Apache License, Version 2.0: \n----------------------------------------------------------------------------------------\n1. Android Source Code  4.4_r1\nCopyright (C) 2005-2015 The Android Open Source Project\n\n\nTerms of the Apache License, Version 2.0:\n--------------------------------------------------------------------\nApache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 \nof this document.\n\n“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\n\n“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are \nunder common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect,\nto cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) \nor more of the outstanding shares, or (iii) beneficial ownership of such entity.\n\n“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.\n\n“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, \ndocumentation source, and configuration files.\n\n“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but \nnot limited to compiled object code, generated documentation, and conversions to other media types.\n\n“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by\na copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\n\n“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for \nwhich the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. \nFor the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) \nto the interfaces of, the Work and Derivative Works thereof.\n\n“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or \nadditions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the \ncopyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this \ndefinition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, \nincluding but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems \nthat are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication \nthat is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”\n\n“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor\nand subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, \nworldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, \npublicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, \nworldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, \nuse, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims \nlicensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) \nwith the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including \na cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct \nor contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate\nas of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without \nmodifications, and in Source or Object form, provided that You meet the following conditions:\n\na) \tYou must give any other recipients of the Work or Derivative Works a copy of this License; and\n\nb) \tYou must cause any modified files to carry prominent notices stating that You changed the files; and\n\nc) \tYou must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, \nand attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\n\nd) \tIf the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must \ninclude a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain \nto any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the \nDerivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated \nby the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational \npurposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, \nalongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as \nmodifying the License. \n\nYou may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions \nfor use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, \nreproduction, and distribution of the Work otherwise complies with the conditions stated in this License. \n\n5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the \nWork by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. \nNotwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed \nwith Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of \nthe Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of \nthe NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor \nprovides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, \nwithout limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. \nYou are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated \nwith Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, \nunless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor \nbe liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as \na 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, \nwork stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been \nadvised of the possibility of such damages.\n9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, \nand charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with \nthis License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, \nnot on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for \nany liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or\nadditional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by \nbrackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the \nappropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included\non the same \"printed page\" as the copyright notice for easier identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\nhttp://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n\nTerms of the BSD 3-Clause License:\n--------------------------------------------------------------------\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the \nfollowing conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer \nin the documentation and/or other materials provided with the distribution.\n3. Neither the name of [copyright holder] nor the names of its contributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, \nBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \nTHE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "## VasSonic: A Lightweight And High-performance Hybrid Framework\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n<p align=\"center\">\n  <img alt=\"logo\" src=\"https://github.com/Tencent/VasSonic/blob/master/assets/logo.png\"/>\n</p>\n\nVasSonic 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.\n 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. \n\n 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.\n 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.\n\n VasSonic can cache html cleverly according to VasSonic Specification obeyed by client and server.\n 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.\n According to this, VasSonic request less data by incremental updating templates and data, the websites are faster and feel more like native application.\n In conclusion, VasSonic effectively enhance the user experience and increase click rate, retention rate and other indicators.\n\n Sonic is called for short in project.\n\n### Before VS After Using VasSonic\n\nPic 1: Before Using VasSonic |  Pic 2: After Using VasSonic\n:-------------------------:|:-------------------------:\n![default mode][1]  |  ![VasSonic mode][2]\n\n## Getting started\n\n[Getting started with Android](https://github.com/Tencent/VasSonic/blob/master/sonic-android/README.md)\n\n[Getting started with iOS](https://github.com/Tencent/VasSonic/blob/master/sonic-iOS/README.md)\n\n[Getting started with Java](https://github.com/Tencent/VasSonic/blob/dev/sonic-java/README.md)\n\n[Getting started with Node.js](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/README.md)\n\n[Getting started with PHP](https://github.com/Tencent/VasSonic/blob/master/sonic-php/README.md)\n\n[Getting started with React](https://github.com/Tencent/VasSonic/blob/master/sonic-react/README.md)\n\n## Demo Downloads\n1. [Here](https://github.com/Tencent/VasSonic/releases) are the latest sample demo for Android and iOS.\n\n\n## Support\nAny problem?\n\n1. Learn more from the following sample. </br>\n[Android sample](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sample)  </br>\n[iOS sample](https://github.com/Tencent/VasSonic/tree/master/sonic-iOS/SonicSample) </br>\n[Java sample](https://github.com/Tencent/VasSonic/tree/dev/sonic-java/sample/webapp) </br>\n[Node.js sample](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs) </br>\n[PHP sample](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sample) </br>\n[React sample](https://github.com/Tencent/VasSonic/tree/master/sonic-react) </br>\n\n2. Read the following source code </br>\n[Android source code](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sdk) </br>\n[iOS source code](https://github.com/Tencent/VasSonic/tree/master/sonic-iOS/Sonic)  </br>\n[Java source code](https://github.com/Tencent/VasSonic/tree/dev/sonic-java/src/main/java/com/github/tencent)\n[Node.js source code](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs) </br>\n[PHP source code](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sdk) </br>\n[React source code](https://github.com/Tencent/VasSonic/tree/master/sonic-react) </br>\n\n3. Read the [wiki](https://github.com/Tencent/VasSonic/wiki) for help.\n\n4. Contact [us](https://jq.qq.com/?_wv=1027&k=4EaxB4K) or scan QR code for help.</br>\n![QR code][3]\n\n## Contributing\nFor more information about contributing issues or pull requests, see our [VasSonic Contributing Guide](https://github.com/Tencent/VasSonic/blob/master/CONTRIBUTING.md).\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n## The End\nIf you are interested in VasSonic, don't forget to STAR [it](https://github.com/Tencent/VasSonic). \n\nVasSonic's mission is MAKING WEB MUCH BETTER!\n\nThank you for reading ~\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/assets/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/assets/20170705120029897.gif\n[3]: https://github.com/Tencent/VasSonic/blob/master/assets/QR.JPG\n[4]: https://github.com/Tencent/VasSonic/blob/master/assets/logo.png\n\n"
  },
  {
    "path": "assets/Sonic2.0.md",
    "content": "Sonic 2.0相比1.0，主要新增了以下几个特性：\n* 支持纯终端模式（Local Server模式），在该模式下无需后台配合亦可完成秒开；\n* 支持自定义请求头和自定义响应头；\n* 支持Cache-Control来控制缓存生命周期；\n* 支持非utf-8编码。\n\n# Local Server模式\n\n## Local Server模式介绍\nLocal Server模式是Sonic 2.0新增的纯终端模式，相比于Sonic 1.0需要终端、前端、后台全部改造接入Sonic，Local Server模式可以在业务后台无法及时支持时，通过终端模拟Server实现Sonic逻辑，从而降低接入成本。\n\nLocal Server的开启方式如下：\n    \n    SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n    sessionConfigBuilder.setSupportLocalServer(true);\n    sessionConfigBuilder.build();\n\n开启Local Server模式后，对于一般页面的请求，Sonic会模拟Sonic后台，对返回的页面数据进行eTag的计算，以及模板和数据的拆分，对比本地缓存的数据，添加sonic响应头（eTag、template-change、template-tag）。最后根据Server数据和本地缓存数据的对比结果，来决定此次请求模式是完全缓存、局部刷新还是模板更新，从而执行不同的刷新逻辑。后台无需接入sonic，也能体验页面秒开。\n\n## Local Server执行流程\n### 1、首次请求\n首次请求也就是无缓存情况下发起的请求，与普通Sonic无缓存模式流程一致。具体细节可参考QuickSonicSession和StandardSonicSession的无缓存模式流程。\n\n### 2、非首次请求\n非首次请求也就是有缓存情况下发起的请求，分为完全缓存、局部刷新、模板变更三种情况。\n\n#### (1) 完全缓存\n\n完全缓存就是本地的数据跟服务器的数据是完全一样的。以Quick模式为例，Local Server的执行流程如下图：\n\n![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeCache.png)\n\n上图主要展示了两条并行线，左边是在主线程执行的Webview流程，右边是在子线程执行Sonic流程。\n\n**Sonic线程：**\nSonic会话创建完成后，首先获取url对应的本地缓存数据，并通知主线程Webview加载该数据。接着Sonic会与Server建立连接，如果Server返回304，则Server数据没有变更，直接使用本地缓存，Sonic流程结束；否则，Sonic拉取到完整的Server数据，计算其SHA1作为eTag，如果与请求头中的eTag相同，就确定本次请求是完全缓存模式，Sonic流程结束。 \n\n**主线程：**\n主线程在收到Sonic通知后，加载本地缓存数据，交给Webview渲染。\n\n#### (2) 局部刷新\n\n局部刷新就是本地的数据跟服务器的数据相比，只有data部分有变化，模板与服务器一样。\n\n![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeDataUpdate.png)\n\n**Sonic线程：**\nSonic会话创建完成后，首先获取url对应的本地缓存数据，并通知主线程Webview加载该数据。接着Sonic与Server建立连接，读取到完整的Server数据，计算其SHA1作为eTag，如果与请求头中的eTag不同，Sonic将Server数据拆分为template和data，计算template的SHA1作为template-tag，如果与请求头中的template-tag相同，则说明模板没有变更，此时确定本次请求是局部刷新，将拆分得到的data与本地保存的data做对比计算，得到增量数据。最后通知Webview进行局部刷新，并更新本地缓存。\n\n**主线程：**\n局部刷新模式下主线程会先收到加载本地缓存数据的通知，而Sonic线程通知主线程刷新data时，主线程可能还未开始加载本地缓存，也可能已经开始渲染本地缓存。如果WebView还未开始加载本地缓存，就会直接加载最新的数据（拆分得到的data跟本地模版合成的数据）；如果主线程已经加载本地缓存，就会直接通过Js接口让WebView用增量数据刷新页面。\n\n#### (3) 模板更新\n\n模板更新是本地的模板跟服务器的模板不一致。\n\n![LocalServer流程](https://github.com/Tencent/VasSonic/blob/master/assets/LocalServerModeTemplateChange.png)\n\n**Sonic线程：**\nSonic会话创建完成后，首先获取url对应的本地缓存数据，并通知主线程Webview加载该数据。接着Sonic与Server建立连接，读取到完整的Server数据，计算其SHA1作为eTag，如果与请求头中的eTag不同，Sonic将Server数据拆分为template和data，计算template的SHA1作为template-tag，如果与请求头中的template-tag不同则说明模板发生了变更，此时确定本次请求是模板刷新模式，通知主线程Webview进行模板刷新，并更新本地缓存。 \n\n**主线程：**\n主线程会先收到加载本地缓存数据的通知，之后Sonic线程通知主线程进行模板刷新时，无论WebView是否已经开始加载本地缓存数据，都会直接重新加载最新的Server数据，完成模板刷新。\n\n# 其他新增特性\n### 1、支持自定义请求头和自定义响应头\nSonic 2.0支持添加自定义请求头和自定义响应头，添加方式如下：\n\n    SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n    sessionConfigBuilder.setCustomRequestHeaders(requestHeaderMap);\n\tsessionConfigBuilder.setCustomResponseHeaders(responseHeaderMap);\n    sessionConfigBuilder.build();\n\n### 2、支持Cache-Control来控制缓存生命周期\nSonic 2.0支持在Http响应头部添加Cache-Control字段来控制缓存生命周期，目前支持max-age、private、public三个可选值。\n\n\n### 3、支持非UTF-8编码\nSonic 2.0优化了字符编码的使用。如果http响应头中包含\"Content-Type\"字段，则优先使用该字段的值作为字符编码，否则默认使用UTF-8编码。\n\n# FAQ\n\n### 1、Sonic后台返回的数据与非sonic后台返回的数据的区别？\n     \n接入了Sonic的Server返回的数据，http响应头会包含\"cache-offline\"、\"template-change\"或者\"template-tag\"字段，而未接入Sonic的Server返回的数据，响应头中不会包含以上三个字段。\n\n### 2、Local Server模式的优缺点？\n\n**优点：**\nLocal Server模式下，简化了终端执行逻辑；而且无需后台接入Sonic，大大减少了接入成本。  \n**缺点：**\nLocal Server模式相比后台接入，损失了一定的性能。因为终端模拟后台的话，非首次请求场景需要等Server数据全部返回才能计算eTag，template-tag，template-change，从而判断是哪种模式（完全缓存、局部刷新还是模板更新）。\n"
  },
  {
    "path": "assets/VasSonic3.0_preload.md",
    "content": "# Sonic 3.0 子资源预下载功能特性介绍\n\n## 1 子资源预下载\n\nVasSonic中子资源预下载功能的灵感就来源于Chrome中的\\<link rel='preload'/>。\n> \\<link rel='preload'/>：\\<link>元素的rel属性的属性值preload能够让你在你的HTML页面中\\<head>元素内部书写一些声明式的资源获取请求，可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源，你可能希望在页面加载的生命周期的早期阶段就开始获取，在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用，且更不易阻塞页面的初步渲染，进而提升性能。\n\n### 1.1 子资源预下载开启方式\n想要开启VasSonic 3.0中的子资源预下载功能，需要终端或者后台参与。在请求主资源时，由后台在Response Header中添加一个名为```sonic-link```的响应头部字段，这个字段的值指定了期望得到预下载的子资源，不同的子资源url之间由\";\"区分。可以预下载的子资源类型包括图片、css样式文件、js脚本文件等等。示例如下：\n\n```http\nsonic-link: http://test.js;http://test.css;http://test.jpg\n```\n\n除了后台返回```sonic-link```相应头，也可以通过终端指定```sonic-link```，方式如下：\n\n```java\nSonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\nMap<String, String> headers = new HashMap<String, String>();\nheaders.put(\"sonic-link\", \"http://test.js;http://test.css;http://test.jpg\");\nsessionConfigBuilder.setCustomResponseHeaders(headers);\nsessionConfigBuilder.build();\n```\n\n### 1.2 子资源预下载的流程说明\nVasSonic检测到主资源响应头中的```sonic-link```字段时，子资源预下载模块就会开始工作，具体执行流程如下图：\n\n![子资源预下载模块的流程](subresource_preload.png)\n\n1. 对```sonic-link```字段中的字资源进行下载是在单独的预下载线程中进行；  \n2. 当内核请求的子资源url不在```sonic-link```头中时，VasSonic不做处理，完全抛给内核；  \n3. 当内核请求的子资源url在```sonic-link```头中时，有以下四种情况： \n    - 如果对应的子资源有缓存且缓存不过期，则直接加载该缓存；\n    - 如果对应的子资源没有缓存，且子资源下载处于排队状态，抛给内核处理（Sonic仍会完成该资源的下载并进行缓存）；\n    - 如果对应的子资源没有缓存，且子资源正在下载，则将已下载的内存数据和未下载的网络流数据组成桥接流给内核；\n    - 如果对应的子资源没有缓存，且子资源已下载完成，则将下载完成的子资源数据给内核。\n\n### 1.3 子资源缓存相关\n子资源完成预下载之后会在本地进行缓存，缓存规则如下：\n1. 子资源数据和子资源响应头数据会分别进行缓存，子资源url的MD5作为子资源数据缓存文件名，子资源url的MD5.header作为子资源响应头缓存的文件名。\n2. 子资源和子资源响应头的缓存数据都保存在```/sdcard/SonicResource/```目录下；\n2. 子资源缓存的过期过期时间由```sonic-link```头中子资源url参数```max-age```唯一决定；\n3. 一旦本地子资源缓存被恶意篡改，被篡改过的子资源不会通过VasSonic校验，该缓存会被删除；\n4. 默认每隔24小时进行一次缓存检查，如果超过大小限制（默认60M，可设置），会进行一次缓存清理。\n\n使用如下方式进行缓存相关设置：\n\n```java\nSonicConfig.Builder builder = new SonicConfig.Builder();\n\n// 设置缓存校验方式为校验文件大小，默认为对文件内容进行Sha1校验\nbuilder.setCacheVerifyWithSha1(false);\n\n// 设置子资源缓存最大为100M，默认为60M\nbuilder.setResourceCacheMaxSize(100 * 1024 * 1024);\n\n// 设置缓存大小检查时间间隔为12小时，默认为24小时\nbuilder.setCacheCheckTimeInterval(12 * 60 * 60 * 1000L);\n\nbuilder.build();\n```\n"
  },
  {
    "path": "assets/sonic发展历程.md",
    "content": "# VasSonic成长历程\n## 1.前言\n2017年8月8日，腾讯SNG增值产品部技术团队(以下简称VAS)研发的轻量级高性能Hybrid框架VasSonic通过了公司最终审核，作为腾讯开源组件的一份子分享给大家。从当初立项优化页面加载速度，到不断摸索、优化，再到整理代码、文档，最终在Github上开源，并且在24小时内获取star数超过1600。我们非常高兴看到我们的成果收到这么多的关注，趁此机会，正好回顾一下VasSonic的成长历程，也希望能够让大家更了解VasSonic。\n\n## 2.项目背景\n\nWeb相信大家再熟悉不过了，它具有快速迭代发布的天然优势，但也存在一些让人诟病的问题，比如加载速度慢，体验差等。在此之前，手Q上很多页面首屏打开速度居高不下，甚至有些耗时达到3s以上，这意味着用户打开页面必须经过3秒之后才能进行交互操作，体验相当差，很多用户忍受不了这个漫长的时间直接流失掉了。\n\n为了提升用户体验和业务用户留存率，我们很多业务一开始通过Web开发，等页面模型验证符合预期后，再将H5页面转化成原生界面。我们很快意识到这不是一种健康的可持续的开发模式，一方面存在重复人力浪费，另外一方面原生商城除了速度快一点，要运营活动改版都很难。\n\n所以后来团队改了切入方向，安排人力专心研究如何加快页面打开速度。经过了一系列的摸爬滚打和优化探索,最终我们研发出了VasSonic框架，让H5页面首屏达到秒开，给用户一个更好的H5体验。期间也曾和空间技术团队共同合作将空间的首屏优化方案wns-html引入到手Q中(共同命名为webso方案)进行尝试，虽然在我们业务使用过程中存在部分场景体验较差，但webso中页面模板和数据分离等思路给VasSonic框架的发展提供了很好的帮助，在此特别感谢webso技术团队的贡献。下面就和大家分享VasSonic框架的发展历程。\n\n## 3.业务形态\n任何一个技术框架都是结合具体的业务形态来进行发展优化的，技术是为了更好地服务业务，业务也会驱动技术的发展。因此在此首先介绍一下业务形态，我们是来自手Q增值产品部门的VAS团队，负责手机QQ上很多深受年轻人喜欢的个性化增值服务，比如气泡、挂件、主题等等。手Q上大部分的业务还是基于H5开发的，大家对手Q的业务形态可能有简单的了解。比如游戏分发中心、会员特权中心、个性化装扮商城等。这部分商城的特点比较明显，页面的很多数据都是动态的，是由我们的产品经理在后台配置的。\n![业务](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870447_pr_yewu.png)\n\n\n这些都是很常见页面，我们通常将html/js/css等静态资源放到CDN上，然后页面加载后，再通过CGI去拉取最新的数据，进行拼接展示， 这样子可以利用到CDN的多地部署和就近接入等优势，同时提高了服务器的并发能力。这种传统模式的加载流程如下所示： </br>\n![加载流程](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870478_pr_jiazai.png)\n1. 用户点击后，经过终端一系列初始化流程，比如进程启动、Runtime初始化、创建WebView等等。\n2. 完成初始化后，WebView开始去CDN上面请求Html加载页面。\n3. 页面发起CGI请求对应的数据或者通过localStorage获取数据，数据回来后再对DOM进行操作更新\n\n\n可以看出上述流程存在着几个问题：\n\n![问题](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870570_pr_question.png)\n\n1. 从外网统计数据来看，用户的终端耗时在1s以上，这意味着在这1s多的时间里，网络完全是空闲在等待的，非常浪费；\n2. 页面的资源和数据完全依赖于网络，特别是用户在弱网络场景下，页面会出现很长时间的白屏，体验非常差；\n3. 因为页面的数据依赖于动态拉取，加载完页面后，往往是看到一些模块先转菊花，再展示，体验也是不好的。同时这里涉及到较多数据更新，经常要更新DOM，性能上也有不少开销。\n\n所以针对以上几个问题，我们也对应做了很多优化和探索。\n\n## 4.VasSonic的前世\n基于传统模式的加载流程存在的种种问题，我们做了以下优化：\n### 4.1 终端优化\n针对终端耗时1s以上的情况，我们对手Q WebView框架进行了重构：\n1. 启动流程彻底拆分，设计为一个状态机按序按需执行\n2. View相关拆分模块化设计，尽可能懒加载，IO异步化\n3. X5内核在手Q中的独立进程中提前预加载\n4. 创建WebView对象复用池\n\n关于第四点，我们想分享一些Android平台上的细节，由于Android系统的生态原因，导致用户的系统版本和系统Webkit内核处于极其分裂状态，所以我们公司在手Q和微信统一使用X5内核。相对系统WebView来说，首次启动X5内核时，创建WebView比较耗时，因此我们尽量想复用WebView，但是WebView却是与Activity Context绑定。销毁复用的时候，需要释放Activity的Context，否则会内存泄露。针对这种情况，有没有一种两全其美的办法呢？\n\n计算机有一句经典的名言：```计算机领域任何一个问题都可以通过引入中间层来解决```。于是我们通过包装的方式，实现了一个Context的壳，真正的实现体包装在里面，逻辑调用真正调用到对应的实现体的函数。 经过实验发现，Android系统本身提供了这么一个```MutableContextWrapper```，作为Context的一个中间层。\n\n我们会将Activity context包在MutableContextWrapper里面，destory的时候，会将WebView的Context设置为Application的Context，从而释放Activity Context。\n类似如下：\n```Java\n\n//precreate WebView\nMutableContextWrapper contextWrapper = new MutableContextWrapper(BaseApplicationImpl.sApplication);\nmPool[0] = new WebView(contextWrapper);\n\n//reset WebView \nct =(MutableContextWrapper)webview.getContext();\nct.setBaseContext(getApplication());\n\n//reuse WebView\n((MutableContextWrapper)webview.getContext()).setBaseContext(activityContext);\n\n```\n\n### 4.2 静态直出\n![直出](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869605_pr_zhichu.png)\n“直出”这个概念对前端同学来说，并不陌生。为了优化首屏体验，大部分主流的页面都会在服务器端拉取首屏数据后通过NodeJs进行渲染，然后生成一个包含了首屏数据的Html文件，这样子展示首屏的时候，就可以解决内容转菊花的问题了。\n当然这种页面“直出”的方式也会带来一个问题，服务器需要拉取首屏数据，意味着服务端处理耗时增加。\n不过因为现在Html都会发布到CDN上，WebView直接从CDN上面获取，这块耗时没有对用户造成影响。\n手Q里面有一套自动化的构建系统Vnues，当产品经理修改数据发布后，可以一键启动构建任务，Vnues系统就会自动同步最新的代码和数据，然后生成新的含首屏Html，并发布到CDN上面去。\n\n### 4.3 离线预推\n\n![带宽优化](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870585_pr_daikuan.png)\n页面发布到CDN上面去后，那么WebView需要发起网络请求去拉取。当用户在弱网络或者网速比较差的环境下，这个加载时间会很长。于是我们通过离线预推的方式，把页面的资源提前拉取到本地，当用户加载资源的时候，相当于从本地加载，即使没有网络，也能展示首屏页面。这个也就是大家熟悉的离线包。\n手Q使用7Z生成离线包, 同时离线包服务器将新的离线包跟业务对应的历史离线包进行BsDiff做二进制差分，生成增量包，进一步降低下载离线包时的带宽成本，下载所消耗的流量从一个完整的离线包（253KB）降低为一个增量包（3KB）。\n\n经过一系列优化后，在Android平台上，点击到页面首屏展示的耗时从平均*3s*多降低为*1.8s*，优化*40% 以上*。\n\n![数据对比](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870598_pr_duibi.png)\n\n\n所以针对以上几个问题，我们对应做了很多优化和探索，这些优化帮助我们形成VasSonic的最初构想。\n\n### 4.4 业务形态变化\n虽然通过静态直出和离线预推等方式优化后，速度已经达到1.8s，但还存在很大的优化空间，当我们准备持续深入优化时，我们的业务形态发生了新的变化。\n\n之前我们页面内容的数据主要是由产品经理要配置的，用户看到的内容基本都是一样的。而现在页面为了更好地为用户推荐喜欢的内容，我们后台引入机器学习和随机算法来做智能个性化推荐。比如左边新用户推荐的是新货精选，而右边活跃用户展示的是潮品推荐。另外还有部分的内容是随机算法推荐的。这意味着不同用户看到的内容是不同的，同一个用户不同时间看到的内容也有可能不同。\n\n![新业务](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869577_pr_xinyewu.png)\n\n### 4.5 动态直出\n所以为了满足业务的需求，我们只能实时拉取用户数据并在服务端渲染后返回给客户端，也就是动态直出的方案。\n\n但是动态直出方案存在几个比较明显的问题：\n1. 服务端实时拉取数据渲染导致白屏时间长，因为服务器要先实时拉取个人数据，然后进行渲染直出，这个耗时不可控；\n2. 首屏无法使用离线预推等缓存策略，因为每个用户看到的内容不一样，我们无法通过静态直出的方式那样把Html全部发布到CDN；\n\n虽然动态直出方案下，页面首屏无法通过离线预推等方式进行加载优化，但前面离线包优化积累的经验给我们提供了思路：要优化白屏问题，核心还是减少对网络的依赖，加速资源加载方向入手。所以，此时的技术挑战为：如何缓存动态直出页面和如何在缓存页面的基础上更新页面。(注:动态直出页面可能内部有用户实时数据，不更新页面会导致看到过时的数据导致投诉)。\n\n### 4.6 webso的尝试\n在我们准备进一步优化的时候，了解到了QQ空间技术团队在动态直出方面做的一些实践尝试，他们提出了wns+html的解决方案：通过主动缓存首屏数据来获得加速，于是我们和QQ空间技术团队一起进行优化合作，将wns+html的解决方引入到手Q平台并命名为webso，其原理如图：\n![image.png-103.9kB][1]\n\n但我们使用过程中，发现页面在首次加载和模板变更场景加载耗时比较高，且在页面有内容变化的场景下需要重刷整个页面，对于变化频繁的页面体验较差，特别是在低端安卓机器上，白屏过程非常明显。于是我们分析背后的原因，发现主要有以下几个问题：\n1、采用了sso+wns腾讯私有协议传输，虽然节省了服务器连接耗时，但需要经过跨进程、服务器中转、信令排队、加解密等步骤，导致传输效率变差(注：传输通道由之前的http->node.js变成了ipc->sso->wns->wns-proxy->node.js，同时也增加了额外的代理服务器和排查定位问题成本)；\n2、需要下载完整模板和数据并拼接html之后才能交给内核渲染，在内容没有完整下载之前，内核无法进行渲染，处于空闲等待状态，与内核边加载边渲染的特性冲突；\n3、页面一旦发生内容变化(模板和数据)，需要进行合并html重刷整个页面(或下次展示)，无法进行局部刷新，仅更新变化的元素节点。\n\n综上，webso方案更加适合变化较少的简单页面，无法满足我们业务变化频繁的场景(每次进入页面数据都有变化，我们的产品和用户都无法接受重刷页面的体验)。于是我们需要一个新的通用的解决方案，通过深入内核分析结合内核特性和不断的优化探索，最终提出了更轻量更高性能的解决方案：VasSonic。\n\n## 5. VasSonic的诞生\n接下来详细介绍VasSonic的解决方案\n### 5.1 并行加载\n\n首先在加载流程方面，我们发现这里WebView访问依然是串行的， WebView要等终端初始化完成之后，才发起请求。虽然终端耗时优化了不少，但是从外网的统计数据来看，终端初始化还是存在几百毫秒的耗时，而这段时间内网络是在空等的。\n(注：在传输通道方面，我们选择了标准的http/https通道，原因是http/https通道支持流式传输，也支持chunk等特性，同时接入成本低，更加通用。)\n\n![串行](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869445_pr_chuanxing.png)\n\n因此性能上不够极致，我们优化代码，这两个操作并行处理，流程改为：\n\n![并行](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869436_pr_bingxing.png)\n\n并行处理后速度有所改善，但我们发现在某些场景下，终端初始化比较快，但数据没有完成返回，这意味着内核在空等，而内核是支持边加载边渲染的，我们在并行的同时，能否也利用内核的这个特性呢？\n\n于是我们加入了一个中间层来桥接内核和数据，内部称为流式拦截：\n\n![桥接流](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869522_pr_liushi.png)\n\n1. 启动子线程请求页面主资源，子线程中不断讲网络数据读取到内存中，也就是网络流(NetStream)和内存流(MemStream)之间的转换；\n2. 当WebView初始化完成的时候，提供一个中间层BridgeStream来连接WebView和数据流；\n3. 当WebView读取数据的时候，中间层BridgeStream会先把内存的数据读取返回后，再继续读取网络的数据。\n\n通过这种桥接流的方式，整个内核无需等待，继续做到边加载边解析。这种并行的方式让首屏的速度优化*15%以上*，进一步提升了页面加载速度。\n\n\n### 5.2 动态缓存\n\n通过并行加载，我们极大地提升了WebView请求的速度，但是在弱网络场景下白屏时间还是非常长，用户体验非常糟糕。基于离线包和webso方案的优化实践经验，我们首先将用户的已经加载的页面内容缓存下来，等用户下此点击页面的时候，我们先加载展示页面缓存，第一时间让用户看到内容，然后同时去请求新的页面数据，等新的页面数据拉取下来之后，我们再重新加载一遍即可。\n\n![动态缓存](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870617_pr_huancun.png)\n\n保存页面内容这个工作很简单，因为现在我们资源读取都是通过中间层BridgeStream来管理的，只需要将整个读取的内容缓存下来即可。\n于是我们就按动态缓存这种方案去实现了，但很快就发现了问题。用户打开页面之后，先是看到历史页面，等用户准备去操作的时候，突然页面白闪一下，重新加载了一遍，这种体验非常差，特别在一些低端机器上，这个白闪的过程太明显，非常影响体验，这是用户和产品经理都不能接受的。于是我们在思考，能否只做局部的刷新，仅刷新变化的元素呢？\n\n通过分析，我们发现同一个用户的页面，大部分数据都是不变的，经常变化的只有少量数据，于是我们提出了模板(template)和数据块(data)的概念：页面中经常变化的数据我们称为数据块，除了数据块之外的数据称为模板。\n\n### 5.3 页面分离\n在页面分离这块，我们沿用了webso方案中的动静分离的思想，并扩展了部分新的字段。首先我们将整个页面html通过VasSonic标签进行划分，包裹在标签中的内容为data，标签外的内容为模版。\n\n![页面规范](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869473_pr_guifan.png)\n\n首先我们对Html内容进行了扩展，通过代码注释的方式，增加了“sonicdiff-xxx”来标注一个数据块的开始与结束。\n而模板就是将数据块抠掉之后的Html，然后通过{albums}来表示这个是一个数据块占位。\n数据就是JSON格式，直接Key-Value。\n当然，为了完美地兼容Html，我们对协议头部进行了扩展，比如增加accept-diff来标注是否支持增量更新、template-tag来标注模板的md5是多少等。OK，有了上面这个规则或者公式后，我们就可以实现增量更新了。\n\n### 5.4 请求规范约定\nVasSonic为了支持区分客户端是否支持增量更新等能力，对头部字段进行了扩展\n\n字段 | 说明 | 请求头(Y/N) | 响应头(Y/N)\n:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------:\naccept-diff | 表示终端是否支持VasSonic模式，true为支持，否则不支持 | Y | N\nIf-none-match | 本地缓存的etag，给服务端判断是否命中304 | Y | N\netag | 页面内容的唯一标识(哈希值) | N | Y\ntemplate-tag | 模版唯一标识(哈希值)，客户端使用本地校验 或 服务端使用判断是模板有变更 | Y | Y\ntemplate-change | 标记模版是否变更，客户端使用 | N | Y\ncache-offline | 客户端端使用，根据不同类型进行不同行为 | N |Y\n\n### 5.5 cache-offline字段说明\n字段 | 说明 \n:-------------------------:|:-------------------------:\ntrue | 缓存到磁盘并展示返回内容\nfalse | 展示返回内容，无需缓存到磁盘\nstore | 缓存到磁盘，如果已经加载缓存，则下次加载，否则展示返回内容\nhttp | 容灾字段，如果http表示终端六个小时之内不会采用sonic请求该URL\n\n### 5.6 模式介绍\nVasSonic根据本地是否有缓存以及本地缓存数据跟服务器数据的差异情况分为以下四种模式。\n\n模式 | 说明 | 条件\n:-------------------------:|:-------------------------:|:-------------------------:\n**首次加载** | 本地没有缓存，即第一次加载页面 | etag为空值或template_tag为空值\n**完全缓存** | 本地有缓存，且缓存内容跟服务器内容完全一样 | etag一致\n**数据更新** | 本地有缓存，本地模版内容跟服务器模版内容一样，但数据块有变化 | etag不一致 且 template_tag一致\n**模版更新** | 本地有缓存，缓存的模版内容跟服务器的模版内容不一样 |  etag不一致 且 template_tag不一致\n\n\n#### 首次加载\n我们会在请求头部带上支持accept-diff为true和sdk版本号等标识着首次加载的信息。当请求返回后，VasSonic会在延迟几秒后(避免激烈IO竞争)将页面抽离成模板和数据并保存到本地。此时终端缓存目录下，该页面将对应三个缓存文件xxx.html、xxx.template、xxx.data，其中xxx是该页面的唯一标识(即sonicSessionId)。\n\n对于页面非首次加载场景，VasSonic优先加载本地缓存， 同时我们会在请求头部带上当前缓存和模板的md5，后台进行模板md5对比之后，分为以下几种情况：\n#### 非首次加载之完全缓存\n本地有缓存，且缓存内容跟服务器内容完全一样.\n\n#### 非首次加载之增量数据\n\n![增量数据](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870643_pr_zengliang.png)\n\n如果模板发现没有变化，那么会在响应头部返回template-change=false，同时响应包体返回的数据不再是完整的html，而是一段JSON数据，及全部的数据块。我们现在需要跟本地数据进行差分，找出真正的增量数据，如上图中，后台返回了N个数据，实际上仅有一个数据是有变化的，那么我们仅需要将这个变化的数据提交到页面即可。一般场景下，这个差异的数据比全部数据要小很多。如果页面拆分数据得更细，那么页面的变动就更小，这个取决于前端同学对数据块的细化程度。\n\n获得变化数据块(diff_data)后，客户端只需要通知页面页面设置的回调接口(getDiffDataCallback)进行界面元素更新即可。这里javascript的通信方式也可以自由定义(可以使用webview标准的javascript通信方式，也可以使用伪协议的方式)，只要页面跟终端协商一致就可以。\n![提交增量](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870607_pr_hebing.png)\n\n对于数据更新这种场景，终端还会将新的数据和模板拼接成为新的页面，保持缓存最新。当终端初始化比较慢的时候，WebView去加载缓存的时候，这个页面可能已经是最新的了，连数据刷新都不需要。\n\n#### 非首次加载之模板更新\n与数据更新模式不一样，由于业务需求，页面的模板会发生更改。当终端在获取到新的模板和数据后，本地在子线程中进行合并，生成一个新的缓存，然后回调通知终端，刷新WebView来加载新的缓存。\n\n\n我们来看一下最终的流程图，跟动态缓存对比，有不少细节优化：\n\n![整体流程](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870626_pr_liucheng.png)\n\n我们从第2步开始，SonicSession首先会去读取缓存。会抛个消息通知WebView读取缓存，如果Webview已经准备好，则直接加载缓存，如果没有，则缓存先放在内存里面。同时SonicSession也会带上模板等信息到后台拉取新的内容，后台经过Sonic-Diff之后，会返回新的数据。SonicSession拿到新的数据后，首先会跟本地数据进行Diff，如果发现WebView已经加载缓存，则直接提交增量数据给页面。否则继续拼接最新的页面，替换掉内存里面的缓存，同时保存到本地。这个时候WebView如果Ready，则直接进行第5步load最新的内容即可。\n\n#### 效果统计\n![效果统计](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502869563_pr_xiaoguo.png)\n\n这个是我们外网的统计数据。在数据更新模式下，首屏的耗时在1s左右，相比普通的动态直出，优化了50%以上。模板更新这个会比首次高，是因为加载了两次页面，不过从模式占比上来看，我们大部分页面都是数据更新。针对模板更新这种耗时比较高的情况，前面优化积累的经验给我们提供了思路，核心还是从提前获取资源方向入手，因此我们优先考虑如何预加载模板更新。\n\n#### 预加载\n实际上整个SonicSession在没有WebView的情况下，也是可以独立完成所有逻辑的，当用户点击页面的时候，我们在将WebView和SonicSession绑定起来即可。于是我们支持了两种预加载的模式，一种是通过后台push的方式，来提前获取数据。还有一种就是JSAPI，页面可以调用JSAPI来预加载用户可能操作的下一个页面。通过这两种方式，我们可以把需要的增量更新数据提前拉取回来\n![预加载](http://imgcache.gtimg.cn/ACT/svip_act/act_img/public/201708/1502870634_pr_preload.png)\n\n## 6. 效果对比\n\nPic 1: 没有使用VasSonic |  Pic 2: 使用VasSonic\n:-------------------------:|:-------------------------:\n![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)\n\n## 7. 展望未来\n开源只是故事的开始，我们仍会持续对 VasSonic 做改进，包括更易用的接口、更好的性能、更高的可靠性，同时快速响应解决开源后的issue和PR。这些改进最终也会原封不动地在手Q内使用，这一切都是为了更快的WebView加载速度。 </br>\n\nTalk is cheap，read the fucking code. If you are interested in VasSonic, don't forget to STAR [VasSonic](https://github.com/Tencent/VasSonic).\nThank you for reading ~\n\n\n## 8. 特别感谢\n最后再次感谢qq空间技术团队的贡献及webso技术带来的启发，感谢infoQ，腾讯开源，bugly等媒体团队对vasSonic的开源支持。\n\n\n  [1]: http://static.zybuluo.com/feilang/7l6ptf1cl5k3qxl0o55a4cxq/image.png"
  },
  {
    "path": "checkstyle.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  Copyright (C) 2016 THL A29 Limited, a Tencent company.\n  Copyright (C) 2014 Square, Inc.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\"\n    \"http://www.puppycrawl.com/dtds/configuration_1_2.dtd\">\n\n<module name=\"Checker\">\n  <!--module name=\"NewlineAtEndOfFile\"/-->\n  <module name=\"FileLength\"/>\n  <module name=\"FileTabCharacter\"/>\n  <module name=\"SuppressWarningsFilter\"/>\n\n  <!-- Trailing spaces -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"\\s+$\"/>\n    <property name=\"message\" value=\"Line has trailing spaces.\"/>\n  </module>\n\n  <!-- Space after 'for' and 'if' -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"^\\s*(for|if)[^ ]\\(\"/>\n    <property name=\"message\" value=\"Space needed before opening parenthesis.\"/>\n  </module>\n\n  <!-- For each spacing -->\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"^\\s*for \\(.*?([^ ]:|:[^ ])\"/>\n    <property name=\"message\" value=\"Space needed around ':' character.\"/>\n  </module>\n\n  <module name=\"TreeWalker\">\n    <!-- Checks for Javadoc comments.                     -->\n    <!-- See http://checkstyle.sf.net/config_javadoc.html -->\n    <!--module name=\"JavadocMethod\"/-->\n    <!--module name=\"JavadocType\"/-->\n    <!--module name=\"JavadocVariable\"/-->\n    <!--module name=\"JavadocStyle\"/-->\n\n\n    <!-- Checks for Naming Conventions.                  -->\n    <!-- See http://checkstyle.sf.net/config_naming.html -->\n    <!--<module name=\"ConstantName\"/>-->\n    <module name=\"LocalFinalVariableName\"/>\n    <module name=\"LocalVariableName\"/>\n    <module name=\"MemberName\"/>\n    <module name=\"MethodName\">\n      <property name=\"format\" value=\"^[a-z][a-zA-Z0-9_]*$\"/>\n    </module>\n    <module name=\"PackageName\"/>\n    <module name=\"ParameterName\"/>\n    <module name=\"StaticVariableName\"/>\n    <module name=\"TypeName\">\n      <property name=\"format\" value=\"^[A-Z][a-zA-Z0-9_]*$\"/>\n    </module>\n\n\n    <!-- Checks for imports                              -->\n    <!-- See http://checkstyle.sf.net/config_import.html -->\n    <module name=\"AvoidStarImport\"/>\n    <module name=\"IllegalImport\"/>\n    <module name=\"RedundantImport\"/>\n    <module name=\"UnusedImports\"/>\n\n\n    <!-- Checks for Size Violations.                    -->\n    <!-- See http://checkstyle.sf.net/config_sizes.html -->\n    <!--module name=\"LineLength\"-->\n      <!--property name=\"max\" value=\"100\"/-->\n    <!--/module-->\n    <!--module name=\"MethodLength\"/-->\n    <!--<module name=\"ParameterNumber\"/>-->\n\n    <!-- Checks for whitespace                               -->\n    <!-- See http://checkstyle.sf.net/config_whitespace.html -->\n    <module name=\"GenericWhitespace\"/>\n    <module name=\"EmptyForIteratorPad\"/>\n    <module name=\"MethodParamPad\"/>\n\n\n    <module name=\"NoWhitespaceAfter\"/>\n    <module name=\"NoWhitespaceBefore\"/>\n    <module name=\"OperatorWrap\"/>\n    <module name=\"ParenPad\"/>\n    <module name=\"TypecastParenPad\"/>\n    <module name=\"WhitespaceAfter\"/>\n    <module name=\"WhitespaceAround\"/>\n\n\n    <!-- Modifier Checks                                    -->\n    <!-- See http://checkstyle.sf.net/config_modifiers.html -->\n    <!--module name=\"ModifierOrder\"/-->\n    <module name=\"RedundantModifier\"/>\n\n\n    <!-- Checks for blocks. You know, those {}'s         -->\n    <!-- See http://checkstyle.sf.net/config_blocks.html -->\n    <!--module name=\"AvoidNestedBlocks\"/-->\n    <!--module name=\"EmptyBlock\"/-->\n    <module name=\"LeftCurly\"/>\n    <!--allow single line-->\n    <module name=\"NeedBraces\">\n      <property name=\"allowSingleLineStatement\" value=\"true\"/>\n    </module>\n\n    <module name=\"RightCurly\"/>\n\n\n    <!-- Checks for common coding problems               -->\n    <!-- See http://checkstyle.sf.net/config_coding.html -->\n    <!--module name=\"AvoidInlineConditionals\"/-->\n    <module name=\"CovariantEquals\"/>\n    <module name=\"EmptyStatement\"/>\n    <!--module name=\"EqualsAvoidNull\"/-->\n    <!--<module name=\"EqualsHashCode\"/>-->\n    <!--module name=\"HiddenField\"/-->\n    <module name=\"IllegalInstantiation\"/>\n    <!--<module name=\"InnerAssignment\"/>-->\n    <!--module name=\"MagicNumber\"/-->\n    <!--<module name=\"MissingSwitchDefault\"/>-->\n    <!--<module name=\"RedundantThrows\"/>-->\n    <module name=\"SimplifyBooleanExpression\"/>\n    <module name=\"SimplifyBooleanReturn\"/>\n\n    <!-- Checks for class design                         -->\n    <!-- See http://checkstyle.sf.net/config_design.html -->\n    <!--module name=\"DesignForExtension\"/-->\n    <!--module name=\"FinalClass\"/-->\n    <!--<module name=\"HideUtilityClassConstructor\"/>-->\n    <!--module name=\"InterfaceIsType\"/-->\n    <!--module name=\"VisibilityModifier\"/-->\n\n\n    <!-- Miscellaneous other checks.                   -->\n    <!-- See http://checkstyle.sf.net/config_misc.html -->\n    <module name=\"ArrayTypeStyle\"/>\n    <!--module name=\"FinalParameters\"/-->\n    <!--<module name=\"TodoComment\"/>-->\n    <module name=\"UpperEll\"/>\n    <module name=\"SuppressWarningsHolder\"/>\n  </module>\n</module>"
  },
  {
    "path": "sonic-android/.gitignore",
    "content": ".gradle\n/build\n# Ignore Gradle GUI config\ngradle-app.setting\n\n# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)\n!gradle-wrapper.jar\n\n# Cache of project\n.gradletasknamecache\n\n.DS_Store\nnode_modules\n\n# Built application files\n*.apk\n*.ap_\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\n\n# Gradle files\n.gradle/\n*.iml\n/*/*.iml\n.idea\n/*/.idea/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\ngradle.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n/*/.idea\n\n/buildSdk\n\n\n"
  },
  {
    "path": "sonic-android/README.md",
    "content": "## Getting started with Android\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n## Dependencies:\n\nAdd VasSonic gradle plugin as a dependency in your module's build.gradle\n```gradle\ncompile 'com.tencent.sonic:sdk:3.1.0'\n```\n\n## Implement sonic interface:\n1. Implement a class which extends from ```SonicRuntime```\n\n> 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.\n\n```Java\n/**\n* Here is a sample subclass of SonicRuntime\n*/\npublic class HostSonicRuntime extends SonicRuntime {\n    public HostSonicRuntime(Context context) {\n        super(context);\n    }\n    /**\n     * @return User's UA\n     */\n    @Override\n    public String getUserAgent() {\n        return \"\";\n    }\n    /**\n     * @return the ID of user.\n     */\n    @Override\n    public String getCurrentUserAccount() {\n        return \"\";\n    }\n    /**\n     * @return the file path which is used to save Sonic caches.\n     */\n    @Override\n    public File getSonicCacheDir() {\n        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator         + \"sonic/\";\n        File file = new File(path.trim());\n        if(!file.exists()){\n            file.mkdir();\n        }\n        return file;\n    }\n}\n```\n2. Implement a subclass which extends from ```SonicSessionClient```\n\n```Java\n/**\n *\n * SonicSessionClient  is a thin API class that delegates its public API to a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.\n */\npublic class SonicSessionClientImpl extends SonicSessionClient {\n    private WebView webView;\n    public void bindWebView(WebView webView) {\n        this.webView = webView;\n    }\n    \n    @Override\n    public void loadUrl(String url, Bundle extraData) {\n        webView.loadUrl(url);\n    }\n\n    @Override\n    public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding,                \n                                    String historyUrl) {\n        webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);\n    }\n}\n```\n## Android Demo\nHere is a simple demo shows how to create an Android activity which uses the VasSonic Framework\n```Java\n\npublic class BrowserActivity extends Activity {\n\n    public final static String PARAM_URL = \"param_url\";\n\n    public final static String PARAM_MODE = \"param_mode\";\n\n    private SonicSession sonicSession;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Intent intent = getIntent();\n        String url = intent.getStringExtra(PARAM_URL);\n        int mode = intent.getIntExtra(PARAM_MODE, -1);\n        if (TextUtils.isEmpty(url) || -1 == mode) {\n            finish();\n            return;\n        }\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);\n\n        // step 1: Initialize sonic engine if necessary, or maybe u can do this when application created\n        if (!SonicEngine.isGetInstanceAllowed()) {\n            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());\n        }\n\n        SonicSessionClientImpl sonicSessionClient = null;\n\n        // step 2: Create SonicSession\n        sonicSession = SonicEngine.getInstance().createSession(url,  new SonicSessionConfig.Builder().build());\n        if (null != sonicSession) {\n            sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());\n        } else {\n            // this only happen when a same sonic session is already running,\n            // u can comment following codes to feedback as a default mode.\n            throw new UnknownError(\"create session fail!\");\n        }\n\n        // step 3: BindWebView for sessionClient and bindClient for SonicSession\n        // in the real world, the init flow may cost a long time as startup\n        // runtime、init configs....\n        setContentView(R.layout.activity_browser);\n        WebView webView = (WebView) findViewById(R.id.webview);\n        webView.setWebViewClient(new WebViewClient() {\n            @Override\n            public void onPageFinished(WebView view, String url) {\n                super.onPageFinished(view, url);\n                if (sonicSession != null) {\n                    sonicSession.getSessionClient().pageFinish(url);\n                }\n            }\n\n            @TargetApi(21)\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {\n                return shouldInterceptRequest(view, request.getUrl().toString());\n            }\n\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {\n                if (sonicSession != null) {\n                //step 6: Call sessionClient.requestResource when host allow the application \n                // to return the local data .\n                    return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);\n                }\n                return null;\n            }\n        });\n\n        WebSettings webSettings = webView.getSettings();\n\n        // step 4: bind javascript\n        // note:if api level lower than 17(android 4.2), addJavascriptInterface has security\n        // issue, please use x5 or see https://developer.android.com/reference/android/webkit/\n        // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)\n        webSettings.setJavaScriptEnabled(true);\n        webView.removeJavascriptInterface(\"searchBoxJavaBridge_\");\n        intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis());\n        webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), \"sonic\");\n\n        // init webview settings\n        webSettings.setAllowContentAccess(true);\n        webSettings.setDatabaseEnabled(true);\n        webSettings.setDomStorageEnabled(true);\n        webSettings.setAppCacheEnabled(true);\n        webSettings.setSavePassword(false);\n        webSettings.setSaveFormData(false);\n        webSettings.setUseWideViewPort(true);\n        webSettings.setLoadWithOverviewMode(true);\n\n\n        // step 5: webview is ready now, just tell session client to bind\n        if (sonicSessionClient != null) {\n            sonicSessionClient.bindWebView(webView);\n            sonicSessionClient.clientReady();\n        } else { // default mode\n            webView.loadUrl(url);\n        }\n    }\n\n    @Override\n    public void onBackPressed() {\n        super.onBackPressed();\n    }\n\n    @Override\n    protected void onDestroy() {\n        if (null != sonicSession) {\n            sonicSession.destroy();\n            sonicSession = null;\n        }\n        super.onDestroy();\n    }\n```\n\n## Support\nAny problem?\n\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-android/sample).\n4. Contact us for help.\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n\n\n"
  },
  {
    "path": "sonic-android/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:2.3.0'\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "sonic-android/docs/Sonic Quick模式实现原理.md",
    "content": "# Sonic Quick模式实现原理\n\n---\n根据本地是否有缓存数据可以将Quick模式下的sonic分为无缓存和有缓存模式。对于有缓存模式又可以分为完全缓存、局部刷新和全局刷新（也就是模版变更），下面就看下这几种模式的执行流程。\n\n无论是哪种执行模式，核心的思想都是并行，即充分利用webview初始化的时间进行一些数据的处理(webview的初始化耗时还是挺多的)。在包含webview的activity启动时会一边进行webview的初始化逻辑，一边并行的执行sonic的逻辑。\n\n## 一，无缓存模式\n\n无缓存模式下的核心思想就是在webview初始化之前建立自己的网络连接，利用webview初始化的时间尽可能多的读取网络的数据，在webview需要数据的时候将自己从网络读取的数据交给webview处理。\n\n代码的主要执行流程\n\n<img src = \"sonicQuickModeFirst.png\" width=100% height=100%>\n\n这里主要有两条并行线，左边是webview的执行流程，右边是sonic的执行流程。Webview的执行流程比较简单，主要是进行webview的初始化，以及在初始化完之后调用SonicSession（这里的SonicSession对象是activity onCreate的时候通过SonicEngine创建的）的onClientReady方法，告知其webview已经init完毕。剩下的事情交给sonic那边处理。\n\n右边这条sonic的执行流程线相对会复杂一些，首先，在activity create之后通过SonicEngine创建SonicSession对象。接着调用SonicCacheInterceptor来获取本地缓存的url对应的数据。由于是首次加载即本地无缓存数据，所以这里的数据是为空的。获取的数据为空之后会post一个CLIENT_CORE_MSG_PRE_LOAD(arg1 = PRE_LOAD_NO_CACHE )的消息到主线程中，同时继续执行下面的逻辑。主线程的逻辑后面统一分析，这里先分析sonic所在子线程中的逻辑。\n\nSonic在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内容进行模版分割及数据保存。\n\n接下来看看主线程的执行逻辑。之前说过sonic在本地无缓存的时候会先post一个CLIENT_CORE_MSG_PRE_LOAD的消息到主线程，如果主线程有执行到这个消息的话（之前也介绍过这个消息有可能被cancel掉）就会调用webview的loadUrl，发起真正的网络请求，之后webview会调用本身的资源拦截方法，在这个方法中sonic会将之前保存的pendingWebResourceStream返回给webview，有了这个pendingWebResourceStream之后webview就可以进行解析渲染逻辑了。同时webview在展示完页面之后会调SonicSessionStream的onClose方法进行关闭数据流，在这个onClose中我们会进行html内容的数据分割以及数据保存操作。\n\n如果主线程处理的是CLIENT_CORE_MSG_FIRST_LOAD消息，则会先判断webview之前是否有发生过loadUrl（通过wasLoadUrlInvoked来判断），如果没有，调用webview的loadDataWithBaseUrl方法去加载之前读取的网络数据，这样webview就可以根据这个数据直接做解析渲染的逻辑了；如果有就不做任何的逻辑处理了。\n\n以上就是在quick模式下sonic首次的基本逻辑。这里有个问题要注意，就是主线程在处理sonic post的消息之前都会判断webview是否ready（初始化完毕），只有webview ready的情况才会执行对应的操作。如果webview没有ready的话就会把对应的消息存起来，直到webview ready的时候再执行对应的逻辑。\n\t\n## 二，有缓存模式\n\n有缓存模式的核心思想也是在webview初始化之前先读取本地的数据，同时建立自己的网络连接，通过网络连接获取服务器最新的数据。在webview需要数据的时候将本地或服务器返回的新的数据交给webview处理。\n有缓存模式又可以分为完全缓存、局部刷新、模板变更。下面依次介绍这几种模式。\n###1，完全缓存：\n所谓完全缓存就是本地的数据跟服务器的数据是完全一样的。\n代码的主要执行流程：\n<img src = \"sonicQuickModeCache.png\" width=100% height=100%>\n\n左边webview的执行跟无缓存模式下没什么区别，右边sonic执行流程中前两步跟首次的逻辑一样，在完全缓存模式下通过SonicCacheInterceptor获取的url对应的本地数据是不为空的，这时候会post一个CLIENT_CORE_MSG_PRE_LOAD(arg1 = PRE_LOAD_WITH_CACHE)的消息到主线程中，同时服务器返回304，sonic流程就走完了。主线程在收到CLIENT_CORE_MSG_PRE_LOAD消息时通过loadDataWithBaseUrl加载本地数据给webview渲染。\n###2，局部刷新：\n局部刷新就是本地的数据跟服务器的数据相比，只有data部分有变化，模板跟服务器一样。\n代码的主要执行流程：\n<img src = \"sonicQuickModeDataUpdate.png\" width=100% height=100%>\n\n左边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保存在本地。\n下面看下主线程的执行逻辑。\n\n之前说过在数据刷新模式下会post一个CLIENT_CORE_MSG_PRE_LOAD的消息到主线程，主线程如果有执行到这个消息（因为有可能被remove掉）的话就会调用webview的loadDataWithBaseUrl将本地的数据交给内核渲染，同时将本地变量wasLoadDataInvoked置为true。\n当主线程接收到CLIENT_CORE_MSG_DATA_UPDATE的消息时会先判断wasLoadDataInvoked是否为true，即判断webview之前是否有掉过loadDataWithBaseUrl方法，如果有的话就会调用SonicSessionClient的callJacaScript方法将diffData给到页面，从而刷新页面如果wasLoadDataInvoked为false的话就调loadDataWithBaseUrl把最新的数据（服务器返回的数据跟本地模版合成的数据）给到webview去渲染。\n\t\n### 3，模版变更\n模板变更是本地的数据跟服务器数据相比，本地的模板跟服务器的模板不一样。\n代码执行流程：\n<img src = \"sonicQuickModeTemplateChange.png\" width=100% height=100%>\n\n同样，左边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)的消息到主线程中，最后进行模版的分割以及数据的保存等操作。\n跟前面一样，接下来分析下主线程的执行逻辑。\n\n主线程执行逻辑比较简单，如果是CLIENT_CORE_MSG_PRE_LOAD消息的话就通过loadDataWithBaseUrl加载本地的数据，如果是CLIENT_CORE_MSG_TEMPLATE_CHANGE消息先判断msg.obj是否为空，如果为空发起loadUrl重新加载数据，同时在资源拦截的时候将本地建立的桥接流交给内核渲染。等待内核渲染完毕之后进行模版分割和模版拆分等操作。如果不为空就通过loadDataWithBaseUrl加载最新的数据。\n这里解释下为什么在模版更新的时候需要判读之前load的本地页面是否有pagefinish。假设本地的页面已经展示完了，而sonic这边还在读取网络的数据，如果没有这个逻辑的话就会等sonic这边读完网络数据之后才能刷新页面；而有了这个逻辑之后就可以在pageFinish的时候直接发起loadUrl，利用webview边下载边解析的功能减少内核的等待时间，从而减少整个页面刷新的耗时。\n\n以上就是sonic在Quick模式下的的大概流程\n \n\n\n\n\n\n"
  },
  {
    "path": "sonic-android/docs/Sonic Standard模式实现原理.md",
    "content": "# Sonic Standard模式实现原理\n---\n从前面介绍的sonic的基本原理可以知道，sonic分为Quick模式和Standard模式。本文介绍Standard模式的基本实现原理。\n根据本地缓存的数据情况可以将Quick模式下的sonic分为无缓存和有缓存模式。对于有缓存模式又可以分为完全缓存、局部刷新和全局刷新（也就是模版变更），下面就看下这几种模式的执行流程。\n无论是哪种执行模式，核心的思想都是并行，即充分利用webview初始化的时间进行一些数据的处理(webview的初始化耗时还是挺多的)。在包含webview的activity启动时会一边进行webview的初始化逻辑，一边并行的执行sonic的逻辑。\n\n## 一，无缓存模式\n无缓存模式下的核心思想就是在webview初始化之前建立自己的网络连接，利用webview初始化的时间尽可能多的读取网络的数据，在webview需要数据的时候将自己从网络读取的数据交给webview处理。\n代码执行流程为：\n<img src = \"sonicStandardModeFirst.png\" width=100% height=100%>\n\n这里主要有两条并行线，左边是webview的执行流程，右边是sonic的执行流程。Webview的执行流程比较简单，主要是进行webview的初始话，以及在初始化完之后调用SonicSession（这里的SonicSession对象是activity onCreate的时候通过SonicEngine创建的）的onClientReady方法，告知其webview已经init完毕，之后就开始调webview的laodUrl方法，等待webview资源拦截的回调。剩下的事情交给sonic那边处理。\n\n右边表示sonic的执行流程。首先调用SonicEngine.createSession创建SonicSession对象，接着调用SonicCacheIterceptor的getSonicCache方法来获取要加载的url对应的本地数据，由于是首次加载，所以这里的cache数据是为空的。之后会通过SonicSessionConnection建立一个URLConnection，接着通过这个连接获取服务器返回的数据。由于获取网络数据是个耗时的过程，所以在读取网络数据的过程中会不断判断webView是否发起资源拦截请求（通过SonicSession的wasInterceptInvoked来判断），如果webview已经发起资源拦截请求，就中断网络数据的读取，将已经读取的数据和未读取的网络数据拼接成桥接流SonicSessionStream，并将其赋值给SonicSession的pendingWebResourceStream。\n\n因此在webview发起资源拦截时pendingWebResourceStream存在两种可能，一种时网络数据还没完全读完的桥接流，另一种是网络数据已经完全读完的数据流。如果是桥接流的话在webview渲染完成关闭桥接流的时候会进行模版分割，数据保存等操作。如果是已读完的数据流的话就会在将pendingWebResourceStream数据给内核之后继续在子线程中执行模版分割，数据保存等操作。\n\n## 二，有缓存模式：\n有缓存模式的核心思想也是在webview初始化之前先读取本地的数据，同时建立自己的网络连接，通过网络连接获取服务器最新的数据。在webview需要数据的时候将本地或服务器返回的新的数据交给webview处理。\n有缓存模式又可以分为完全缓存、局部刷新、模板变更。下面依次介绍这几种模式。\n\n### 1，完全缓存：\n所谓完全缓存就是本地的数据跟服务器的数据是完全一样的。\n代码执行流程为\n<img src = \"sonicStandardModeCache.png\" width=100% height=100%>\n\n左边webview的执行逻辑跟首次基本一致。右边sonic的执行逻辑前面几步跟首次的逻辑也基本一致，不同的地方开始于通过SonicCacheInterceptor获取的本地cacahe数据是不为空的，会将本地的数据包装为一个InputStream，在webview发起资源拦截的时候将这个InputStream交给内核渲染。同时通过SonicSessionConnection向服务器请求最新数据，由于服务器返回304，没有数据更新，整个sonic的流程执行完毕。\n\n### 2，局部刷新：\n局部刷新就是本地的数据跟服务器的数据相比，只有data部分有变化，模板跟服务器一样。\n代码执行流程为：\n<img src = \"sonicStandardModeDataUpdate.png\" width=100% height=100%>\n\n左边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，然后执行最后的数据保存等操作。\n\n通过上面的介绍可以知道在数据更新模式下，webview发起资源拦截的时候有可能得到两种值，一种是之前本地数据组成的输入流，在这种情况下页面调用js获取diffData的时候会将保存的diffData给到页面，让页面执行刷新操作；另一种是由服务器返回的data跟本地模版组成的最新的html包装成的输入流，这种情况下页面展示的就是最新的数据，在获取diffData的时候就不会有返回值了。\n\n### 3，模版变更\n模板变更是本地的数据跟服务器数据相比，本地的模板跟服务器的模板不一样。\n代码执行流程为：\n<img src = \"sonicStandardModeTemplateChange.png\" width=100% height=100%>\n\n左边webview的逻辑跟首次差不多，不一样的地方后面再讲。右边sonic的逻辑前面几个跟数据更新基本一致，不一样的地方开始于服务器的回包数据不同。在模版更新模式下服务器会返回最新的完整的html内容，由于读取网络数据耗时比较长，为了可以让页面更快的刷新，在读取网络数据的时候会不断判断之前load的本地缓存的数据的页面有没有finish（通过SonicSession的wasOnPageFinishInvoked来判断，这个值会在SonicSessionClient在webview onpagefinish的时候设置），如果wasOnPageFinishInvoked为true就不再读取网络数据了，而是将已读的数据和未读的数据组成桥接流SonicSessionStream，然后在主线程中发起loadUrl。同时在webview资源拦截的时候将刚才建立的桥接流交给内核渲染。\n\n如果整个网络数据读取过程wasOnPageFinishInvoked都没有被设置为true的话sonic就会将读取完的最新的数据包装成一个输入流放在pendingWebResourceStream里。接下来判断wevbiew是否有发起资源拦截。如果没有的话就执行最后的保存数据操作，因为这时已经将pendingWebResourceStream更新为最新的数据了，当webview发起资源拦截的时候sonic给到内核的就是最新的数据了；如果此时webview的资源拦截已经发起了，就是说webview已经加载过之前本地的数据了，那么这时候sonic会主动再调一次webview的loadUrl方法进行刷新页面，等到webview第二次发起资源拦截请求的时候再把最新的数据给到内核去渲染，这种情况sonic在发起webview的loadUrl之后就会继续在子线程执行文件保存等收尾的工作。\n\n这里解释下为什么在模版更新的时候需要判读之前load的本地页面是否有pagefinish。假设本地的页面已经展示完了，而sonic这边还在读取网络的数据，如果没有这个逻辑的话就会等sonic这边读完网络数据之后才能刷新页面；而有了这个逻辑之后就可以在pageFinish的时候直接发起loadUrl，利用webview边下载边解析的功能减少内核的等待时间，从而减少整个页面刷新的耗时。\n以上就是sonic在Standard模式下的的大概流程\n\t"
  },
  {
    "path": "sonic-android/docs/Sonic接入指引.md",
    "content": "# 终端接入指引-Android版本\n----\n## 1.Sdk引入配置\n在模块的build.gradle文件里面加入\n\n```\ncompile 'com.tencent.sonic:sdk:3.0.0-alpha'\n```\n\n## 2.代码接入\n### (1).创建一个类继承SonicRuntime\nSonicRuntime类主要提供sonic运行时环境，包括Context、用户UA、ID(用户唯一标识，存放数据时唯一标识对应用户)等等信息。以下代码展示了SonicRuntime的几个方法。\n```java\npublic class HostSonicRuntime extends SonicRuntime {\n    public HostSonicRuntime(Context context) {\n        super(context);\n    }\n    /**\n     * 获取用户UA信息\n     * @return\n     */\n    @Override\n    public String getUserAgent() {\n        return \"\";\n    }\n    /**\n     * 获取用户ID信息\n     * @return\n     */\n    @Override\n    public String getCurrentUserAccount() {\n        return \"\";\n    }\n    /**\n     * 创建sonic文件存放的路径\n     * @return\n     */\n    @Override\n    public File getSonicCacheDir() {\n        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator         + \"sonic/\";\n        File file = new File(path.trim());\n        if(!file.exists()){\n            file.mkdir();\n        }\n        return file;\n    }\n}\n```\n\n### (2).创建一个类继承SonicSessionClient\n\nSonicSessionClient主要负责跟webView的通信，比如调用webView的loadUrl、loadDataWithBaseUrl等方法。\n\n```java\npublic class SonicSessionClientImpl extends SonicSessionClient {\n    private WebView webView;\n    public void bindWebView(WebView webView) {\n        this.webView = webView;\n    }\n    /**\n     * 调用webView的loadUrl\n     */\n    @Override\n    public void loadUrl(String url, Bundle extraData) {\n        webView.loadUrl(url);\n    }\n    /**\n     * 调用webView的loadDataWithBaseUrl方法\n     */\n    @Override\n    public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding,                \n                                    String historyUrl) {\n        webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);\n    }\n}\n```\n### (3).新建包含webView的Activity(或者Fragment等)，在activity中完成sonic的接入。这里通过简单的demo展示如何接入\n\n```java\npublic class SonicTestActivity extends Activity {\n\n\n    public final static String PARAM_URL = \"param_url\";\n\n    public final static String PARAM_MODE = \"param_mode\";\n\n    private SonicSession sonicSession;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Intent intent = getIntent();\n        String url = intent.getStringExtra(PARAM_URL);\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);\n\n        // init sonic engine if necessary, or maybe u can do this when application created\n        if (!SonicEngine.isGetInstanceAllowed()) {\n            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());\n        }\n\n        SonicSessionClientImpl sonicSessionClient = null;\n\n        // if it's sonic mode , startup sonic session at first time\n        SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n        // create sonic session and run sonic flow\n        sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());\n        if (null != sonicSession) {\n            sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());\n        } else {\n            // this only happen when a same sonic session is already running,\n            // u can comment following code to feedback for default mode to\n            throw new UnknownError(\"create session fail!\");\n        }\n\n        // start init flow ... in the real world, the init flow may cost a long time as startup\n        // runtime、init configs....\n        setContentView(R.layout.activity_browser);\n\n        // init webview\n        WebView webView = (WebView) findViewById(R.id.webview);\n        webView.setWebViewClient(new WebViewClient() {\n            @Override\n            public void onPageFinished(WebView view, String url) {\n                super.onPageFinished(view, url);\n                if (sonicSession != null) {\n                    sonicSession.getSessionClient().pageFinish(url);\n                }\n            }\n\n            @TargetApi(21)\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {\n                return shouldInterceptRequest(view, request.getUrl().toString());\n            }\n\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {\n                if (sonicSession != null) {\n                    return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);\n                }\n                return null;\n            }\n        });\n\n        WebSettings webSettings = webView.getSettings();\n\n        // add java script interface\n        // note:if api level if lower than 17(android 4.2), addJavascriptInterface has security\n        // issue, please use x5 or see https://developer.android.com/reference/android/webkit/\n        // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)\n        webSettings.setJavaScriptEnabled(true);\n        webView.removeJavascriptInterface(\"searchBoxJavaBridge_\");\n        intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis());\n        webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), \"sonic\");\n\n        // init webview settings\n        webSettings.setAllowContentAccess(true);\n        webSettings.setDatabaseEnabled(true);\n        webSettings.setDomStorageEnabled(true);\n        webSettings.setAppCacheEnabled(true);\n        webSettings.setSavePassword(false);\n        webSettings.setSaveFormData(false);\n        webSettings.setUseWideViewPort(true);\n        webSettings.setLoadWithOverviewMode(true);\n\n\n        // webview is ready now, just tell session client to bind\n        if (sonicSessionClient != null) {\n            sonicSessionClient.bindWebView(webView);\n            sonicSessionClient.clientReady();\n        } else { // default mode\n            webView.loadUrl(url);\n        }\n    }\n\n    @Override\n    public void onBackPressed() {\n        super.onBackPressed();\n    }\n\n    @Override\n    protected void onDestroy() {\n        if (null != sonicSession) {\n            sonicSession.destroy();\n            sonicSession = null;\n        }\n        super.onDestroy();\n    }\n}\n```\n\nSonicTestActivity是一个含有webView的demo代码，里面展示了sonic的整体流程。主要分为6个步骤：\n\n**Step1**：在activity onCreate的时候创建SonicRuntime并且初始化SonicEngine。为sonic初始化运行时需要的环境\n```java\nif (!SonicEngine.isGetInstanceAllowed()) {\n    SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());\n}\n```\n\n**Setp2**：通过SonicEngine.getInstance().createSession来为要加载的url创建一个SonicSession对象，同时为session绑定client。session创建之后sonic就会异步加载数据了。\n```java\nSonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n// create sonic session and run sonic flow\nsonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());\nif (null != sonicSession) {\n    sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());\n}\n```\n\n**Step3**：设置javascript，这个主要是设置页面跟终端的js交互方式。\n按照sonic的规范，webView打开页面之后页面会通过js来获取sonic提供的一些数据(比如页面需要刷新的数据)。Demo里使用的是标准的js交互代码，第三方可以替换为自己的js交互实现方式(比如提供jsbridge伪协议等)。\n```java\nwebSettings.setJavaScriptEnabled(true);\nwebView.removeJavascriptInterface(\"searchBoxJavaBridge_\");\nwebView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), \"sonic\");\n```\n\n**Step4**：为clinet绑定webview，在webView准备发起loadUrl的时候通过SonicSession的onClientReady方法通知sonicSession： webView ready可以开始loadUrl了。这时sonic内部就会根据本地的数据情况执行webView相应的逻辑（执行loadUrl或者loadData等）。\n```java\nif (sonicSessionClient != null) {\n    sonicSessionClient.bindWebView(webView);\n    sonicSessionClient.clientReady();\n}\n```\n\n**Step5**：在webView资源拦截的回调中调用session.onClientRequestResource(url)。通过这个方法向sonic获取url对应的WebResourceResponse数据。这样内核就可以根据这个返回的response的内容进行渲染了。(如果sonic在webView ready的时候执行的是loadData的话，是不会走到资源拦截这里的)\n```java\npublic WebResourceResponse shouldInterceptRequest(WebView view, String url) {\n    if (sonicSession != null) {\n        return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);\n    }\n    return null;\n}\n```\n\n\n\n\n\n\n"
  },
  {
    "path": "sonic-android/docs/Sonic框架介绍.md",
    "content": "# Sonic框架介绍\n\n\n\n---\n本文主要介绍sonic的整个框架设置，包括这个框架的类图结构以及各个类的主要职责介绍。\n\t\nsonicSdk类图结构：\n<img src = \"sonic.png\">\n\n\nsonic类职责说明：\n\nSonicSession：负责sonic的核心逻辑：包括缓存数据的获取，服务器回包数据的处理，页面展示数据的生成以及数据模版的拆分、拼接等。\n\nQuickSonicSession：SonicSession的子类，这种类型的session会使用webview的loadData方式来加载页面。这种方式加载速度比较快，但是由于不能带header（例如csp等），可能会有一些安全问题。\n\nStandardSonicSession：SonicSession的子类，这种类型的session只是通过loadUrl，并且在资源拦截的时候返回数据。这种类型相比于QuickSonicSession速度上可能会慢一些（因为资源拦截需要内核底层派发，再到终端进行拦截）。但是这种方式支持在数据返回的时候添加header，所以不存在安全问题。\n\nSonicEngine：sonic引擎初始化，主要初始化sonic运行需要的runtime和context等信息。\n\nSonicRuntime：提供sonic运行环境需要的一些数据，比如context，文件的保存路径，页面的cookie等信息。\n\nSonicSessionClient：提供sonic与webview交互需要的功能，例如loadUrl，loadDataWithBaseUrl等\n\nSonicCacheInterceptor：sonic缓存数据的提供者，第三方可以提供自定义的缓存内容，也可以使用sonic默认提供的缓存数据。\n\nSonicSessionConnection：sonic底层连接的提供者，通过SonicSessionConnection去获取服务器的回包数据。\n\nSonicSessionStream：为sonic提供数据流，SonicSessionStream会将已读取的网络数据和未读取的网络数据组合成一个桥接流，将这个桥接的数据提供给webview内核进行渲染。利用webview流式加载功能减少耗时。\n\nSonicUtils：sonic工具类，主要负责sonic数据的模版分割，数据重组，diffdata计算等\n\nSonicFileUtils：sonic文件操作工具类，主要负责文件的读写\n\nSonicDataHelper：sonic数据帮助类，主要负责管理sonic除去文件内容之外的其它数据，比如html的md5值，模版的tag等等。\n\n\n\n\n"
  },
  {
    "path": "sonic-android/docs/javadoc/allclasses-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>所有类 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\">所有类</h1>\n<div class=\"indexContainer\">\n<ul>\n<li><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">QuickSonicSession</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicCacheInterceptor</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConfig</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConfig.Builder</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConstants</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicDBHelper</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicDiffDataCallback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCache</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCache.SonicResourceCache</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicDownloadCallback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCallback.SimpleDownloadCallback</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient.DownloadTask</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient.SubResourceDownloadCallback</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadEngine</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicEngine</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicFileUtils</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicResourceDataHelper</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicResourceDataHelper.ResourceData</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicRuntime</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicServer</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSession</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicSession.Callback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionClient</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConfig</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConfig.Builder</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnection</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnection.SessionConnectionDefaultImpl</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnectionInterceptor</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionStatistics</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionStream</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicSessionStream.Callback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicUtils</a></li>\n<li><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">StandardSonicSession</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/allclasses-noframe.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>所有类 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\">所有类</h1>\n<div class=\"indexContainer\">\n<ul>\n<li><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"interfaceName\">SonicDiffDataCallback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"interfaceName\">SonicDownloadCallback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"interfaceName\">SonicSession.Callback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"interfaceName\">SonicSessionStream.Callback</span></a></li>\n<li><a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></li>\n<li><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/QuickSonicSession.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>QuickSonicSession (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"QuickSonicSession (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/QuickSonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"QuickSonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 QuickSonicSession\" class=\"title\">类 QuickSonicSession</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">com.tencent.sonic.sdk.SonicSession</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.QuickSonicSession</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>android.os.Handler.Callback</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">QuickSonicSession</span>\nextends <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>\nimplements android.os.Handler.Callback</pre>\n<div class=\"block\">A subclass of SonicSession.\n QuickSonicSession mainly uses <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\"><code>SonicSessionClient.loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)</code></a>\n to load data. Sometime, it will use <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadUrl-java.lang.String-android.os.Bundle-\"><code>SonicSessionClient.loadUrl(String, Bundle)</code></a> instead. By using\n <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\"><code>SonicSessionClient.loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)</code></a>, WebView will\n quickly load web pages without the network affecting.\n\n <p>\n  ATTENTION:\n  Standard WebView don't have head information (such as csp) when it calls\n  <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\"><code>SonicSessionClient.loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)</code></a> method.\n  So this session mode may cause a security risk. However, you can put the csp contents into the html to avoid this risk caused by the lack of csp.\n\n <p>\n See also <a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><code>StandardSonicSession</code></a></div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的字段&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CHROME_FILE_THREAD\">CHROME_FILE_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_NOTIFY_RESULT\">CLIENT_MSG_NOTIFY_RESULT</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_ON_WEB_READY\">CLIENT_MSG_ON_WEB_READY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReady\">clientIsReady</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReload\">clientIsReload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_BEGIN\">COMMON_MSG_BEGIN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_END\">COMMON_MSG_END</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#config\">config</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createdTime\">createdTime</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#DATA_UPDATE_BUNDLE_PARAMS_DIFF\">DATA_UPDATE_BUNDLE_PARAMS_DIFF</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#diffDataCallback\">diffDataCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_MSG_BEGIN\">FILE_THREAD_MSG_BEGIN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#fileHandler\">fileHandler</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#finalResultCode\">finalResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#id\">id</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#intent\">intent</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload\">isPreload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForDestroy\">isWaitingForDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSaveFile\">isWaitingForSaveFile</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSessionThread\">isWaitingForSessionThread</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#mainHandler\">mainHandler</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_FALSE\">OFFLINE_MODE_FALSE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_HTTP\">OFFLINE_MODE_HTTP</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_STORE\">OFFLINE_MODE_STORE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_TRUE\">OFFLINE_MODE_TRUE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingDiffData\">pendingDiffData</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingWebResourceStream\">pendingWebResourceStream</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#preloadLinks\">preloadLinks</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_NONE\">RESOURCE_INTERCEPT_STATE_NONE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceDownloaderEngine\">resourceDownloaderEngine</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceInterceptState\">resourceInterceptState</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#server\">server</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SESSION_MSG_FORCE_DESTROY\">SESSION_MSG_FORCE_DESTROY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionCallbackList\">sessionCallbackList</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionClient\">sessionClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionState\">sessionState</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sId\">sId</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sNextSessionLogId\">sNextSessionLogId</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\">SONIC_RESULT_CODE_DATA_UPDATE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\">SONIC_RESULT_CODE_FIRST_LOAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_HIT_CACHE\">SONIC_RESULT_CODE_HIT_CACHE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\">SONIC_RESULT_CODE_TEMPLATE_CHANGE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_UNKNOWN\">SONIC_RESULT_CODE_UNKNOWN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcResultCode\">srcResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcUrl\">srcUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_DESTROY\">STATE_DESTROY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_NONE\">STATE_NONE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_READY\">STATE_READY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_RUNNING\">STATE_RUNNING</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#stateChangedCallbackList\">stateChangedCallbackList</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#statistics\">statistics</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasInterceptInvoked\">wasInterceptInvoked</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasOnPageFinishInvoked\">wasOnPageFinishInvoked</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_CODE\">WEB_RESPONSE_CODE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_DATA\">WEB_RESPONSE_DATA</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_EXTRA\">WEB_RESPONSE_EXTRA</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_LOCAL_REFRESH_TIME\">WEB_RESPONSE_LOCAL_REFRESH_TIME</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_SRC_CODE\">WEB_RESPONSE_SRC_CODE</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#clearSessionData--\">clearSessionData</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate</a></span>(java.lang.String&nbsp;serverRsp)</code>\n<div class=\"block\">In this case sonic obtains the difference data between the server and the local\n data first,then sonic will build the template and server data into html,\n then send a <code>CLIENT_CORE_MSG_DATA_UPDATE</code> message.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad</a></span>()</code>\n<div class=\"block\">In this case sonic will always read the new data from the server until the client\n initiates a resource interception.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError</a></span>(int&nbsp;responseCode)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache</a></span>(java.lang.String&nbsp;cacheHtml)</code>\n<div class=\"block\">Handle load local cache of html if exist.</div>\n</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange</a></span>(java.lang.String&nbsp;newHtml)</code>\n<div class=\"block\">In this case sonic will always read the new data from the server until the local page finish.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#handleMessage-android.os.Message-\">handleMessage</a></span>(android.os.Message&nbsp;msg)</code>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#onClientReady--\">onClientReady</a></span>()</code>\n<div class=\"block\">Client informs sonic that it is ready.</div>\n</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#onRequestResource-java.lang.String-\">onRequestResource</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</code>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">addSessionCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">addSessionStateChangedCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#bindClient-com.tencent.sonic.sdk.SonicSessionClient-\">bindClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#canDestroy--\">canDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createConnectionIntent-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">createConnectionIntent</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy--\">destroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy-boolean-\">destroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#doSaveSonicCache-com.tencent.sonic.sdk.SonicServer-java.lang.String-\">doSaveSonicCache</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCacheHeaders--\">getCacheHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders--\">getCharsetFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders-java.util.Map-\">getCharsetFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCurrentUrl--\">getCurrentUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getFinalResultCode--\">getFinalResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getHeaders--\">getHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSessionClient--\">getSessionClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSrcResultCode--\">getSrcResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getStatistics--\">getStatistics</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_Connection-boolean-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">handleFlow_Connection</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_NotModified--\">handleFlow_NotModified</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isDestroyedOrWaitingForDestroy--\">isDestroyedOrWaitingForDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isMatchCurrentUrl-java.lang.String-\">isMatchCurrentUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload--\">isPreload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#notifyStateChange-int-int-android.os.Bundle-\">notifyStateChange</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientPageFinished-java.lang.String-\">onClientPageFinished</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientRequestResource-java.lang.String-\">onClientRequestResource</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onServerClosed-com.tencent.sonic.sdk.SonicServer-boolean-\">onServerClosed</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postForceDestroyIfNeed--\">postForceDestroyIfNeed</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postTaskToSaveSonicCache-java.lang.String-\">postTaskToSaveSonicCache</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#refresh--\">refresh</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">removeSessionCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">removeSessionStateChangedCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setCookiesFromHeaders-java.util.Map-boolean-\">setCookiesFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setResult-int-int-boolean-\">setResult</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#shouldSetCookieAsynchronous--\">shouldSetCookieAsynchronous</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#start--\">start</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#switchState-int-int-boolean-\">switchState</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"handleMessage-android.os.Message-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleMessage</h4>\n<pre>public&nbsp;boolean&nbsp;handleMessage(android.os.Message&nbsp;msg)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">SonicSession</a></code></span></div>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>handleMessage</code>&nbsp;在接口中&nbsp;<code>android.os.Handler.Callback</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">handleMessage</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_LoadLocalCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_LoadLocalCache</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_LoadLocalCache(java.lang.String&nbsp;cacheHtml)</pre>\n<div class=\"block\">Handle load local cache of html if exist.\n This handle is called before connection.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>cacheHtml</code> - local cache of html</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onWebReady</h4>\n<pre>public&nbsp;boolean&nbsp;onWebReady(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">SonicSession</a></code></span></div>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>callback</code> - Sonic provides the latest data to the page through this callback</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The result</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onClientReady--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onClientReady</h4>\n<pre>public&nbsp;boolean&nbsp;onClientReady()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">SonicSession</a></code></span></div>\n<div class=\"block\">Client informs sonic that it is ready.\n Client ready means it's webview has been initialized, can start load url or load data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">onClientReady</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>True if it is set for the first time</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onRequestResource-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onRequestResource</h4>\n<pre>protected&nbsp;java.lang.Object&nbsp;onRequestResource(java.lang.String&nbsp;url)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">SonicSession</a></code></span></div>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">onRequestResource</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url of this session</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_HttpError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_HttpError</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_HttpError(int&nbsp;responseCode)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_ServiceUnavailable--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_ServiceUnavailable</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_ServiceUnavailable()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_TemplateChange-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_TemplateChange</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_TemplateChange(java.lang.String&nbsp;newHtml)</pre>\n<div class=\"block\">In this case sonic will always read the new data from the server until the local page finish.\n If the server data is read finished, sonic will send a <code>CLIENT_CORE_MSG_TEMPLATE_CHANGE</code>\n message.\n\n If the server data is not read finished sonic will split the read and unread data into a\n bridgedStream<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>. When the client initiates a resource interception,\n sonic will provide the bridgedStream to the kernel.\n\n <p>\n If need save and separate data, sonic will save the server data and separate the server data to template and data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>newHtml</code> - html content from server</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_FirstLoad--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_FirstLoad</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_FirstLoad()</pre>\n<div class=\"block\">In this case sonic will always read the new data from the server until the client\n initiates a resource interception.\n\n If the server data is read finished, sonic will send <code>CLIENT_CORE_MSG_FIRST_LOAD</code>\n message with the new html content from server.\n\n If the server data is not read finished sonic will split the read and unread data into\n a bridgedStream<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>.When client initiates a resource interception,\n sonic will provide the bridgedStream to the kernel.\n\n <p>\n If need save and separate data, sonic will save the server data and separate the server data\n to template and data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_DataUpdate-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_DataUpdate</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_DataUpdate(java.lang.String&nbsp;serverRsp)</pre>\n<div class=\"block\">In this case sonic obtains the difference data between the server and the local\n data first,then sonic will build the template and server data into html,\n then send a <code>CLIENT_CORE_MSG_DATA_UPDATE</code> message.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>serverRsp</code> - Server response data</dd>\n</dl>\n</li>\n</ul>\n<a name=\"clearSessionData--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>clearSessionData</h4>\n<pre>protected&nbsp;void&nbsp;clearSessionData()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clearSessionData--\">clearSessionData</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/QuickSonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"QuickSonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicCacheInterceptor.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicCacheInterceptor (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicCacheInterceptor (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicCacheInterceptor.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicCacheInterceptor.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicCacheInterceptor\" class=\"title\">类 SonicCacheInterceptor</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicCacheInterceptor</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicCacheInterceptor</span>\nextends java.lang.Object</pre>\n<div class=\"block\"><code>SonicCacheInterceptor</code> provide local data.\n if a <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionConfig</code></a> does not set a sonicCacheInterceptor\n sonic will use <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionConnection.SessionConnectionDefaultImpl</code></a> as default.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html#TAG\">TAG</a></span></code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html#SonicCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">SonicCacheInterceptor</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a>&nbsp;next)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html#getCacheData-com.tencent.sonic.sdk.SonicSession-\">getCacheData</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html#next--\">next</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicCacheInterceptor.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicCacheInterceptor</h4>\n<pre>public&nbsp;SonicCacheInterceptor(<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a>&nbsp;next)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"next--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>next</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a>&nbsp;next()</pre>\n</li>\n</ul>\n<a name=\"getCacheData-com.tencent.sonic.sdk.SonicSession-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getCacheData</h4>\n<pre>public abstract&nbsp;java.lang.String&nbsp;getCacheData(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicCacheInterceptor.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicCacheInterceptor.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConfig.Builder.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicConfig.Builder (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicConfig.Builder (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConfig.Builder.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConfig.Builder.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicConfig.Builder\" class=\"title\">类 SonicConfig.Builder</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicConfig.Builder</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicConfig.Builder</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Builder for SonicConfig</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#Builder--\">Builder</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#build--\">build</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setAutoInitDBWhenCreate-boolean-\">setAutoInitDBWhenCreate</a></span>(boolean&nbsp;autoInitDBWhenCreate)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheCheckTimeInterval-long-\">setCacheCheckTimeInterval</a></span>(long&nbsp;time)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheMaxSize-long-\">setCacheMaxSize</a></span>(long&nbsp;maxSize)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheVerifyWithSha1-boolean-\">setCacheVerifyWithSha1</a></span>(boolean&nbsp;enable)</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setGetCookieWhenSessionCreate-boolean-\">setGetCookieWhenSessionCreate</a></span>(boolean&nbsp;value)</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setMaxNumOfDownloadingTasks-int-\">setMaxNumOfDownloadingTasks</a></span>(int&nbsp;num)</code>&nbsp;</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setMaxPreloadSessionCount-int-\">setMaxPreloadSessionCount</a></span>(int&nbsp;maxPreloadSessionCount)</code>&nbsp;</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setResourceCacheMaxSize-long-\">setResourceCacheMaxSize</a></span>(long&nbsp;maxSize)</code>&nbsp;</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setSonicCacheMaxAge-int-\">setSonicCacheMaxAge</a></span>(int&nbsp;maxAge)</code>&nbsp;</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html#setUnavailableTime-long-\">setUnavailableTime</a></span>(long&nbsp;unavailableTime)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"Builder--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>Builder</h4>\n<pre>public&nbsp;Builder()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"setMaxPreloadSessionCount-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setMaxPreloadSessionCount</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setMaxPreloadSessionCount(int&nbsp;maxPreloadSessionCount)</pre>\n</li>\n</ul>\n<a name=\"setUnavailableTime-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setUnavailableTime</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setUnavailableTime(long&nbsp;unavailableTime)</pre>\n</li>\n</ul>\n<a name=\"setCacheVerifyWithSha1-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCacheVerifyWithSha1</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setCacheVerifyWithSha1(boolean&nbsp;enable)</pre>\n</li>\n</ul>\n<a name=\"setCacheMaxSize-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCacheMaxSize</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setCacheMaxSize(long&nbsp;maxSize)</pre>\n</li>\n</ul>\n<a name=\"setResourceCacheMaxSize-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setResourceCacheMaxSize</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setResourceCacheMaxSize(long&nbsp;maxSize)</pre>\n</li>\n</ul>\n<a name=\"setCacheCheckTimeInterval-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCacheCheckTimeInterval</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setCacheCheckTimeInterval(long&nbsp;time)</pre>\n</li>\n</ul>\n<a name=\"setMaxNumOfDownloadingTasks-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setMaxNumOfDownloadingTasks</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setMaxNumOfDownloadingTasks(int&nbsp;num)</pre>\n</li>\n</ul>\n<a name=\"setAutoInitDBWhenCreate-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setAutoInitDBWhenCreate</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setAutoInitDBWhenCreate(boolean&nbsp;autoInitDBWhenCreate)</pre>\n</li>\n</ul>\n<a name=\"setGetCookieWhenSessionCreate-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setGetCookieWhenSessionCreate</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setGetCookieWhenSessionCreate(boolean&nbsp;value)</pre>\n</li>\n</ul>\n<a name=\"setSonicCacheMaxAge-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setSonicCacheMaxAge</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a>&nbsp;setSonicCacheMaxAge(int&nbsp;maxAge)</pre>\n</li>\n</ul>\n<a name=\"build--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>build</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a>&nbsp;build()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConfig.Builder.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConfig.Builder.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConfig.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicConfig (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicConfig (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConfig.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConfig.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicConfig\" class=\"title\">类 SonicConfig</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicConfig</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicConfig</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Sonic global config</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></span></code>\n<div class=\"block\">Builder for SonicConfig</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#SONIC_MAX_NUM_OF_DOWNLOADING_TASK\">SONIC_MAX_NUM_OF_DOWNLOADING_TASK</a></span></code>\n<div class=\"block\">The max number of tasks which is downloading in the same time.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#VERIFY_CACHE_FILE_WITH_SHA1\">VERIFY_CACHE_FILE_WITH_SHA1</a></span></code>\n<div class=\"block\">Whether verify file by compare SHA1.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"SONIC_MAX_NUM_OF_DOWNLOADING_TASK\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_MAX_NUM_OF_DOWNLOADING_TASK</h4>\n<pre>public&nbsp;int SONIC_MAX_NUM_OF_DOWNLOADING_TASK</pre>\n<div class=\"block\">The max number of tasks which is downloading in the same time.</div>\n</li>\n</ul>\n<a name=\"VERIFY_CACHE_FILE_WITH_SHA1\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>VERIFY_CACHE_FILE_WITH_SHA1</h4>\n<pre>public&nbsp;boolean VERIFY_CACHE_FILE_WITH_SHA1</pre>\n<div class=\"block\">Whether verify file by compare SHA1. If this value is false, sonic will verify file by file's size.\n Verify the file size is less time consuming than checking SHA1.</div>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConfig.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConfig.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicConstants.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicConstants (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicConstants (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConstants.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConstants.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicConstants\" class=\"title\">类 SonicConstants</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicConstants</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicConstants</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Sonic constants</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_BUILD_HTML_ERROR\">ERROR_CODE_BUILD_HTML_ERROR</a></span></code>\n<div class=\"block\">Build template and data to html failed</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_IOE\">ERROR_CODE_CONNECT_IOE</a></span></code>\n<div class=\"block\">Http(s) connection error : IO Exception</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_NPE\">ERROR_CODE_CONNECT_NPE</a></span></code>\n<div class=\"block\">Http(s) connection error : nullPointer in native</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_TOE\">ERROR_CODE_CONNECT_TOE</a></span></code>\n<div class=\"block\">Http(s) connection error : time out</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_DATA_VERIFY_FAIL\">ERROR_CODE_DATA_VERIFY_FAIL</a></span></code>\n<div class=\"block\">Verify local file failed</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MAKE_DIR_ERROR\">ERROR_CODE_MAKE_DIR_ERROR</a></span></code>\n<div class=\"block\">Failed to create sonic directory</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MERGE_DIFF_DATA_FAIL\">ERROR_CODE_MERGE_DIFF_DATA_FAIL</a></span></code>\n<div class=\"block\">Obtain difference data between server and local data failed</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SERVER_DATA_EXCEPTION\">ERROR_CODE_SERVER_DATA_EXCEPTION</a></span></code>\n<div class=\"block\">Server data exception</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SPLIT_HTML_FAIL\">ERROR_CODE_SPLIT_HTML_FAIL</a></span></code>\n<div class=\"block\">Separate html to template and data failed</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SUCCESS\">ERROR_CODE_SUCCESS</a></span></code>\n<div class=\"block\">Success</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_UNKNOWN\">ERROR_CODE_UNKNOWN</a></span></code>\n<div class=\"block\">Unknown</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_WRITE_FILE_FAIL\">ERROR_CODE_WRITE_FILE_FAIL</a></span></code>\n<div class=\"block\">File save failed</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_DEFAULT\">SESSION_MODE_DEFAULT</a></span></code>\n<div class=\"block\">SonicSession mode : StandardSonicSession</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_QUICK\">SESSION_MODE_QUICK</a></span></code>\n<div class=\"block\">SonicSession mode : QuickSonicSession</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SONIC_PARAMETER_NAME_PREFIX\">SONIC_PARAMETER_NAME_PREFIX</a></span></code>\n<div class=\"block\">Sonic parameter prefix</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_NAMES\">SONIC_REMAIN_PARAMETER_NAMES</a></span></code>\n<div class=\"block\">This parameter in url will be as part of session id，and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">SONIC_REMAIN_PARAMETER_SPLIT_CHAR</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SONIC_SDK_LOG_PREFIX\">SONIC_SDK_LOG_PREFIX</a></span></code>\n<div class=\"block\">SonicSDK log prefix</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SONIC_VERSION_NUM\">SONIC_VERSION_NUM</a></span></code>\n<div class=\"block\">SonicSDK version</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html#SonicConstants--\">SonicConstants</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"SONIC_SDK_LOG_PREFIX\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_SDK_LOG_PREFIX</h4>\n<pre>public static final&nbsp;java.lang.String SONIC_SDK_LOG_PREFIX</pre>\n<div class=\"block\">SonicSDK log prefix</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SONIC_SDK_LOG_PREFIX\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_VERSION_NUM\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_VERSION_NUM</h4>\n<pre>public static final&nbsp;java.lang.String SONIC_VERSION_NUM</pre>\n<div class=\"block\">SonicSDK version</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SONIC_VERSION_NUM\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_PARAMETER_NAME_PREFIX\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_PARAMETER_NAME_PREFIX</h4>\n<pre>public static final&nbsp;java.lang.String SONIC_PARAMETER_NAME_PREFIX</pre>\n<div class=\"block\">Sonic parameter prefix</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SONIC_PARAMETER_NAME_PREFIX\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_REMAIN_PARAMETER_NAMES\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_REMAIN_PARAMETER_NAMES</h4>\n<pre>public static final&nbsp;java.lang.String SONIC_REMAIN_PARAMETER_NAMES</pre>\n<div class=\"block\">This parameter in url will be as part of session id，and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SONIC_REMAIN_PARAMETER_NAMES\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_REMAIN_PARAMETER_SPLIT_CHAR</h4>\n<pre>public static final&nbsp;java.lang.String SONIC_REMAIN_PARAMETER_SPLIT_CHAR</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SESSION_MODE_DEFAULT\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SESSION_MODE_DEFAULT</h4>\n<pre>public static final&nbsp;int SESSION_MODE_DEFAULT</pre>\n<div class=\"block\">SonicSession mode : StandardSonicSession</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SESSION_MODE_DEFAULT\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SESSION_MODE_QUICK\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SESSION_MODE_QUICK</h4>\n<pre>public static final&nbsp;int SESSION_MODE_QUICK</pre>\n<div class=\"block\">SonicSession mode : QuickSonicSession</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.SESSION_MODE_QUICK\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_UNKNOWN\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_UNKNOWN</h4>\n<pre>public static final&nbsp;int ERROR_CODE_UNKNOWN</pre>\n<div class=\"block\">Unknown</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_UNKNOWN\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_SUCCESS\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_SUCCESS</h4>\n<pre>public static final&nbsp;int ERROR_CODE_SUCCESS</pre>\n<div class=\"block\">Success</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SUCCESS\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_CONNECT_IOE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_CONNECT_IOE</h4>\n<pre>public static final&nbsp;int ERROR_CODE_CONNECT_IOE</pre>\n<div class=\"block\">Http(s) connection error : IO Exception</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_IOE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_CONNECT_TOE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_CONNECT_TOE</h4>\n<pre>public static final&nbsp;int ERROR_CODE_CONNECT_TOE</pre>\n<div class=\"block\">Http(s) connection error : time out</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_TOE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_CONNECT_NPE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_CONNECT_NPE</h4>\n<pre>public static final&nbsp;int ERROR_CODE_CONNECT_NPE</pre>\n<div class=\"block\">Http(s) connection error : nullPointer in native</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_NPE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_DATA_VERIFY_FAIL\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_DATA_VERIFY_FAIL</h4>\n<pre>public static final&nbsp;int ERROR_CODE_DATA_VERIFY_FAIL</pre>\n<div class=\"block\">Verify local file failed</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_DATA_VERIFY_FAIL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_MAKE_DIR_ERROR\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_MAKE_DIR_ERROR</h4>\n<pre>public static final&nbsp;int ERROR_CODE_MAKE_DIR_ERROR</pre>\n<div class=\"block\">Failed to create sonic directory</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_MAKE_DIR_ERROR\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_WRITE_FILE_FAIL\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_WRITE_FILE_FAIL</h4>\n<pre>public static final&nbsp;int ERROR_CODE_WRITE_FILE_FAIL</pre>\n<div class=\"block\">File save failed</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_WRITE_FILE_FAIL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_SPLIT_HTML_FAIL\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_SPLIT_HTML_FAIL</h4>\n<pre>public static final&nbsp;int ERROR_CODE_SPLIT_HTML_FAIL</pre>\n<div class=\"block\">Separate html to template and data failed</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SPLIT_HTML_FAIL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_MERGE_DIFF_DATA_FAIL\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_MERGE_DIFF_DATA_FAIL</h4>\n<pre>public static final&nbsp;int ERROR_CODE_MERGE_DIFF_DATA_FAIL</pre>\n<div class=\"block\">Obtain difference data between server and local data failed</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_MERGE_DIFF_DATA_FAIL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_SERVER_DATA_EXCEPTION\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_SERVER_DATA_EXCEPTION</h4>\n<pre>public static final&nbsp;int ERROR_CODE_SERVER_DATA_EXCEPTION</pre>\n<div class=\"block\">Server data exception</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SERVER_DATA_EXCEPTION\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"ERROR_CODE_BUILD_HTML_ERROR\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>ERROR_CODE_BUILD_HTML_ERROR</h4>\n<pre>public static final&nbsp;int ERROR_CODE_BUILD_HTML_ERROR</pre>\n<div class=\"block\">Build template and data to html failed</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_BUILD_HTML_ERROR\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicConstants--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicConstants</h4>\n<pre>public&nbsp;SonicConstants()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicConstants.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicConstants.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicDBHelper.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDBHelper (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDBHelper (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":9,\"i1\":10,\"i2\":10,\"i3\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicDBHelper.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDBHelper.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicDBHelper\" class=\"title\">类 SonicDBHelper</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>android.database.sqlite.SQLiteOpenHelper</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicDBHelper</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicDBHelper</span>\nextends android.database.sqlite.SQLiteOpenHelper</pre>\n<div class=\"block\">SonicDBHelper interacts with the database, such as managing database creation and\n the version management.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html#getInstance--\">getInstance</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html#isUpgrading--\">isUpgrading</a></span>()</code>\n<div class=\"block\">Indicates whether is upgrading or not.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html#onCreate-android.database.sqlite.SQLiteDatabase-\">onCreate</a></span>(android.database.sqlite.SQLiteDatabase&nbsp;db)</code>\n<div class=\"block\">Called when the database is created for the first time.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html#onUpgrade-android.database.sqlite.SQLiteDatabase-int-int-\">onUpgrade</a></span>(android.database.sqlite.SQLiteDatabase&nbsp;db,\n         int&nbsp;oldVersion,\n         int&nbsp;newVersion)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.android.database.sqlite.SQLiteOpenHelper\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;android.database.sqlite.SQLiteOpenHelper</h3>\n<code>close, getDatabaseName, getReadableDatabase, getWritableDatabase, onConfigure, onDowngrade, onOpen, setWriteAheadLoggingEnabled</code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getInstance--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getInstance</h4>\n<pre>public static&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a>&nbsp;getInstance()</pre>\n</li>\n</ul>\n<a name=\"onCreate-android.database.sqlite.SQLiteDatabase-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onCreate</h4>\n<pre>public&nbsp;void&nbsp;onCreate(android.database.sqlite.SQLiteDatabase&nbsp;db)</pre>\n<div class=\"block\">Called when the database is created for the first time. This is where the\n creation of tables and the initial population of the tables should happen.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>onCreate</code>&nbsp;在类中&nbsp;<code>android.database.sqlite.SQLiteOpenHelper</code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>db</code> - The database.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onUpgrade-android.database.sqlite.SQLiteDatabase-int-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onUpgrade</h4>\n<pre>public&nbsp;void&nbsp;onUpgrade(android.database.sqlite.SQLiteDatabase&nbsp;db,\n                      int&nbsp;oldVersion,\n                      int&nbsp;newVersion)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>onUpgrade</code>&nbsp;在类中&nbsp;<code>android.database.sqlite.SQLiteOpenHelper</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"isUpgrading--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>isUpgrading</h4>\n<pre>public&nbsp;boolean&nbsp;isUpgrading()</pre>\n<div class=\"block\">Indicates whether is upgrading or not. If return true, It will fail to create session.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>is Upgrading or not</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicDBHelper.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDBHelper.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicDiffDataCallback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDiffDataCallback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDiffDataCallback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicDiffDataCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDiffDataCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"接口 SonicDiffDataCallback\" class=\"title\">接口 SonicDiffDataCallback</h2>\n</div>\n<div class=\"contentContainer\">\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public interface <span class=\"typeNameLabel\">SonicDiffDataCallback</span></pre>\n<div class=\"block\">This interface is used to call the difference data between local and server data\n to the client.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html#callback-java.lang.String-\">callback</a></span>(java.lang.String&nbsp;resultData)</code>\n<div class=\"block\">Called when sonic processes the local data and the server data.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"callback-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>callback</h4>\n<pre>void&nbsp;callback(java.lang.String&nbsp;resultData)</pre>\n<div class=\"block\">Called when sonic processes the local data and the server data.\n When the page requests the latest data, sonic will send the latest\n data to page by this method.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resultData</code> - The result to page.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicDiffDataCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDiffDataCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicEngine.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicEngine (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicEngine (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":9,\"i2\":10,\"i3\":10,\"i4\":9,\"i5\":10,\"i6\":10,\"i7\":9,\"i8\":10,\"i9\":9,\"i10\":10,\"i11\":10,\"i12\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicEngine.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicEngine.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicEngine\" class=\"title\">类 SonicEngine</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicEngine</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicEngine</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Interacts with the overall SonicSessions running in the system.\n Instances of this class can be used to query or fetch the information, such as SonicSession SonicRuntime.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#cleanCache--\">cleanCache</a></span>()</code>\n<div class=\"block\">Removes all of the cache from <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a> and deletes file caches from SDCard.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\">createInstance</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a>&nbsp;runtime,\n              <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a>&nbsp;config)</code>\n<div class=\"block\">Create SonicEngine instance.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">createSession</a></span>(java.lang.String&nbsp;url,\n             <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a>&nbsp;sessionConfig)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#getConfig--\">getConfig</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#getInstance--\">getInstance</a></span>()</code>\n<div class=\"block\">Returns a SonicEngine instance\n \n Make sure <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\"><code>createInstance(SonicRuntime, SonicConfig)</code></a> has been called.</div>\n</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#getRuntime--\">getRuntime</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#initSonicDB--\">initSonicDB</a></span>()</code>\n<div class=\"block\">Init sonic DB which will upgrade to new version of database.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#isGetInstanceAllowed--\">isGetInstanceAllowed</a></span>()</code>\n<div class=\"block\">Check if <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#getInstance--\"><code>getInstance()</code></a> is ready or not.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#isSonicAvailable--\">isSonicAvailable</a></span>()</code>\n<div class=\"block\">Whether Sonic Service is available or not</div>\n</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#makeSessionId-java.lang.String-boolean-\">makeSessionId</a></span>(java.lang.String&nbsp;url,\n             boolean&nbsp;isAccountRelated)</code>\n<div class=\"block\">Create session ID</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preCreateSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">preCreateSession</a></span>(java.lang.String&nbsp;url,\n                <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a>&nbsp;sessionConfig)</code>\n<div class=\"block\">This method will preCreate sonic session .</div>\n</td>\n</tr>\n<tr id=\"i11\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#removeSessionCache-java.lang.String-\">removeSessionCache</a></span>(java.lang.String&nbsp;sessionId)</code>\n<div class=\"block\">Removes the sessionId and its corresponding SonicSession from <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a>.</div>\n</td>\n</tr>\n<tr id=\"i12\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#trimSonicCache--\">trimSonicCache</a></span>()</code>\n<div class=\"block\">It will Post a task to trim sonic cache\n if the last time of check sonic cache exceed <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#SONIC_CACHE_CHECK_TIME_INTERVAL\"><code>SonicConfig.SONIC_CACHE_CHECK_TIME_INTERVAL</code></a>.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getInstance--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getInstance</h4>\n<pre>public static&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a>&nbsp;getInstance()</pre>\n<div class=\"block\">Returns a SonicEngine instance\n <p>\n Make sure <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\"><code>createInstance(SonicRuntime, SonicConfig)</code></a> has been called.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>SonicEngine instance</dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.lang.IllegalStateException</code> - if <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\"><code>createInstance(SonicRuntime, SonicConfig)</code></a> hasn't been called</dd>\n</dl>\n</li>\n</ul>\n<a name=\"isGetInstanceAllowed--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isGetInstanceAllowed</h4>\n<pre>public static&nbsp;boolean&nbsp;isGetInstanceAllowed()</pre>\n<div class=\"block\">Check if <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#getInstance--\"><code>getInstance()</code></a> is ready or not.\n <p><b>Note: <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\"><code>createInstance(SonicRuntime, SonicConfig)</code></a> must be called if <code>false</code> is returned.</b></p></div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return <code>true</code> if <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#sInstance\"><code>sInstance</code></a> is not null, <code>false</code> otherwise</dd>\n</dl>\n</li>\n</ul>\n<a name=\"createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createInstance</h4>\n<pre>public static&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a>&nbsp;createInstance(@NonNull\n                                         <a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a>&nbsp;runtime,\n                                         @NonNull\n                                         <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a>&nbsp;config)</pre>\n<div class=\"block\">Create SonicEngine instance. Meanwhile it will initialize engine and SonicRuntime.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>runtime</code> - SonicRuntime</dd>\n<dd><code>config</code> - SonicConfig</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>SonicEngine object</dd>\n</dl>\n</li>\n</ul>\n<a name=\"initSonicDB--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>initSonicDB</h4>\n<pre>public&nbsp;void&nbsp;initSonicDB()</pre>\n<div class=\"block\">Init sonic DB which will upgrade to new version of database.</div>\n</li>\n</ul>\n<a name=\"getRuntime--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getRuntime</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a>&nbsp;getRuntime()</pre>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>SonicRuntime object</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getConfig--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getConfig</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a>&nbsp;getConfig()</pre>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>SonicConfig object</dd>\n</dl>\n</li>\n</ul>\n<a name=\"isSonicAvailable--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isSonicAvailable</h4>\n<pre>public&nbsp;boolean&nbsp;isSonicAvailable()</pre>\n<div class=\"block\">Whether Sonic Service is available or not</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>return true if Sonic Service is available , false else others.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"makeSessionId-java.lang.String-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>makeSessionId</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;makeSessionId(java.lang.String&nbsp;url,\n                                             boolean&nbsp;isAccountRelated)</pre>\n<div class=\"block\">Create session ID</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - session url</dd>\n<dd><code>isAccountRelated</code> - Session Id will contain <a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getCurrentUserAccount--\"><code>SonicRuntime.getCurrentUserAccount()</code></a>  if <code>isAccountRelated </code> is true.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>String Object of session ID</dd>\n</dl>\n</li>\n</ul>\n<a name=\"preCreateSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>preCreateSession</h4>\n<pre>public&nbsp;boolean&nbsp;preCreateSession(@NonNull\n                                java.lang.String&nbsp;url,\n                                @NonNull\n                                <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a>&nbsp;sessionConfig)</pre>\n<div class=\"block\">This method will preCreate sonic session .\n And maps the specified session id to the specified value in this table <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a> if there is no same sonic session.\n At the same time, if the number of <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a> exceeds <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#MAX_PRELOAD_SESSION_COUNT\"><code>SonicConfig.MAX_PRELOAD_SESSION_COUNT</code></a>,\n preCreateSession will return false and not create any sonic session.\n\n <p><b>Note: this method is intended for preload scene.</b></p></div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - url for preCreate sonic session</dd>\n<dd><code>sessionConfig</code> - SonicSession config</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>If this method preCreate sonic session and associated with <code>sessionId</code> in this table <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a> successfully,\n  it will return true,\n  <code>false</code> otherwise.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"createSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createSession</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;createSession(@NonNull\n                                  java.lang.String&nbsp;url,\n                                  @NonNull\n                                  <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a>&nbsp;sessionConfig)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - url for SonicSession Object</dd>\n<dd><code>sessionConfig</code> - SSonicSession config</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>This method will create and return SonicSession Object when url is legal.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"cleanCache--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>cleanCache</h4>\n<pre>public&nbsp;boolean&nbsp;cleanCache()</pre>\n<div class=\"block\">Removes all of the cache from <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a> and deletes file caches from SDCard.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns <code>false</code> if <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#runningSessionHashMap\"><code>runningSessionHashMap</code></a> is not empty.\n      Returns <code>true</code> if all of the local file cache has been deleted, <code>false</code> otherwise</dd>\n</dl>\n</li>\n</ul>\n<a name=\"removeSessionCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>removeSessionCache</h4>\n<pre>public&nbsp;boolean&nbsp;removeSessionCache(@NonNull\n                                  java.lang.String&nbsp;sessionId)</pre>\n<div class=\"block\">Removes the sessionId and its corresponding SonicSession from <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>preloadSessionPool</code></a>.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>sessionId</code> - A unique session id</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return <code>true</code> If there is no specified sessionId in <a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html#runningSessionHashMap\"><code>runningSessionHashMap</code></a>, <code>false</code> otherwise.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"trimSonicCache--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>trimSonicCache</h4>\n<pre>public&nbsp;void&nbsp;trimSonicCache()</pre>\n<div class=\"block\">It will Post a task to trim sonic cache\n if the last time of check sonic cache exceed <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#SONIC_CACHE_CHECK_TIME_INTERVAL\"><code>SonicConfig.SONIC_CACHE_CHECK_TIME_INTERVAL</code></a>.</div>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicEngine.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicEngine.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicFileUtils.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicFileUtils (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicFileUtils (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":9,\"i1\":9,\"i2\":9,\"i3\":9,\"i4\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicFileUtils.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFileUtils.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicFileUtils\" class=\"title\">类 SonicFileUtils</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicFileUtils</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicFileUtils</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Interact with the overall file operations.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#SonicFileUtils--\">SonicFileUtils</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>static java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#getHeaderFromLocalCache-java.lang.String-\">getHeaderFromLocalCache</a></span>(java.lang.String&nbsp;headerPath)</code>\n<div class=\"block\">Get headers from local cache file</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#getSonicResourceHeaderPath-java.lang.String-\">getSonicResourceHeaderPath</a></span>(java.lang.String&nbsp;resourceName)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#getSonicResourcePath-java.lang.String-\">getSonicResourcePath</a></span>(java.lang.String&nbsp;resourceName)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static byte[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#readFileToBytes-java.io.File-\">readFileToBytes</a></span>(java.io.File&nbsp;file)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>static boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html#verifyData-byte:A-java.lang.String-\">verifyData</a></span>(byte[]&nbsp;content,\n          java.lang.String&nbsp;targetSha1)</code>\n<div class=\"block\">This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicFileUtils--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicFileUtils</h4>\n<pre>public&nbsp;SonicFileUtils()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getSonicResourcePath-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSonicResourcePath</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;getSonicResourcePath(java.lang.String&nbsp;resourceName)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceName</code> - resource file name</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The path of the resource file.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSonicResourceHeaderPath-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSonicResourceHeaderPath</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;getSonicResourceHeaderPath(java.lang.String&nbsp;resourceName)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceName</code> - resource file name</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The path of the resource header file.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"verifyData-byte:A-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>verifyData</h4>\n<pre>public static&nbsp;boolean&nbsp;verifyData(byte[]&nbsp;content,\n                                 java.lang.String&nbsp;targetSha1)</pre>\n<div class=\"block\">This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>content</code> - Data bytes</dd>\n<dd><code>targetSha1</code> - The specified hash value</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd><code>true</code> if the given hash value\n          equivalent to computed hash value, <code>false</code> otherwise</dd>\n</dl>\n</li>\n</ul>\n<a name=\"readFileToBytes-java.io.File-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>readFileToBytes</h4>\n<pre>public static&nbsp;byte[]&nbsp;readFileToBytes(java.io.File&nbsp;file)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>file</code> - path of the file to read</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the content bytes read from the file.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getHeaderFromLocalCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getHeaderFromLocalCache</h4>\n<pre>public static&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getHeaderFromLocalCache(java.lang.String&nbsp;headerPath)</pre>\n<div class=\"block\">Get headers from local cache file</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>headerPath</code> - header file path</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The last http response headers from local cache.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicFileUtils.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFileUtils.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicResourceDataHelper.ResourceData (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicResourceDataHelper.ResourceData (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicResourceDataHelper.ResourceData.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicResourceDataHelper.ResourceData\" class=\"title\">类 SonicResourceDataHelper.ResourceData</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicResourceDataHelper.ResourceData</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicResourceDataHelper.ResourceData</span>\nextends java.lang.Object</pre>\n<div class=\"block\">resource data structure</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#expiredTime\">expiredTime</a></span></code>\n<div class=\"block\">Indicates when local resource cache is expired.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#resourceSha1\">resourceSha1</a></span></code>\n<div class=\"block\">The sha1 of resource</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#resourceSize\">resourceSize</a></span></code>\n<div class=\"block\">The size of resource</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#ResourceData--\">ResourceData</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#reset--\">reset</a></span>()</code>\n<div class=\"block\">Reset data</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"resourceSha1\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>resourceSha1</h4>\n<pre>public&nbsp;java.lang.String resourceSha1</pre>\n<div class=\"block\">The sha1 of resource</div>\n</li>\n</ul>\n<a name=\"resourceSize\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>resourceSize</h4>\n<pre>public&nbsp;long resourceSize</pre>\n<div class=\"block\">The size of resource</div>\n</li>\n</ul>\n<a name=\"expiredTime\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>expiredTime</h4>\n<pre>public&nbsp;long expiredTime</pre>\n<div class=\"block\">Indicates when local resource cache is expired.\n If It is expired, the record of database and file on SDCard will be removed.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"ResourceData--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>ResourceData</h4>\n<pre>public&nbsp;ResourceData()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"reset--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>reset</h4>\n<pre>public&nbsp;void&nbsp;reset()</pre>\n<div class=\"block\">Reset data</div>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicResourceDataHelper.ResourceData.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicResourceDataHelper.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicResourceDataHelper (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicResourceDataHelper (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":9,\"i1\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicResourceDataHelper.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicResourceDataHelper.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicResourceDataHelper\" class=\"title\">类 SonicResourceDataHelper</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicResourceDataHelper</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicResourceDataHelper</span>\nextends java.lang.Object</pre>\n<div class=\"block\">SonicResourceDataHelper manages the resource database.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></span></code>\n<div class=\"block\">resource data structure</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html#CREATE_TABLE_SQL\">CREATE_TABLE_SQL</a></span></code>\n<div class=\"block\">The create table sql</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html#SonicResourceDataHelper--\">SonicResourceDataHelper</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html#getAllResourceDataColumn--\">getAllResourceDataColumn</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html#getResourceData-java.lang.String-\">getResourceData</a></span>(java.lang.String&nbsp;resourceId)</code>\n<div class=\"block\">Get sonic ResourceData by unique resource id</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"CREATE_TABLE_SQL\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>CREATE_TABLE_SQL</h4>\n<pre>public static final&nbsp;java.lang.String CREATE_TABLE_SQL</pre>\n<div class=\"block\">The create table sql</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicResourceDataHelper.CREATE_TABLE_SQL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicResourceDataHelper--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicResourceDataHelper</h4>\n<pre>public&nbsp;SonicResourceDataHelper()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getResourceData-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResourceData</h4>\n<pre>@NonNull\npublic static&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a>&nbsp;getResourceData(java.lang.String&nbsp;resourceId)</pre>\n<div class=\"block\">Get sonic ResourceData by unique resource id</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceId</code> - a unique resource id</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>ResourceData</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getAllResourceDataColumn--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getAllResourceDataColumn</h4>\n<pre>public static&nbsp;java.lang.String[]&nbsp;getAllResourceDataColumn()</pre>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>all of the column in <code>Sonic_RESOURCE_TABLE_NAME</code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicResourceDataHelper.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicResourceDataHelper.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicRuntime.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicRuntime (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicRuntime (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":10,\"i2\":6,\"i3\":6,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":6,\"i11\":6,\"i12\":6,\"i13\":6,\"i14\":10,\"i15\":6,\"i16\":10,\"i17\":10,\"i18\":6,\"i19\":6,\"i20\":10,\"i21\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicRuntime.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicRuntime.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicRuntime\" class=\"title\">类 SonicRuntime</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicRuntime</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicRuntime</span>\nextends java.lang.Object</pre>\n<div class=\"block\"><code>SonicRuntime</code> is a class which interacts with the overall running information in the system,\n including Context, UA, ID (which is the unique identification for the saved data) and other information.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected android.content.Context</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#context\">context</a></span></code>\n<div class=\"block\">A context for this runtime, it's expected to be ApplicationContext</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static android.os.HandlerThread</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#fileHandlerThread\">fileHandlerThread</a></span></code>\n<div class=\"block\">This handle thread use to save sonic cache.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#SonicRuntime-android.content.Context-\">SonicRuntime</a></span>(android.content.Context&nbsp;context)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#createWebResourceResponse-java.lang.String-java.lang.String-java.io.InputStream-java.util.Map-\">createWebResourceResponse</a></span>(java.lang.String&nbsp;mimeType,\n                         java.lang.String&nbsp;encoding,\n                         java.io.InputStream&nbsp;data,\n                         java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</code>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>android.content.Context</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getContext--\">getContext</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getCookie-java.lang.String-\">getCookie</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">Get cookies of the input url, this method will be called before sonic session make a\n session connection to request data.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getCurrentUserAccount--\">getCurrentUserAccount</a></span>()</code>\n<div class=\"block\">Get the current user account, this method will be called when makeSessionId's params is\n account related.</div>\n</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>android.os.Looper</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getFileThreadLooper--\">getFileThreadLooper</a></span>()</code>\n<div class=\"block\">Return the looper of HandleThread which use to save sonic cache.</div>\n</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getHostDirectAddress-java.lang.String-\">getHostDirectAddress</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">Get the direct address of a url(host)，format as[ip:port]，the default http port is 80 and\n 443 for https.</div>\n</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.util.Set&lt;java.lang.String&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getQueryParameterNames-android.net.Uri-\">getQueryParameterNames</a></span>(android.net.Uri&nbsp;uri)</code>\n<div class=\"block\">Returns a set of the unique names of all query parameters.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.io.File</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getSonicCacheDir--\">getSonicCacheDir</a></span>()</code>\n<div class=\"block\">The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.io.File</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getSonicResourceCacheDir--\">getSonicResourceCacheDir</a></span>()</code>\n<div class=\"block\">The resource cache root dir which resource cache will be storage.</div>\n</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>android.content.SharedPreferences</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getSonicSharedPreferences--\">getSonicSharedPreferences</a></span>()</code>\n<div class=\"block\">get SharedPreferences of sonic.</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#getUserAgent--\">getUserAgent</a></span>()</code>\n<div class=\"block\">Get user agent of current runtime, this method will be called before sonic session make a\n session connection to request data.</div>\n</td>\n</tr>\n<tr id=\"i11\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#isNetworkValid--\">isNetworkValid</a></span>()</code>\n<div class=\"block\">This method is used to judge is network valid or not</div>\n</td>\n</tr>\n<tr id=\"i12\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#isSonicUrl-java.lang.String-\">isSonicUrl</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">This method is used to judge the input url is support sonic or not, when this method return\n true, it means it's allow to create a sonic session for this url.</div>\n</td>\n</tr>\n<tr id=\"i13\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#log-java.lang.String-int-java.lang.String-\">log</a></span>(java.lang.String&nbsp;tag,\n   int&nbsp;level,\n   java.lang.String&nbsp;message)</code>&nbsp;</td>\n</tr>\n<tr id=\"i14\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#makeSessionId-java.lang.String-boolean-\">makeSessionId</a></span>(java.lang.String&nbsp;url,\n             boolean&nbsp;isAccountRelated)</code>\n<div class=\"block\">Make a unique session id for the url, it can be account related.</div>\n</td>\n</tr>\n<tr id=\"i15\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#notifyError-com.tencent.sonic.sdk.SonicSessionClient-java.lang.String-int-\">notifyError</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a>&nbsp;client,\n           java.lang.String&nbsp;url,\n           int&nbsp;errorCode)</code>\n<div class=\"block\">Notify error for host application to do report or statics</div>\n</td>\n</tr>\n<tr id=\"i16\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#postTaskToMainThread-java.lang.Runnable-long-\">postTaskToMainThread</a></span>(java.lang.Runnable&nbsp;task,\n                    long&nbsp;delayMillis)</code>\n<div class=\"block\">Post a task in main thread</div>\n</td>\n</tr>\n<tr id=\"i17\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#postTaskToSessionThread-java.lang.Runnable-\">postTaskToSessionThread</a></span>(java.lang.Runnable&nbsp;task)</code>\n<div class=\"block\">Post a task to session thread(a high priority thread is better)</div>\n</td>\n</tr>\n<tr id=\"i18\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#postTaskToThread-java.lang.Runnable-long-\">postTaskToThread</a></span>(java.lang.Runnable&nbsp;task,\n                long&nbsp;delayMillis)</code>\n<div class=\"block\">Post a task to the thread(a io thread is better) which used to separate template and data.</div>\n</td>\n</tr>\n<tr id=\"i19\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#setCookie-java.lang.String-java.util.List-\">setCookie</a></span>(java.lang.String&nbsp;url,\n         java.util.List&lt;java.lang.String&gt;&nbsp;cookies)</code>\n<div class=\"block\">Set cookies to webview after session connection response with cookies in it's headers.</div>\n</td>\n</tr>\n<tr id=\"i20\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#shouldLog-int-\">shouldLog</a></span>(int&nbsp;level)</code>\n<div class=\"block\">Logger function</div>\n</td>\n</tr>\n<tr id=\"i21\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html#showToast-java.lang.CharSequence-int-\">showToast</a></span>(java.lang.CharSequence&nbsp;text,\n         int&nbsp;duration)</code>\n<div class=\"block\">Show toast</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"context\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>context</h4>\n<pre>protected final&nbsp;android.content.Context context</pre>\n<div class=\"block\">A context for this runtime, it's expected to be ApplicationContext</div>\n</li>\n</ul>\n<a name=\"fileHandlerThread\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>fileHandlerThread</h4>\n<pre>protected static volatile&nbsp;android.os.HandlerThread fileHandlerThread</pre>\n<div class=\"block\">This handle thread use to save sonic cache.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicRuntime-android.content.Context-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicRuntime</h4>\n<pre>public&nbsp;SonicRuntime(android.content.Context&nbsp;context)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getContext--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getContext</h4>\n<pre>public&nbsp;android.content.Context&nbsp;getContext()</pre>\n</li>\n</ul>\n<a name=\"makeSessionId-java.lang.String-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>makeSessionId</h4>\n<pre>public&nbsp;java.lang.String&nbsp;makeSessionId(java.lang.String&nbsp;url,\n                                      boolean&nbsp;isAccountRelated)</pre>\n<div class=\"block\">Make a unique session id for the url, it can be account related.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - Url which need to make session id</dd>\n<dd><code>isAccountRelated</code> - Is account related or not</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>A unique session id</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getQueryParameterNames-android.net.Uri-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getQueryParameterNames</h4>\n<pre>public&nbsp;java.util.Set&lt;java.lang.String&gt;&nbsp;getQueryParameterNames(android.net.Uri&nbsp;uri)</pre>\n<div class=\"block\">Returns a set of the unique names of all query parameters. Iterating\n over the set will return the names in order of their first occurrence.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>uri</code> - The uri</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>A set of decoded names</dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.lang.UnsupportedOperationException</code> - if this isn't a hierarchical URI</dd>\n</dl>\n</li>\n</ul>\n<a name=\"shouldLog-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>shouldLog</h4>\n<pre>public&nbsp;boolean&nbsp;shouldLog(int&nbsp;level)</pre>\n<div class=\"block\">Logger function</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>level</code> - Level of this log，such like Log.DEBUG.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Should log or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"log-java.lang.String-int-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>log</h4>\n<pre>public abstract&nbsp;void&nbsp;log(java.lang.String&nbsp;tag,\n                         int&nbsp;level,\n                         java.lang.String&nbsp;message)</pre>\n</li>\n</ul>\n<a name=\"getCookie-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCookie</h4>\n<pre>public abstract&nbsp;java.lang.String&nbsp;getCookie(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">Get cookies of the input url, this method will be called before sonic session make a\n session connection to request data.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url which need to get cookies</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The cookies for current input url</dd>\n</dl>\n</li>\n</ul>\n<a name=\"setCookie-java.lang.String-java.util.List-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCookie</h4>\n<pre>public abstract&nbsp;boolean&nbsp;setCookie(java.lang.String&nbsp;url,\n                                  java.util.List&lt;java.lang.String&gt;&nbsp;cookies)</pre>\n<div class=\"block\">Set cookies to webview after session connection response with cookies in it's headers.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url which need to set cookies</dd>\n<dd><code>cookies</code> - The cookies for current input url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Set cookie success or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getUserAgent--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getUserAgent</h4>\n<pre>public abstract&nbsp;java.lang.String&nbsp;getUserAgent()</pre>\n<div class=\"block\">Get user agent of current runtime, this method will be called before sonic session make a\n session connection to request data.(sonic sdk info such like \"sonic-sdk-version/2.0.0\" will\n be added to this user agent.)</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The user agent</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSonicCacheDir--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSonicCacheDir</h4>\n<pre>public&nbsp;java.io.File&nbsp;getSonicCacheDir()</pre>\n<div class=\"block\">The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.\n it's expected to be a dir in /data dir for security.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The root cache dir.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSonicResourceCacheDir--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSonicResourceCacheDir</h4>\n<pre>public&nbsp;java.io.File&nbsp;getSonicResourceCacheDir()</pre>\n<div class=\"block\">The resource cache root dir which resource cache will be storage.\n it's expected to be a dir in /sdcard dir for security.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The root cache dir.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSonicSharedPreferences--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSonicSharedPreferences</h4>\n<pre>public&nbsp;android.content.SharedPreferences&nbsp;getSonicSharedPreferences()</pre>\n<div class=\"block\">get SharedPreferences of sonic.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>the sp</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getCurrentUserAccount--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCurrentUserAccount</h4>\n<pre>public abstract&nbsp;java.lang.String&nbsp;getCurrentUserAccount()</pre>\n<div class=\"block\">Get the current user account, this method will be called when makeSessionId's params is\n account related.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Current user account</dd>\n</dl>\n</li>\n</ul>\n<a name=\"isSonicUrl-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isSonicUrl</h4>\n<pre>public abstract&nbsp;boolean&nbsp;isSonicUrl(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">This method is used to judge the input url is support sonic or not, when this method return\n true, it means it's allow to create a sonic session for this url.\n e.g. In mobile QQ, it will judge url params contain sonic=1 or not, if contains it will return\n true, others return false.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url which need to judge</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return is sonic url or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"createWebResourceResponse-java.lang.String-java.lang.String-java.io.InputStream-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createWebResourceResponse</h4>\n<pre>public abstract&nbsp;java.lang.Object&nbsp;createWebResourceResponse(java.lang.String&nbsp;mimeType,\n                                                           java.lang.String&nbsp;encoding,\n                                                           java.io.InputStream&nbsp;data,\n                                                           java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</pre>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.\n\n e.g. If u use a system webview, just call new android.webkit.WebResourceResponse\n\n Constructs a resource response with the given MIME type, encoding, and\n input stream. Callers must implement\n <code>InputStream.read(byte[])</code> for the input\n stream.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>mimeType</code> - The resource response's MIME type, for example text/html</dd>\n<dd><code>encoding</code> - The resource response's encoding</dd>\n<dd><code>data</code> - The input stream that provides the resource response's data. Must not be a\n                 StringBufferInputStream.</dd>\n<dd><code>headers</code> - The headers</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The response to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"isNetworkValid--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isNetworkValid</h4>\n<pre>public abstract&nbsp;boolean&nbsp;isNetworkValid()</pre>\n<div class=\"block\">This method is used to judge is network valid or not</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Network valid or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getHostDirectAddress-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getHostDirectAddress</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getHostDirectAddress(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">Get the direct address of a url(host)，format as[ip:port]，the default http port is 80 and\n 443 for https.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The input url which need to get direct address</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return a valid direct address or null.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"showToast-java.lang.CharSequence-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>showToast</h4>\n<pre>public abstract&nbsp;void&nbsp;showToast(java.lang.CharSequence&nbsp;text,\n                               int&nbsp;duration)</pre>\n<div class=\"block\">Show toast</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>text</code> - Content</dd>\n<dd><code>duration</code> - See Toast.LENGTH_SHORT/Toast.LENGTH_LONG</dd>\n</dl>\n</li>\n</ul>\n<a name=\"postTaskToThread-java.lang.Runnable-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>postTaskToThread</h4>\n<pre>public abstract&nbsp;void&nbsp;postTaskToThread(java.lang.Runnable&nbsp;task,\n                                      long&nbsp;delayMillis)</pre>\n<div class=\"block\">Post a task to the thread(a io thread is better) which used to separate template and data.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>task</code> - A runnable task</dd>\n<dd><code>delayMillis</code> - The delay (in milliseconds) until the Runnable\n        will be executed.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"postTaskToSessionThread-java.lang.Runnable-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>postTaskToSessionThread</h4>\n<pre>public&nbsp;void&nbsp;postTaskToSessionThread(java.lang.Runnable&nbsp;task)</pre>\n<div class=\"block\">Post a task to session thread(a high priority thread is better)</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>task</code> - A runnable task</dd>\n</dl>\n</li>\n</ul>\n<a name=\"postTaskToMainThread-java.lang.Runnable-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>postTaskToMainThread</h4>\n<pre>public&nbsp;void&nbsp;postTaskToMainThread(java.lang.Runnable&nbsp;task,\n                                 long&nbsp;delayMillis)</pre>\n<div class=\"block\">Post a task in main thread</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>task</code> - A runnable task</dd>\n<dd><code>delayMillis</code> - Delay millis</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getFileThreadLooper--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getFileThreadLooper</h4>\n<pre>public&nbsp;android.os.Looper&nbsp;getFileThreadLooper()</pre>\n<div class=\"block\">Return the looper of HandleThread which use to save sonic cache.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The looper of HandleThread which use to save sonic cache.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"notifyError-com.tencent.sonic.sdk.SonicSessionClient-java.lang.String-int-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>notifyError</h4>\n<pre>public abstract&nbsp;void&nbsp;notifyError(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a>&nbsp;client,\n                                 java.lang.String&nbsp;url,\n                                 int&nbsp;errorCode)</pre>\n<div class=\"block\">Notify error for host application to do report or statics</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>client</code> - The error client</dd>\n<dd><code>url</code> - The error url</dd>\n<dd><code>errorCode</code> - Error code</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicRuntime.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicRuntime.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicServer.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicServer (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicServer (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicServer.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicServer.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicServer\" class=\"title\">类 SonicServer</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicServer</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicServer</span>\nextends java.lang.Object\nimplements <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></pre>\n<div class=\"block\">Instances of this class can be used to read server response from SonicSessionConnection.\n If this request support Local Sonic Server, it will separate html into template and data file.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#cachedResponseHeaders\">cachedResponseHeaders</a></span></code>\n<div class=\"block\">Cached response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code></div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#connectionImpl\">connectionImpl</a></span></code>\n<div class=\"block\">A session connection implement.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#dataString\">dataString</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected android.content.Intent</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#requestIntent\">requestIntent</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#responseCode\">responseCode</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#serverRsp\">serverRsp</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#session\">session</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#TAG\">TAG</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#templateString\">templateString</a></span></code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#SonicServer-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SonicServer</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n           android.content.Intent&nbsp;requestIntent)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#connect--\">connect</a></span>()</code>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#disconnect--\">disconnect</a></span>()</code>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getResponseCode--\">getResponseCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getResponseData-boolean-\">getResponseData</a></span>(boolean&nbsp;readUntilEnd)</code>\n<div class=\"block\">Return current cached server response data.</div>\n</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField</a></span>(java.lang.String&nbsp;key)</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getResponseHeaderFields--\">getResponseHeaderFields</a></span>()</code>\n<div class=\"block\">return response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code>\n  note: server response headers have high priority than custom headers!</div>\n</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.io.InputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getResponseStream-java.util.concurrent.atomic.AtomicBoolean-\">getResponseStream</a></span>(java.util.concurrent.atomic.AtomicBoolean&nbsp;breakConditions)</code>\n<div class=\"block\">Read all of data from <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> into byte array output stream <code>outputStream</code> until\n <code>breakCondition</code> is true when <code>breakCondition</code> is not null.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getTemplate--\">getTemplate</a></span>()</code>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#getUpdatedData--\">getUpdatedData</a></span>()</code>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.</div>\n</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose</a></span>(boolean&nbsp;readComplete,\n       java.io.ByteArrayOutputStream&nbsp;outputStream)</code>\n<div class=\"block\">Close callback</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html#separateTemplateAndData--\">separateTemplateAndData</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicServer.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"connectionImpl\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connectionImpl</h4>\n<pre>protected final&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a> connectionImpl</pre>\n<div class=\"block\">A session connection implement.</div>\n</li>\n</ul>\n<a name=\"serverRsp\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>serverRsp</h4>\n<pre>protected&nbsp;java.lang.String serverRsp</pre>\n</li>\n</ul>\n<a name=\"templateString\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>templateString</h4>\n<pre>protected&nbsp;java.lang.String templateString</pre>\n</li>\n</ul>\n<a name=\"dataString\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>dataString</h4>\n<pre>protected&nbsp;java.lang.String dataString</pre>\n</li>\n</ul>\n<a name=\"responseCode\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>responseCode</h4>\n<pre>protected&nbsp;int responseCode</pre>\n</li>\n</ul>\n<a name=\"session\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>session</h4>\n<pre>protected final&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a> session</pre>\n</li>\n</ul>\n<a name=\"requestIntent\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>requestIntent</h4>\n<pre>protected final&nbsp;android.content.Intent requestIntent</pre>\n</li>\n</ul>\n<a name=\"cachedResponseHeaders\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>cachedResponseHeaders</h4>\n<pre>protected&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt; cachedResponseHeaders</pre>\n<div class=\"block\">Cached response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code></div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicServer-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicServer</h4>\n<pre>public&nbsp;SonicServer(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                   android.content.Intent&nbsp;requestIntent)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"connect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connect</h4>\n<pre>protected&nbsp;int&nbsp;connect()</pre>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session.\n If this request support Local Sonic Server, it will separate html into template and data file.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the response code of connection</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseCode</h4>\n<pre>public&nbsp;int&nbsp;getResponseCode()</pre>\n</li>\n</ul>\n<a name=\"disconnect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>disconnect</h4>\n<pre>public&nbsp;void&nbsp;disconnect()</pre>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</li>\n</ul>\n<a name=\"getResponseHeaderFields--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseHeaderFields</h4>\n<pre>public&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getResponseHeaderFields()</pre>\n<div class=\"block\">return response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code>\n  note: server response headers have high priority than custom headers!</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>a Map of header fields</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseHeaderField-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseHeaderField</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getResponseHeaderField(java.lang.String&nbsp;key)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>key</code> - the name of a header field.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the value of the named header field from SonicSessionConnection.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseStream-java.util.concurrent.atomic.AtomicBoolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseStream</h4>\n<pre>public&nbsp;java.io.InputStream&nbsp;getResponseStream(java.util.concurrent.atomic.AtomicBoolean&nbsp;breakConditions)</pre>\n<div class=\"block\">Read all of data from <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> into byte array output stream <code>outputStream</code> until\n <code>breakCondition</code> is true when <code>breakCondition</code> is not null.\n Then return a <code>SonicSessionStream</code> obtains input bytes\n from  <code>outputStream</code> and a <code>netStream</code> when there is unread data from network.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>breakConditions</code> - This method won't read any data from <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> if <code>breakCondition</code> is true.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns a <code>SonicSessionStream</code> obtains input bytes\n from  <code>outputStream</code> and a <code>netStream</code> when there is unread data from network.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseData-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseData</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getResponseData(boolean&nbsp;readUntilEnd)</pre>\n<div class=\"block\">Return current cached server response data.\n  If @{code readUntilEnd} is true and current cached response data is empty, read all of data from <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> into byte array output stream <code>outputStream</code>.\n  And then this method convert outputStream into response string <code>serverRsp</code>. <br>\n <p><b>Note: This method blocks until the end of the input stream has been reached or <code>breakCondition</code> has been reset to true.</b></p></div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>readUntilEnd</code> - This method won't read any data from <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> if <code>readUntilEnd</code> is false.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns <code>serverRsp</code> current cached server response data.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getTemplate--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getTemplate</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getTemplate()</pre>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The template.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getUpdatedData--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getUpdatedData</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getUpdatedData()</pre>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>the JSONObject String which represent data.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"separateTemplateAndData--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>separateTemplateAndData</h4>\n<pre>protected&nbsp;void&nbsp;separateTemplateAndData()</pre>\n</li>\n</ul>\n<a name=\"onClose-boolean-java.io.ByteArrayOutputStream-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onClose</h4>\n<pre>public&nbsp;void&nbsp;onClose(boolean&nbsp;readComplete,\n                    java.io.ByteArrayOutputStream&nbsp;outputStream)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">SonicSessionStream.Callback</a></code></span></div>\n<div class=\"block\">Close callback</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>readComplete</code> - <code>SonicSessionStream</code> data has read completed</dd>\n<dd><code>outputStream</code> - outputStream include <code>memStream</code> data and <code>netStream</code> data</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicServer.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicServer.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSession.Callback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSession.Callback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSession.Callback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSession.Callback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSession.Callback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"接口 SonicSession.Callback\" class=\"title\">接口 SonicSession.Callback</h2>\n</div>\n<div class=\"contentContainer\">\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static interface <span class=\"typeNameLabel\">SonicSession.Callback</span></pre>\n<div class=\"block\">The interface is used to inform the listeners that the state of the\n session has changed.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html#onSessionStateChange-com.tencent.sonic.sdk.SonicSession-int-int-android.os.Bundle-\">onSessionStateChange</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                    int&nbsp;oldState,\n                    int&nbsp;newState,\n                    android.os.Bundle&nbsp;extraData)</code>\n<div class=\"block\">When the session's state changes, this method will be invoked.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"onSessionStateChange-com.tencent.sonic.sdk.SonicSession-int-int-android.os.Bundle-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onSessionStateChange</h4>\n<pre>void&nbsp;onSessionStateChange(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                          int&nbsp;oldState,\n                          int&nbsp;newState,\n                          android.os.Bundle&nbsp;extraData)</pre>\n<div class=\"block\">When the session's state changes, this method will be invoked.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>session</code> - Current session.</dd>\n<dd><code>oldState</code> - The old state.</dd>\n<dd><code>newState</code> - The next state.</dd>\n<dd><code>extraData</code> - Extra data.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSession.Callback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSession.Callback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSession.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSession (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSession (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10,\"i11\":10,\"i12\":10,\"i13\":10,\"i14\":10,\"i15\":10,\"i16\":10,\"i17\":10,\"i18\":10,\"i19\":6,\"i20\":6,\"i21\":6,\"i22\":6,\"i23\":10,\"i24\":6,\"i25\":6,\"i26\":10,\"i27\":10,\"i28\":10,\"i29\":10,\"i30\":10,\"i31\":10,\"i32\":10,\"i33\":10,\"i34\":10,\"i35\":10,\"i36\":10,\"i37\":10,\"i38\":10,\"i39\":10,\"i40\":10,\"i41\":10,\"i42\":10,\"i43\":10,\"i44\":10,\"i45\":10,\"i46\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSession\" class=\"title\">类 SonicSession</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSession</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>android.os.Handler.Callback</dd>\n</dl>\n<dl>\n<dt>直接已知子类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a>, <a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicSession</span>\nextends java.lang.Object\nimplements android.os.Handler.Callback</pre>\n<div class=\"block\">In Sonic, <code>SonicSession</code>s are used to manage the entire process,include\n obtain the latest data from the server, provide local and latest\n data to kernel, separate html to template and data, build template\n and data to html and so on. Each url involves one session at a time,\n that session will be destroyed when the page is destroyed.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static interface&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a></span></code>\n<div class=\"block\">The interface is used to inform the listeners that the state of the\n session has changed.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CHROME_FILE_THREAD\">CHROME_FILE_THREAD</a></span></code>\n<div class=\"block\">Name of chrome file thread</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_NOTIFY_RESULT\">CLIENT_MSG_NOTIFY_RESULT</a></span></code>\n<div class=\"block\">The message to record sonic mode.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_ON_WEB_READY\">CLIENT_MSG_ON_WEB_READY</a></span></code>\n<div class=\"block\">The message of page ready, its means page want to get the latest session data.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReady\">clientIsReady</a></span></code>\n<div class=\"block\">Whether the client is ready.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReload\">clientIsReload</a></span></code>\n<div class=\"block\">Indicate current session is reload or not.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_BEGIN\">COMMON_MSG_BEGIN</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_END\">COMMON_MSG_END</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#config\">config</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createdTime\">createdTime</a></span></code>\n<div class=\"block\">The time of current session created.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#DATA_UPDATE_BUNDLE_PARAMS_DIFF\">DATA_UPDATE_BUNDLE_PARAMS_DIFF</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#diffDataCallback\">diffDataCallback</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_MSG_BEGIN\">FILE_THREAD_MSG_BEGIN</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</a></span></code>\n<div class=\"block\">The message of saving sonic cache while server close.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</a></span></code>\n<div class=\"block\">The message of saving sonic cache while session finish.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected android.os.Handler</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#fileHandler\">fileHandler</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#finalResultCode\">finalResultCode</a></span></code>\n<div class=\"block\">Sonic final mode.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#id\">id</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected android.content.Intent</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#intent\">intent</a></span></code>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload\">isPreload</a></span></code>\n<div class=\"block\">Whether current session is preload.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForDestroy\">isWaitingForDestroy</a></span></code>\n<div class=\"block\">Whether the session is waiting for destroy.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSaveFile\">isWaitingForSaveFile</a></span></code>\n<div class=\"block\">Whether it is waiting for the file to be saved.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSessionThread\">isWaitingForSessionThread</a></span></code>\n<div class=\"block\">Whether the session is waiting for data.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected android.os.Handler</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#mainHandler\">mainHandler</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_FALSE\">OFFLINE_MODE_FALSE</a></span></code>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_HTTP\">OFFLINE_MODE_HTTP</a></span></code>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_STORE\">OFFLINE_MODE_STORE</a></span></code>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_TRUE\">OFFLINE_MODE_TRUE</a></span></code>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingDiffData\">pendingDiffData</a></span></code>\n<div class=\"block\">The difference data between local and server data.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.io.InputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingWebResourceStream\">pendingWebResourceStream</a></span></code>\n<div class=\"block\">The response for client interception.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.List&lt;java.lang.String&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#preloadLinks\">preloadLinks</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</a></span></code>\n<div class=\"block\">Resource Intercept State : intercepting in file thread</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</a></span></code>\n<div class=\"block\">Resource Intercept State : intercepting in other thread(may be IOThread or other else)</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_NONE\">RESOURCE_INTERCEPT_STATE_NONE</a></span></code>\n<div class=\"block\">Resource Intercept State : none</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceDownloaderEngine\">resourceDownloaderEngine</a></span></code>\n<div class=\"block\">Sonic sub resource downloader</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicInteger</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceInterceptState\">resourceInterceptState</a></span></code>\n<div class=\"block\">Resource intercept state, include <code>RESOURCE_INTERCEPT_STATE_NONE</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</code>\n More about it at {https://codereview.chromium.org/1350553005/#ps20001}</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#server\">server</a></span></code>\n<div class=\"block\">Sonic server</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SESSION_MSG_FORCE_DESTROY\">SESSION_MSG_FORCE_DESTROY</a></span></code>\n<div class=\"block\">The message of forced to destroy the session.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.CopyOnWriteArrayList&lt;java.lang.ref.WeakReference&lt;com.tencent.sonic.sdk.SonicSessionCallback&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionCallbackList\">sessionCallbackList</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionClient\">sessionClient</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicInteger</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionState\">sessionState</a></span></code>\n<div class=\"block\">Session state, include <code>STATE_NONE</code>, <code>STATE_RUNNING</code>,\n <code>STATE_READY</code> and <code>STATE_DESTROY</code>.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sId\">sId</a></span></code>\n<div class=\"block\">The integer id of current session</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected static long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sNextSessionLogId\">sNextSessionLogId</a></span></code>\n<div class=\"block\">Log id</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\">SONIC_RESULT_CODE_DATA_UPDATE</a></span></code>\n<div class=\"block\">Sonic mode : data update.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\">SONIC_RESULT_CODE_FIRST_LOAD</a></span></code>\n<div class=\"block\">Sonic mode : first load.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_HIT_CACHE\">SONIC_RESULT_CODE_HIT_CACHE</a></span></code>\n<div class=\"block\">Sonic mode : 304.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\">SONIC_RESULT_CODE_TEMPLATE_CHANGE</a></span></code>\n<div class=\"block\">Sonic mode : template change.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_UNKNOWN\">SONIC_RESULT_CODE_UNKNOWN</a></span></code>\n<div class=\"block\">Sonic mode : unknown.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcResultCode\">srcResultCode</a></span></code>\n<div class=\"block\">Sonic original mode.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcUrl\">srcUrl</a></span></code>\n<div class=\"block\">The original url</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_DESTROY\">STATE_DESTROY</a></span></code>\n<div class=\"block\">Session state : destroyed.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_NONE\">STATE_NONE</a></span></code>\n<div class=\"block\">Session state : original.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_READY\">STATE_READY</a></span></code>\n<div class=\"block\">Session state : ready.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_RUNNING\">STATE_RUNNING</a></span></code>\n<div class=\"block\">Session state : running.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.CopyOnWriteArrayList&lt;java.lang.ref.WeakReference&lt;<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#stateChangedCallbackList\">stateChangedCallbackList</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#statistics\">statistics</a></span></code>\n<div class=\"block\">Session statics var</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#TAG\">TAG</a></span></code>\n<div class=\"block\">Log filter</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasInterceptInvoked\">wasInterceptInvoked</a></span></code>\n<div class=\"block\">Whether the client initiates a resource interception.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasOnPageFinishInvoked\">wasOnPageFinishInvoked</a></span></code>\n<div class=\"block\">Whether the local html is loaded, it is used only the template changes.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_CODE\">WEB_RESPONSE_CODE</a></span></code>\n<div class=\"block\">The result keyword to page : the value is <code>finalResultCode</code></div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_DATA\">WEB_RESPONSE_DATA</a></span></code>\n<div class=\"block\">The all data keyword to page</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_EXTRA\">WEB_RESPONSE_EXTRA</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_LOCAL_REFRESH_TIME\">WEB_RESPONSE_LOCAL_REFRESH_TIME</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_SRC_CODE\">WEB_RESPONSE_SRC_CODE</a></span></code>\n<div class=\"block\">The result keyword to page : the value is <code>srcResultCode</code></div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">addSessionCallback</a></span>(com.tencent.sonic.sdk.SonicSessionCallback&nbsp;callback)</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">addSessionStateChangedCallback</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&nbsp;callback)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#bindClient-com.tencent.sonic.sdk.SonicSessionClient-\">bindClient</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a>&nbsp;client)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#canDestroy--\">canDestroy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clearSessionData--\">clearSessionData</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected android.content.Intent</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createConnectionIntent-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">createConnectionIntent</a></span>(com.tencent.sonic.sdk.SonicDataHelper.SessionData&nbsp;sessionData)</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy--\">destroy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy-boolean-\">destroy</a></span>(boolean&nbsp;force)</code>&nbsp;</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#doSaveSonicCache-com.tencent.sonic.sdk.SonicServer-java.lang.String-\">doSaveSonicCache</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a>&nbsp;sonicServer,\n                java.lang.String&nbsp;htmlString)</code>&nbsp;</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.util.HashMap&lt;java.lang.String,java.lang.String&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCacheHeaders--\">getCacheHeaders</a></span>()</code>\n<div class=\"block\">Get header info from local cache headers</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders--\">getCharsetFromHeaders</a></span>()</code>\n<div class=\"block\">Get the charset from the latest response http header.</div>\n</td>\n</tr>\n<tr id=\"i11\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders-java.util.Map-\">getCharsetFromHeaders</a></span>(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</code>&nbsp;</td>\n</tr>\n<tr id=\"i12\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCurrentUrl--\">getCurrentUrl</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i13\" class=\"rowColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getFinalResultCode--\">getFinalResultCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i14\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.util.HashMap&lt;java.lang.String,java.lang.String&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getHeaders--\">getHeaders</a></span>()</code>\n<div class=\"block\">Get header info with the original url of current session.</div>\n</td>\n</tr>\n<tr id=\"i15\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSessionClient--\">getSessionClient</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i16\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSrcResultCode--\">getSrcResultCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i17\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getStatistics--\">getStatistics</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i18\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_Connection-boolean-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">handleFlow_Connection</a></span>(boolean&nbsp;hasCache,\n                     com.tencent.sonic.sdk.SonicDataHelper.SessionData&nbsp;sessionData)</code>\n<div class=\"block\">Initiate a network request to obtain server data.</div>\n</td>\n</tr>\n<tr id=\"i19\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate</a></span>(java.lang.String&nbsp;serverRsp)</code>\n<div class=\"block\">Handle data update <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\"><code>SONIC_RESULT_CODE_DATA_UPDATE</code></a> logic.</div>\n</td>\n</tr>\n<tr id=\"i20\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad</a></span>()</code>\n<div class=\"block\">Handle sonic first <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\"><code>SONIC_RESULT_CODE_FIRST_LOAD</code></a> logic.</div>\n</td>\n</tr>\n<tr id=\"i21\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError</a></span>(int&nbsp;responseCode)</code>&nbsp;</td>\n</tr>\n<tr id=\"i22\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache</a></span>(java.lang.String&nbsp;cacheHtml)</code>&nbsp;</td>\n</tr>\n<tr id=\"i23\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_NotModified--\">handleFlow_NotModified</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i24\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i25\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange</a></span>(java.lang.String&nbsp;newHtml)</code>\n<div class=\"block\">Handle template update <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\"><code>SONIC_RESULT_CODE_TEMPLATE_CHANGE</code></a> logic.</div>\n</td>\n</tr>\n<tr id=\"i26\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">handleMessage</a></span>(android.os.Message&nbsp;msg)</code>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n</td>\n</tr>\n<tr id=\"i27\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isDestroyedOrWaitingForDestroy--\">isDestroyedOrWaitingForDestroy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i28\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isMatchCurrentUrl-java.lang.String-\">isMatchCurrentUrl</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">Whether the incoming url matches the current url,it will\n ignore url parameters</div>\n</td>\n</tr>\n<tr id=\"i29\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload--\">isPreload</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i30\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#notifyStateChange-int-int-android.os.Bundle-\">notifyStateChange</a></span>(int&nbsp;oldState,\n                 int&nbsp;newState,\n                 android.os.Bundle&nbsp;extraData)</code>\n<div class=\"block\">When the session state changes, notify the listeners.</div>\n</td>\n</tr>\n<tr id=\"i31\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientPageFinished-java.lang.String-\">onClientPageFinished</a></span>(java.lang.String&nbsp;url)</code>&nbsp;</td>\n</tr>\n<tr id=\"i32\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">onClientReady</a></span>()</code>\n<div class=\"block\">Client informs sonic that it is ready.</div>\n</td>\n</tr>\n<tr id=\"i33\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientRequestResource-java.lang.String-\">onClientRequestResource</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">When the webview initiates a resource interception, the client invokes the method to retrieve the data</div>\n</td>\n</tr>\n<tr id=\"i34\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">onRequestResource</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n</td>\n</tr>\n<tr id=\"i35\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onServerClosed-com.tencent.sonic.sdk.SonicServer-boolean-\">onServerClosed</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a>&nbsp;sonicServer,\n              boolean&nbsp;readComplete)</code>\n<div class=\"block\">If the kernel obtain inputStream from a <code>SonicSessionStream</code>, the inputStream\n will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream\n close.</div>\n</td>\n</tr>\n<tr id=\"i36\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;diffDataCallback)</code>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n</td>\n</tr>\n<tr id=\"i37\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postForceDestroyIfNeed--\">postForceDestroyIfNeed</a></span>()</code>\n<div class=\"block\">Destroy the session if it is waiting for destroy and it is can be destroyed.</div>\n</td>\n</tr>\n<tr id=\"i38\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postTaskToSaveSonicCache-java.lang.String-\">postTaskToSaveSonicCache</a></span>(java.lang.String&nbsp;htmlString)</code>&nbsp;</td>\n</tr>\n<tr id=\"i39\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#refresh--\">refresh</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i40\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">removeSessionCallback</a></span>(com.tencent.sonic.sdk.SonicSessionCallback&nbsp;callback)</code>&nbsp;</td>\n</tr>\n<tr id=\"i41\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">removeSessionStateChangedCallback</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&nbsp;callback)</code>&nbsp;</td>\n</tr>\n<tr id=\"i42\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setCookiesFromHeaders-java.util.Map-boolean-\">setCookiesFromHeaders</a></span>(java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;headers,\n                     boolean&nbsp;executeInNewThread)</code>\n<div class=\"block\">Set cookies to webview from headers</div>\n</td>\n</tr>\n<tr id=\"i43\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setResult-int-int-boolean-\">setResult</a></span>(int&nbsp;srcCode,\n         int&nbsp;finalCode,\n         boolean&nbsp;notify)</code>\n<div class=\"block\">Record the sonic mode, notify the result to page if necessary.</div>\n</td>\n</tr>\n<tr id=\"i44\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#shouldSetCookieAsynchronous--\">shouldSetCookieAsynchronous</a></span>()</code>\n<div class=\"block\">Whether should set cookie asynchronous or not , if <code>onClientRequestResource</code> is calling\n in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may\n cause deadlock\n More about it see {https://issuetracker.google.com/issues/36989494#c8}\n Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}</div>\n</td>\n</tr>\n<tr id=\"i45\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#start--\">start</a></span>()</code>\n<div class=\"block\">Start the sonic process</div>\n</td>\n</tr>\n<tr id=\"i46\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#switchState-int-int-boolean-\">switchState</a></span>(int&nbsp;fromState,\n           int&nbsp;toState,\n           boolean&nbsp;notify)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<div class=\"block\">Log filter</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"WEB_RESPONSE_SRC_CODE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>WEB_RESPONSE_SRC_CODE</h4>\n<pre>public static final&nbsp;java.lang.String WEB_RESPONSE_SRC_CODE</pre>\n<div class=\"block\">The result keyword to page : the value is <code>srcResultCode</code></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_SRC_CODE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"WEB_RESPONSE_CODE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>WEB_RESPONSE_CODE</h4>\n<pre>public static final&nbsp;java.lang.String WEB_RESPONSE_CODE</pre>\n<div class=\"block\">The result keyword to page : the value is <code>finalResultCode</code></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_CODE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"WEB_RESPONSE_EXTRA\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>WEB_RESPONSE_EXTRA</h4>\n<pre>public static final&nbsp;java.lang.String WEB_RESPONSE_EXTRA</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_EXTRA\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"WEB_RESPONSE_DATA\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>WEB_RESPONSE_DATA</h4>\n<pre>public static final&nbsp;java.lang.String WEB_RESPONSE_DATA</pre>\n<div class=\"block\">The all data keyword to page</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_DATA\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"DATA_UPDATE_BUNDLE_PARAMS_DIFF\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>DATA_UPDATE_BUNDLE_PARAMS_DIFF</h4>\n<pre>public static final&nbsp;java.lang.String DATA_UPDATE_BUNDLE_PARAMS_DIFF</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.DATA_UPDATE_BUNDLE_PARAMS_DIFF\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"WEB_RESPONSE_LOCAL_REFRESH_TIME\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>WEB_RESPONSE_LOCAL_REFRESH_TIME</h4>\n<pre>public static final&nbsp;java.lang.String WEB_RESPONSE_LOCAL_REFRESH_TIME</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_LOCAL_REFRESH_TIME\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CHROME_FILE_THREAD\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CHROME_FILE_THREAD</h4>\n<pre>public static final&nbsp;java.lang.String CHROME_FILE_THREAD</pre>\n<div class=\"block\">Name of chrome file thread</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.CHROME_FILE_THREAD\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_NONE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_NONE</h4>\n<pre>public static final&nbsp;int STATE_NONE</pre>\n<div class=\"block\">Session state : original.\n <p>\n This state means session has not start.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.STATE_NONE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_RUNNING\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_RUNNING</h4>\n<pre>public static final&nbsp;int STATE_RUNNING</pre>\n<div class=\"block\">Session state : running.\n <p>\n This state means session has begun to request data from\n the server and is processing the data.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.STATE_RUNNING\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_READY\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_READY</h4>\n<pre>public static final&nbsp;int STATE_READY</pre>\n<div class=\"block\">Session state : ready.\n <p>\n This state means session data is available when the page\n initiates a resource interception. In other stats the\n client(kernel) will wait.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.STATE_READY\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_DESTROY\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_DESTROY</h4>\n<pre>public static final&nbsp;int STATE_DESTROY</pre>\n<div class=\"block\">Session state : destroyed.\n <p>\n This state means the session is destroyed.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.STATE_DESTROY\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"OFFLINE_MODE_HTTP\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>OFFLINE_MODE_HTTP</h4>\n<pre>public static final&nbsp;java.lang.String OFFLINE_MODE_HTTP</pre>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.\n <p>\n This value means sonic server unavailable, the terminal\n does not take sonic logic for the next period of time,the\n value of time is defined in <a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html#SONIC_UNAVAILABLE_TIME\"><code>SonicConfig.SONIC_UNAVAILABLE_TIME</code></a></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_HTTP\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"OFFLINE_MODE_STORE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>OFFLINE_MODE_STORE</h4>\n<pre>public static final&nbsp;java.lang.String OFFLINE_MODE_STORE</pre>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.\n <p>\n This value means sonic will save the latest data, but not refresh\n page.For example, when sonic mode is data update, sonic will not\n provide the difference data between local and server to page to refresh\n the content.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_STORE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"OFFLINE_MODE_TRUE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>OFFLINE_MODE_TRUE</h4>\n<pre>public static final&nbsp;java.lang.String OFFLINE_MODE_TRUE</pre>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.\n <p>\n This value means sonic will save the latest data and refresh page content.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_TRUE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"OFFLINE_MODE_FALSE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>OFFLINE_MODE_FALSE</h4>\n<pre>public static final&nbsp;java.lang.String OFFLINE_MODE_FALSE</pre>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.\n <p>\n This value means sonic will refresh page content but not save date, sonic\n will remove the local data also.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_FALSE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_RESULT_CODE_UNKNOWN\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_RESULT_CODE_UNKNOWN</h4>\n<pre>public static final&nbsp;int SONIC_RESULT_CODE_UNKNOWN</pre>\n<div class=\"block\">Sonic mode : unknown.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_UNKNOWN\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_RESULT_CODE_FIRST_LOAD\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_RESULT_CODE_FIRST_LOAD</h4>\n<pre>public static final&nbsp;int SONIC_RESULT_CODE_FIRST_LOAD</pre>\n<div class=\"block\">Sonic mode : first load.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_FIRST_LOAD\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_RESULT_CODE_TEMPLATE_CHANGE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_RESULT_CODE_TEMPLATE_CHANGE</h4>\n<pre>public static final&nbsp;int SONIC_RESULT_CODE_TEMPLATE_CHANGE</pre>\n<div class=\"block\">Sonic mode : template change.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_TEMPLATE_CHANGE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_RESULT_CODE_DATA_UPDATE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_RESULT_CODE_DATA_UPDATE</h4>\n<pre>public static final&nbsp;int SONIC_RESULT_CODE_DATA_UPDATE</pre>\n<div class=\"block\">Sonic mode : data update.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_DATA_UPDATE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SONIC_RESULT_CODE_HIT_CACHE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SONIC_RESULT_CODE_HIT_CACHE</h4>\n<pre>public static final&nbsp;int SONIC_RESULT_CODE_HIT_CACHE</pre>\n<div class=\"block\">Sonic mode : 304.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_HIT_CACHE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"srcResultCode\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>srcResultCode</h4>\n<pre>protected&nbsp;int srcResultCode</pre>\n<div class=\"block\">Sonic original mode.\n <p>\n  For example, when local data does not exist, the value is\n  <code>SONIC_RESULT_CODE_FIRST_LOAD</code></div>\n</li>\n</ul>\n<a name=\"finalResultCode\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>finalResultCode</h4>\n<pre>protected&nbsp;int finalResultCode</pre>\n<div class=\"block\">Sonic final mode.\n <p>\n  For example, when local data does not exist, the <code>srcResultCode</code>\n  value is <code>SONIC_RESULT_CODE_FIRST_LOAD</code>. If the server data is read\n  finished, sonic will provide the latest data to kernel when the kernel\n  initiates a resource interception.This effect is the same as loading local data,\n  so the sonic mode will be set as <code>SONIC_RESULT_CODE_HIT_CACHE</code></div>\n</li>\n</ul>\n<a name=\"COMMON_MSG_BEGIN\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>COMMON_MSG_BEGIN</h4>\n<pre>protected static final&nbsp;int COMMON_MSG_BEGIN</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.COMMON_MSG_BEGIN\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CLIENT_MSG_NOTIFY_RESULT\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CLIENT_MSG_NOTIFY_RESULT</h4>\n<pre>protected static final&nbsp;int CLIENT_MSG_NOTIFY_RESULT</pre>\n<div class=\"block\">The message to record sonic mode.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.CLIENT_MSG_NOTIFY_RESULT\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CLIENT_MSG_ON_WEB_READY\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CLIENT_MSG_ON_WEB_READY</h4>\n<pre>protected static final&nbsp;int CLIENT_MSG_ON_WEB_READY</pre>\n<div class=\"block\">The message of page ready, its means page want to get the latest session data.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.CLIENT_MSG_ON_WEB_READY\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"SESSION_MSG_FORCE_DESTROY\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>SESSION_MSG_FORCE_DESTROY</h4>\n<pre>protected static final&nbsp;int SESSION_MSG_FORCE_DESTROY</pre>\n<div class=\"block\">The message of forced to destroy the session.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.SESSION_MSG_FORCE_DESTROY\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"COMMON_MSG_END\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>COMMON_MSG_END</h4>\n<pre>protected static final&nbsp;int COMMON_MSG_END</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.COMMON_MSG_END\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"FILE_THREAD_MSG_BEGIN\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>FILE_THREAD_MSG_BEGIN</h4>\n<pre>protected static final&nbsp;int FILE_THREAD_MSG_BEGIN</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.FILE_THREAD_MSG_BEGIN\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</h4>\n<pre>protected static final&nbsp;int FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</pre>\n<div class=\"block\">The message of saving sonic cache while server close.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</h4>\n<pre>protected static final&nbsp;int FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</pre>\n<div class=\"block\">The message of saving sonic cache while session finish.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"RESOURCE_INTERCEPT_STATE_NONE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>RESOURCE_INTERCEPT_STATE_NONE</h4>\n<pre>protected static final&nbsp;int RESOURCE_INTERCEPT_STATE_NONE</pre>\n<div class=\"block\">Resource Intercept State : none</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_NONE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</h4>\n<pre>protected static final&nbsp;int RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</pre>\n<div class=\"block\">Resource Intercept State : intercepting in file thread</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</h4>\n<pre>protected static final&nbsp;int RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</pre>\n<div class=\"block\">Resource Intercept State : intercepting in other thread(may be IOThread or other else)</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"sessionState\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sessionState</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicInteger sessionState</pre>\n<div class=\"block\">Session state, include <code>STATE_NONE</code>, <code>STATE_RUNNING</code>,\n <code>STATE_READY</code> and <code>STATE_DESTROY</code>.</div>\n</li>\n</ul>\n<a name=\"wasInterceptInvoked\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>wasInterceptInvoked</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean wasInterceptInvoked</pre>\n<div class=\"block\">Whether the client initiates a resource interception.</div>\n</li>\n</ul>\n<a name=\"clientIsReady\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>clientIsReady</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean clientIsReady</pre>\n<div class=\"block\">Whether the client is ready.</div>\n</li>\n</ul>\n<a name=\"isWaitingForSaveFile\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isWaitingForSaveFile</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean isWaitingForSaveFile</pre>\n<div class=\"block\">Whether it is waiting for the file to be saved. If it is true, the session can not\n be destroyed.</div>\n</li>\n</ul>\n<a name=\"isWaitingForDestroy\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isWaitingForDestroy</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean isWaitingForDestroy</pre>\n<div class=\"block\">Whether the session is waiting for destroy.</div>\n</li>\n</ul>\n<a name=\"isWaitingForSessionThread\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isWaitingForSessionThread</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean isWaitingForSessionThread</pre>\n<div class=\"block\">Whether the session is waiting for data. If it is true, the session can not\n be destroyed.</div>\n</li>\n</ul>\n<a name=\"wasOnPageFinishInvoked\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>wasOnPageFinishInvoked</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean wasOnPageFinishInvoked</pre>\n<div class=\"block\">Whether the local html is loaded, it is used only the template changes.</div>\n</li>\n</ul>\n<a name=\"resourceInterceptState\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>resourceInterceptState</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicInteger resourceInterceptState</pre>\n<div class=\"block\">Resource intercept state, include <code>RESOURCE_INTERCEPT_STATE_NONE</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</code>\n More about it at {https://codereview.chromium.org/1350553005/#ps20001}</div>\n</li>\n</ul>\n<a name=\"clientIsReload\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>clientIsReload</h4>\n<pre>protected final&nbsp;java.util.concurrent.atomic.AtomicBoolean clientIsReload</pre>\n<div class=\"block\">Indicate current session is reload or not.</div>\n</li>\n</ul>\n<a name=\"statistics\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>statistics</h4>\n<pre>protected&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a> statistics</pre>\n<div class=\"block\">Session statics var</div>\n</li>\n</ul>\n<a name=\"server\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>server</h4>\n<pre>protected volatile&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a> server</pre>\n<div class=\"block\">Sonic server</div>\n</li>\n</ul>\n<a name=\"resourceDownloaderEngine\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>resourceDownloaderEngine</h4>\n<pre>protected volatile&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a> resourceDownloaderEngine</pre>\n<div class=\"block\">Sonic sub resource downloader</div>\n</li>\n</ul>\n<a name=\"pendingWebResourceStream\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>pendingWebResourceStream</h4>\n<pre>protected volatile&nbsp;java.io.InputStream pendingWebResourceStream</pre>\n<div class=\"block\">The response for client interception.</div>\n</li>\n</ul>\n<a name=\"pendingDiffData\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>pendingDiffData</h4>\n<pre>protected&nbsp;java.lang.String pendingDiffData</pre>\n<div class=\"block\">The difference data between local and server data.</div>\n</li>\n</ul>\n<a name=\"sNextSessionLogId\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sNextSessionLogId</h4>\n<pre>protected static&nbsp;long sNextSessionLogId</pre>\n<div class=\"block\">Log id</div>\n</li>\n</ul>\n<a name=\"config\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>config</h4>\n<pre>public final&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a> config</pre>\n</li>\n</ul>\n<a name=\"id\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>id</h4>\n<pre>public final&nbsp;java.lang.String id</pre>\n</li>\n</ul>\n<a name=\"isPreload\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isPreload</h4>\n<pre>protected&nbsp;boolean isPreload</pre>\n<div class=\"block\">Whether current session is preload.</div>\n</li>\n</ul>\n<a name=\"createdTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createdTime</h4>\n<pre>public&nbsp;long createdTime</pre>\n<div class=\"block\">The time of current session created.</div>\n</li>\n</ul>\n<a name=\"sId\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sId</h4>\n<pre>public final&nbsp;long sId</pre>\n<div class=\"block\">The integer id of current session</div>\n</li>\n</ul>\n<a name=\"srcUrl\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>srcUrl</h4>\n<pre>public&nbsp;java.lang.String srcUrl</pre>\n<div class=\"block\">The original url</div>\n</li>\n</ul>\n<a name=\"sessionClient\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sessionClient</h4>\n<pre>protected volatile&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a> sessionClient</pre>\n</li>\n</ul>\n<a name=\"mainHandler\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mainHandler</h4>\n<pre>protected final&nbsp;android.os.Handler mainHandler</pre>\n</li>\n</ul>\n<a name=\"stateChangedCallbackList\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>stateChangedCallbackList</h4>\n<pre>protected final&nbsp;java.util.concurrent.CopyOnWriteArrayList&lt;java.lang.ref.WeakReference&lt;<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&gt;&gt; stateChangedCallbackList</pre>\n</li>\n</ul>\n<a name=\"diffDataCallback\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>diffDataCallback</h4>\n<pre>protected&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a> diffDataCallback</pre>\n</li>\n</ul>\n<a name=\"fileHandler\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>fileHandler</h4>\n<pre>protected final&nbsp;android.os.Handler fileHandler</pre>\n</li>\n</ul>\n<a name=\"preloadLinks\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>preloadLinks</h4>\n<pre>protected&nbsp;java.util.List&lt;java.lang.String&gt; preloadLinks</pre>\n</li>\n</ul>\n<a name=\"sessionCallbackList\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sessionCallbackList</h4>\n<pre>protected final&nbsp;java.util.concurrent.CopyOnWriteArrayList&lt;java.lang.ref.WeakReference&lt;com.tencent.sonic.sdk.SonicSessionCallback&gt;&gt; sessionCallbackList</pre>\n</li>\n</ul>\n<a name=\"intent\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>intent</h4>\n<pre>protected final&nbsp;android.content.Intent intent</pre>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"handleMessage-android.os.Message-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleMessage</h4>\n<pre>public&nbsp;boolean&nbsp;handleMessage(android.os.Message&nbsp;msg)</pre>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>handleMessage</code>&nbsp;在接口中&nbsp;<code>android.os.Handler.Callback</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"start--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>start</h4>\n<pre>public&nbsp;void&nbsp;start()</pre>\n<div class=\"block\">Start the sonic process</div>\n</li>\n</ul>\n<a name=\"refresh--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>refresh</h4>\n<pre>public&nbsp;boolean&nbsp;refresh()</pre>\n</li>\n</ul>\n<a name=\"createConnectionIntent-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createConnectionIntent</h4>\n<pre>protected&nbsp;android.content.Intent&nbsp;createConnectionIntent(com.tencent.sonic.sdk.SonicDataHelper.SessionData&nbsp;sessionData)</pre>\n</li>\n</ul>\n<a name=\"handleFlow_Connection-boolean-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_Connection</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_Connection(boolean&nbsp;hasCache,\n                                     com.tencent.sonic.sdk.SonicDataHelper.SessionData&nbsp;sessionData)</pre>\n<div class=\"block\">Initiate a network request to obtain server data.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>hasCache</code> - Indicates local sonic cache is exist or not.</dd>\n<dd><code>sessionData</code> - SessionData holds eTag templateTag</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_LoadLocalCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_LoadLocalCache</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_LoadLocalCache(java.lang.String&nbsp;cacheHtml)</pre>\n</li>\n</ul>\n<a name=\"handleFlow_FirstLoad--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_FirstLoad</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_FirstLoad()</pre>\n<div class=\"block\">Handle sonic first <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\"><code>SONIC_RESULT_CODE_FIRST_LOAD</code></a> logic.</div>\n</li>\n</ul>\n<a name=\"handleFlow_DataUpdate-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_DataUpdate</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_DataUpdate(java.lang.String&nbsp;serverRsp)</pre>\n<div class=\"block\">Handle data update <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\"><code>SONIC_RESULT_CODE_DATA_UPDATE</code></a> logic.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>serverRsp</code> - Server response data.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_TemplateChange-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_TemplateChange</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_TemplateChange(java.lang.String&nbsp;newHtml)</pre>\n<div class=\"block\">Handle template update <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\"><code>SONIC_RESULT_CODE_TEMPLATE_CHANGE</code></a> logic.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>newHtml</code> - new Html string from web-server</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_HttpError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_HttpError</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_HttpError(int&nbsp;responseCode)</pre>\n</li>\n</ul>\n<a name=\"handleFlow_ServiceUnavailable--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_ServiceUnavailable</h4>\n<pre>protected abstract&nbsp;void&nbsp;handleFlow_ServiceUnavailable()</pre>\n</li>\n</ul>\n<a name=\"handleFlow_NotModified--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_NotModified</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_NotModified()</pre>\n</li>\n</ul>\n<a name=\"isPreload--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isPreload</h4>\n<pre>public&nbsp;boolean&nbsp;isPreload()</pre>\n</li>\n</ul>\n<a name=\"getStatistics--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getStatistics</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a>&nbsp;getStatistics()</pre>\n</li>\n</ul>\n<a name=\"addSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>addSessionStateChangedCallback</h4>\n<pre>protected&nbsp;boolean&nbsp;addSessionStateChangedCallback(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&nbsp;callback)</pre>\n</li>\n</ul>\n<a name=\"removeSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>removeSessionStateChangedCallback</h4>\n<pre>protected&nbsp;boolean&nbsp;removeSessionStateChangedCallback(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a>&nbsp;callback)</pre>\n</li>\n</ul>\n<a name=\"addSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>addSessionCallback</h4>\n<pre>public&nbsp;boolean&nbsp;addSessionCallback(com.tencent.sonic.sdk.SonicSessionCallback&nbsp;callback)</pre>\n</li>\n</ul>\n<a name=\"removeSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>removeSessionCallback</h4>\n<pre>public&nbsp;boolean&nbsp;removeSessionCallback(com.tencent.sonic.sdk.SonicSessionCallback&nbsp;callback)</pre>\n</li>\n</ul>\n<a name=\"getCurrentUrl--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCurrentUrl</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getCurrentUrl()</pre>\n</li>\n</ul>\n<a name=\"getFinalResultCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getFinalResultCode</h4>\n<pre>public&nbsp;int&nbsp;getFinalResultCode()</pre>\n</li>\n</ul>\n<a name=\"getSrcResultCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSrcResultCode</h4>\n<pre>public&nbsp;int&nbsp;getSrcResultCode()</pre>\n</li>\n</ul>\n<a name=\"isDestroyedOrWaitingForDestroy--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isDestroyedOrWaitingForDestroy</h4>\n<pre>public&nbsp;boolean&nbsp;isDestroyedOrWaitingForDestroy()</pre>\n</li>\n</ul>\n<a name=\"postForceDestroyIfNeed--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>postForceDestroyIfNeed</h4>\n<pre>protected&nbsp;boolean&nbsp;postForceDestroyIfNeed()</pre>\n<div class=\"block\">Destroy the session if it is waiting for destroy and it is can be destroyed.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return true if the session is waiting for destroy and it is can be destroyed.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"canDestroy--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>canDestroy</h4>\n<pre>protected&nbsp;boolean&nbsp;canDestroy()</pre>\n</li>\n</ul>\n<a name=\"switchState-int-int-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>switchState</h4>\n<pre>protected&nbsp;boolean&nbsp;switchState(int&nbsp;fromState,\n                              int&nbsp;toState,\n                              boolean&nbsp;notify)</pre>\n</li>\n</ul>\n<a name=\"onServerClosed-com.tencent.sonic.sdk.SonicServer-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onServerClosed</h4>\n<pre>public&nbsp;void&nbsp;onServerClosed(<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a>&nbsp;sonicServer,\n                           boolean&nbsp;readComplete)</pre>\n<div class=\"block\">If the kernel obtain inputStream from a <code>SonicSessionStream</code>, the inputStream\n will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream\n close.\n\n <p>\n  If the html is read complete, sonic will separate the html to template and data, and save these\n  data.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>sonicServer</code> - The actual server connection of current SonicSession.</dd>\n<dd><code>readComplete</code> - Whether the html is read complete.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"postTaskToSaveSonicCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>postTaskToSaveSonicCache</h4>\n<pre>protected&nbsp;void&nbsp;postTaskToSaveSonicCache(java.lang.String&nbsp;htmlString)</pre>\n</li>\n</ul>\n<a name=\"doSaveSonicCache-com.tencent.sonic.sdk.SonicServer-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>doSaveSonicCache</h4>\n<pre>protected&nbsp;void&nbsp;doSaveSonicCache(<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a>&nbsp;sonicServer,\n                                java.lang.String&nbsp;htmlString)</pre>\n</li>\n</ul>\n<a name=\"notifyStateChange-int-int-android.os.Bundle-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>notifyStateChange</h4>\n<pre>protected&nbsp;void&nbsp;notifyStateChange(int&nbsp;oldState,\n                                 int&nbsp;newState,\n                                 android.os.Bundle&nbsp;extraData)</pre>\n<div class=\"block\">When the session state changes, notify the listeners.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>oldState</code> - The old state.</dd>\n<dd><code>newState</code> - The nex state.</dd>\n<dd><code>extraData</code> - The extra data.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"setResult-int-int-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setResult</h4>\n<pre>protected&nbsp;void&nbsp;setResult(int&nbsp;srcCode,\n                         int&nbsp;finalCode,\n                         boolean&nbsp;notify)</pre>\n<div class=\"block\">Record the sonic mode, notify the result to page if necessary.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>srcCode</code> - The original mode.</dd>\n<dd><code>finalCode</code> - The final mode.</dd>\n<dd><code>notify</code> - Whether notify te result to page.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"bindClient-com.tencent.sonic.sdk.SonicSessionClient-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>bindClient</h4>\n<pre>public&nbsp;boolean&nbsp;bindClient(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a>&nbsp;client)</pre>\n</li>\n</ul>\n<a name=\"onClientReady--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onClientReady</h4>\n<pre>public&nbsp;boolean&nbsp;onClientReady()</pre>\n<div class=\"block\">Client informs sonic that it is ready.\n Client ready means it's webview has been initialized, can start load url or load data.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>True if it is set for the first time</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onClientRequestResource-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onClientRequestResource</h4>\n<pre>public final&nbsp;java.lang.Object&nbsp;onClientRequestResource(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">When the webview initiates a resource interception, the client invokes the method to retrieve the data</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url of this session</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"shouldSetCookieAsynchronous--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>shouldSetCookieAsynchronous</h4>\n<pre>protected&nbsp;boolean&nbsp;shouldSetCookieAsynchronous()</pre>\n<div class=\"block\">Whether should set cookie asynchronous or not , if <code>onClientRequestResource</code> is calling\n in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may\n cause deadlock\n More about it see {https://issuetracker.google.com/issues/36989494#c8}\n Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"setCookiesFromHeaders-java.util.Map-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCookiesFromHeaders</h4>\n<pre>protected&nbsp;boolean&nbsp;setCookiesFromHeaders(java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;headers,\n                                        boolean&nbsp;executeInNewThread)</pre>\n<div class=\"block\">Set cookies to webview from headers</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>headers</code> - headers from server response</dd>\n<dd><code>executeInNewThread</code> - whether execute in new thread or not</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Set cookie success or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onRequestResource-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onRequestResource</h4>\n<pre>protected&nbsp;java.lang.Object&nbsp;onRequestResource(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url of this session</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onWebReady</h4>\n<pre>public&nbsp;boolean&nbsp;onWebReady(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;diffDataCallback)</pre>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>diffDataCallback</code> - Sonic provides the latest data to the page through this callback</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The result</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onClientPageFinished-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onClientPageFinished</h4>\n<pre>public&nbsp;boolean&nbsp;onClientPageFinished(java.lang.String&nbsp;url)</pre>\n</li>\n</ul>\n<a name=\"isMatchCurrentUrl-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isMatchCurrentUrl</h4>\n<pre>public&nbsp;boolean&nbsp;isMatchCurrentUrl(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">Whether the incoming url matches the current url,it will\n ignore url parameters</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The incoming url.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Whether the incoming url matches the current url.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getHeaders--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getHeaders</h4>\n<pre>protected&nbsp;java.util.HashMap&lt;java.lang.String,java.lang.String&gt;&nbsp;getHeaders()</pre>\n<div class=\"block\">Get header info with the original url of current session.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The header info.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getCharsetFromHeaders--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCharsetFromHeaders</h4>\n<pre>protected&nbsp;java.lang.String&nbsp;getCharsetFromHeaders()</pre>\n<div class=\"block\">Get the charset from the latest response http header.</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The charset.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getCharsetFromHeaders-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCharsetFromHeaders</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getCharsetFromHeaders(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</pre>\n</li>\n</ul>\n<a name=\"getCacheHeaders--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCacheHeaders</h4>\n<pre>protected&nbsp;java.util.HashMap&lt;java.lang.String,java.lang.String&gt;&nbsp;getCacheHeaders()</pre>\n<div class=\"block\">Get header info from local cache headers</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The header info.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSessionClient--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSessionClient</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a>&nbsp;getSessionClient()</pre>\n</li>\n</ul>\n<a name=\"destroy--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>destroy</h4>\n<pre>public&nbsp;void&nbsp;destroy()</pre>\n</li>\n</ul>\n<a name=\"destroy-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>destroy</h4>\n<pre>protected&nbsp;void&nbsp;destroy(boolean&nbsp;force)</pre>\n</li>\n</ul>\n<a name=\"clearSessionData--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>clearSessionData</h4>\n<pre>protected&nbsp;void&nbsp;clearSessionData()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionClient.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionClient (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionClient (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":6,\"i5\":6,\"i6\":6,\"i7\":10,\"i8\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionClient.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionClient.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionClient\" class=\"title\">类 SonicSessionClient</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionClient</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicSessionClient</span>\nextends java.lang.Object</pre>\n<div class=\"block\"><code>SonicSessionClient</code> is a thin API class that delegates its public API to\n a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#SonicSessionClient--\">SonicSessionClient</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#bindSession-com.tencent.sonic.sdk.SonicSession-\">bindSession</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</code>\n<div class=\"block\">Bind a sonic session to current client</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#clearHistory--\">clearHistory</a></span>()</code>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#clientReady--\">clientReady</a></span>()</code>\n<div class=\"block\">Notify client is ready to accept data</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#getDiffData-com.tencent.sonic.sdk.SonicDiffDataCallback-\">getDiffData</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</code>\n<div class=\"block\">The page execute a java script function to invoke a native method by javascript interface,\n this callback will be called when sonic has finished diff data.</div>\n</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrl-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-\">loadDataWithBaseUrl</a></span>(java.lang.String&nbsp;baseUrl,\n                   java.lang.String&nbsp;data,\n                   java.lang.String&nbsp;mimeType,\n                   java.lang.String&nbsp;encoding,\n                   java.lang.String&nbsp;historyUrl)</code>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\">loadDataWithBaseUrlAndHeader</a></span>(java.lang.String&nbsp;baseUrl,\n                            java.lang.String&nbsp;data,\n                            java.lang.String&nbsp;mimeType,\n                            java.lang.String&nbsp;encoding,\n                            java.lang.String&nbsp;historyUrl,\n                            java.util.HashMap&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</code>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadUrl-java.lang.String-android.os.Bundle-\">loadUrl</a></span>(java.lang.String&nbsp;url,\n       android.os.Bundle&nbsp;extraData)</code>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#pageFinish-java.lang.String-\">pageFinish</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">We need to tell the session when onPageFinished is called by WebViewClient since to make a\n better reload when current hit template-changed case.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#requestResource-java.lang.String-\">requestResource</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">Webview ask the host client to intercept request, this method should be called when webview\n call shouldInterceptRequest.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicSessionClient--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicSessionClient</h4>\n<pre>public&nbsp;SonicSessionClient()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"clientReady--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>clientReady</h4>\n<pre>public&nbsp;void&nbsp;clientReady()</pre>\n<div class=\"block\">Notify client is ready to accept data</div>\n</li>\n</ul>\n<a name=\"requestResource-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>requestResource</h4>\n<pre>public&nbsp;java.lang.Object&nbsp;requestResource(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">Webview ask the host client to intercept request, this method should be called when webview\n call shouldInterceptRequest.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The target url which need to request web response</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The data to kernel.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getDiffData-com.tencent.sonic.sdk.SonicDiffDataCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getDiffData</h4>\n<pre>public&nbsp;void&nbsp;getDiffData(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</pre>\n<div class=\"block\">The page execute a java script function to invoke a native method by javascript interface,\n this callback will be called when sonic has finished diff data.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>callback</code> - A callback of web page</dd>\n</dl>\n</li>\n</ul>\n<a name=\"pageFinish-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>pageFinish</h4>\n<pre>public&nbsp;void&nbsp;pageFinish(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">We need to tell the session when onPageFinished is called by WebViewClient since to make a\n better reload when current hit template-changed case.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The target url which is page finished</dd>\n</dl>\n</li>\n</ul>\n<a name=\"bindSession-com.tencent.sonic.sdk.SonicSession-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>bindSession</h4>\n<pre>public&nbsp;void&nbsp;bindSession(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</pre>\n<div class=\"block\">Bind a sonic session to current client</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>session</code> - A sonic session</dd>\n</dl>\n</li>\n</ul>\n<a name=\"loadUrl-java.lang.String-android.os.Bundle-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>loadUrl</h4>\n<pre>public abstract&nbsp;void&nbsp;loadUrl(java.lang.String&nbsp;url,\n                             android.os.Bundle&nbsp;extraData)</pre>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - Url which need to load</dd>\n<dd><code>extraData</code> - Extra data</dd>\n</dl>\n</li>\n</ul>\n<a name=\"loadDataWithBaseUrl-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>loadDataWithBaseUrl</h4>\n<pre>public abstract&nbsp;void&nbsp;loadDataWithBaseUrl(java.lang.String&nbsp;baseUrl,\n                                         java.lang.String&nbsp;data,\n                                         java.lang.String&nbsp;mimeType,\n                                         java.lang.String&nbsp;encoding,\n                                         java.lang.String&nbsp;historyUrl)</pre>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>baseUrl</code> - The URL to use as the page's base URL. If null defaults to\n                   'about:blank'.</dd>\n<dd><code>data</code> - A String of data in the given encoding</dd>\n<dd><code>mimeType</code> - the MIMEType of the data, e.g. 'text/html'. If null,\n                   defaults to 'text/html'.</dd>\n<dd><code>encoding</code> - The encoding of the data</dd>\n<dd><code>historyUrl</code> - The URL to use as the history entry. If null defaults\n                   to 'about:blank'. If non-null, this must be a valid URL.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>loadDataWithBaseUrlAndHeader</h4>\n<pre>public abstract&nbsp;void&nbsp;loadDataWithBaseUrlAndHeader(java.lang.String&nbsp;baseUrl,\n                                                  java.lang.String&nbsp;data,\n                                                  java.lang.String&nbsp;mimeType,\n                                                  java.lang.String&nbsp;encoding,\n                                                  java.lang.String&nbsp;historyUrl,\n                                                  java.util.HashMap&lt;java.lang.String,java.lang.String&gt;&nbsp;headers)</pre>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>baseUrl</code> - The URL to use as the page's base URL. If null defaults to\n                   'about:blank'.</dd>\n<dd><code>data</code> - A String of data in the given encoding</dd>\n<dd><code>mimeType</code> - The MIMEType of the data, e.g. 'text/html'. If null,\n                   defaults to 'text/html'.</dd>\n<dd><code>encoding</code> - The encoding of the data</dd>\n<dd><code>historyUrl</code> - The URL to use as the history entry. If null defaults\n                   to 'about:blank'. If non-null, this must be a valid URL.</dd>\n<dd><code>headers</code> - The headers</dd>\n</dl>\n</li>\n</ul>\n<a name=\"clearHistory--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>clearHistory</h4>\n<pre>public&nbsp;void&nbsp;clearHistory()</pre>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.\n When we hit template-change case, webview may load twice(first load:local cache second load:new page)\n when user press back button, if we do not clear history,it will return to the first load case\n which will make user feel unsure about the action. So we need to clear history if need.</div>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionClient.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionClient.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConfig.Builder.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionConfig.Builder (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionConfig.Builder (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10,\"i11\":10,\"i12\":10,\"i13\":10,\"i14\":10,\"i15\":10,\"i16\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConfig.Builder.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionConfig.Builder\" class=\"title\">类 SonicSessionConfig.Builder</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionConfig.Builder</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicSessionConfig.Builder</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Builder for SonicSessionConfig</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#Builder--\">Builder</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#build--\">build</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setAcceptDiff-boolean-\">setAcceptDiff</a></span>(boolean&nbsp;enable)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setAutoStartWhenCreate-boolean-\">setAutoStartWhenCreate</a></span>(boolean&nbsp;autoStartWhenCreate)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">setCacheInterceptor</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a>&nbsp;interceptor)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setConnectionInterceptor-com.tencent.sonic.sdk.SonicSessionConnectionInterceptor-\">setConnectionInterceptor</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a>&nbsp;interceptor)</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setConnectTimeoutMillis-int-\">setConnectTimeoutMillis</a></span>(int&nbsp;connectTimeoutMillis)</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCustomRequestHeaders-java.util.Map-\">setCustomRequestHeaders</a></span>(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;customRequestHeaders)</code>&nbsp;</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCustomResponseHeaders-java.util.Map-\">setCustomResponseHeaders</a></span>(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;customResponseHeaders)</code>&nbsp;</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setIsAccountRelated-boolean-\">setIsAccountRelated</a></span>(boolean&nbsp;value)</code>&nbsp;</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setPreloadSessionExpiredTimeMillis-long-\">setPreloadSessionExpiredTimeMillis</a></span>(long&nbsp;preloadSessionExpiredTimeMillis)</code>&nbsp;</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReadBufferSize-int-\">setReadBufferSize</a></span>(int&nbsp;readBufferSize)</code>&nbsp;</td>\n</tr>\n<tr id=\"i11\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReadTimeoutMillis-int-\">setReadTimeoutMillis</a></span>(int&nbsp;readTimeoutMillis)</code>&nbsp;</td>\n</tr>\n<tr id=\"i12\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReloadInBadNetwork-boolean-\">setReloadInBadNetwork</a></span>(boolean&nbsp;reloadInBadNetwork)</code>&nbsp;</td>\n</tr>\n<tr id=\"i13\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSessionMode-int-\">setSessionMode</a></span>(int&nbsp;sessionMode)</code>&nbsp;</td>\n</tr>\n<tr id=\"i14\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSupportCacheControl-boolean-\">setSupportCacheControl</a></span>(boolean&nbsp;supportCacheControl)</code>&nbsp;</td>\n</tr>\n<tr id=\"i15\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSupportLocalServer-boolean-\">setSupportLocalServer</a></span>(boolean&nbsp;enable)</code>&nbsp;</td>\n</tr>\n<tr id=\"i16\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setUseSonicCacheInBadNetworkToastMessage-java.lang.String-\">setUseSonicCacheInBadNetworkToastMessage</a></span>(java.lang.String&nbsp;toastMessage)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"Builder--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>Builder</h4>\n<pre>public&nbsp;Builder()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"setConnectTimeoutMillis-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setConnectTimeoutMillis</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setConnectTimeoutMillis(int&nbsp;connectTimeoutMillis)</pre>\n</li>\n</ul>\n<a name=\"setReadTimeoutMillis-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setReadTimeoutMillis</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setReadTimeoutMillis(int&nbsp;readTimeoutMillis)</pre>\n</li>\n</ul>\n<a name=\"setReadBufferSize-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setReadBufferSize</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setReadBufferSize(int&nbsp;readBufferSize)</pre>\n</li>\n</ul>\n<a name=\"setPreloadSessionExpiredTimeMillis-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setPreloadSessionExpiredTimeMillis</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setPreloadSessionExpiredTimeMillis(long&nbsp;preloadSessionExpiredTimeMillis)</pre>\n</li>\n</ul>\n<a name=\"setAcceptDiff-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setAcceptDiff</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setAcceptDiff(boolean&nbsp;enable)</pre>\n</li>\n</ul>\n<a name=\"setIsAccountRelated-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setIsAccountRelated</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setIsAccountRelated(boolean&nbsp;value)</pre>\n</li>\n</ul>\n<a name=\"setReloadInBadNetwork-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setReloadInBadNetwork</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setReloadInBadNetwork(boolean&nbsp;reloadInBadNetwork)</pre>\n</li>\n</ul>\n<a name=\"setAutoStartWhenCreate-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setAutoStartWhenCreate</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setAutoStartWhenCreate(boolean&nbsp;autoStartWhenCreate)</pre>\n</li>\n</ul>\n<a name=\"setUseSonicCacheInBadNetworkToastMessage-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setUseSonicCacheInBadNetworkToastMessage</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setUseSonicCacheInBadNetworkToastMessage(java.lang.String&nbsp;toastMessage)</pre>\n</li>\n</ul>\n<a name=\"setSessionMode-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setSessionMode</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setSessionMode(int&nbsp;sessionMode)</pre>\n</li>\n</ul>\n<a name=\"setCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCacheInterceptor</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setCacheInterceptor(<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a>&nbsp;interceptor)</pre>\n</li>\n</ul>\n<a name=\"setConnectionInterceptor-com.tencent.sonic.sdk.SonicSessionConnectionInterceptor-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setConnectionInterceptor</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setConnectionInterceptor(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a>&nbsp;interceptor)</pre>\n</li>\n</ul>\n<a name=\"setCustomRequestHeaders-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCustomRequestHeaders</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setCustomRequestHeaders(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;customRequestHeaders)</pre>\n</li>\n</ul>\n<a name=\"setCustomResponseHeaders-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setCustomResponseHeaders</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setCustomResponseHeaders(java.util.Map&lt;java.lang.String,java.lang.String&gt;&nbsp;customResponseHeaders)</pre>\n</li>\n</ul>\n<a name=\"setSupportCacheControl-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setSupportCacheControl</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setSupportCacheControl(boolean&nbsp;supportCacheControl)</pre>\n</li>\n</ul>\n<a name=\"setSupportLocalServer-boolean-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>setSupportLocalServer</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a>&nbsp;setSupportLocalServer(boolean&nbsp;enable)</pre>\n</li>\n</ul>\n<a name=\"build--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>build</h4>\n<pre>public&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a>&nbsp;build()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConfig.Builder.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConfig.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionConfig (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionConfig (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConfig.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConfig.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionConfig\" class=\"title\">类 SonicSessionConfig</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionConfig</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicSessionConfig</span>\nextends java.lang.Object</pre>\n<div class=\"block\">The sonicSession configurations. A sonicSession configuration describes\n the http(s) connection time out, the way sonicSession's id be generated and\n so on</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></span></code>\n<div class=\"block\">Builder for SonicSessionConfig</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html#equals-java.lang.Object-\">equals</a></span>(java.lang.Object&nbsp;other)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"equals-java.lang.Object-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>equals</h4>\n<pre>public&nbsp;boolean&nbsp;equals(java.lang.Object&nbsp;other)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>equals</code>&nbsp;在类中&nbsp;<code>java.lang.Object</code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConfig.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConfig.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionConnection.SessionConnectionDefaultImpl (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionConnection.SessionConnectionDefaultImpl (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnection.SessionConnectionDefaultImpl.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSessionConnection\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionConnection.SessionConnectionDefaultImpl\" class=\"title\">类 SonicSessionConnection.SessionConnectionDefaultImpl</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">com.tencent.sonic.sdk.SonicSessionConnection</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicSessionConnection.SessionConnectionDefaultImpl</span>\nextends <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSessionConnection\">\n<!--   -->\n</a>\n<h3>从类继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.net.URLConnection</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#connectionImpl\">connectionImpl</a></span></code>\n<div class=\"block\">A default http connection referred to by the <code>com.tencent.sonic.sdk.SonicSession#currUrl</code>.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"fields.inherited.from.class.com.tencent.sonic.sdk.SonicSessionConnection\">\n<!--   -->\n</a>\n<h3>从类继承的字段&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ACCEPT_DIFF\">CUSTOM_HEAD_FILED_ACCEPT_DIFF</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_CACHE_OFFLINE\">CUSTOM_HEAD_FILED_CACHE_OFFLINE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_DNS_PREFETCH\">CUSTOM_HEAD_FILED_DNS_PREFETCH</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ETAG\">CUSTOM_HEAD_FILED_ETAG</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_HTML_SHA1\">CUSTOM_HEAD_FILED_HTML_SHA1</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_LINK\">CUSTOM_HEAD_FILED_LINK</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_SDK_VERSION\">CUSTOM_HEAD_FILED_SDK_VERSION</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_TAG\">CUSTOM_HEAD_FILED_TEMPLATE_TAG</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#DNS_PREFETCH_ADDRESS\">DNS_PREFETCH_ADDRESS</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP\">HTTP_HEAD_CSP</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP_REPORT_ONLY\">HTTP_HEAD_CSP_REPORT_ONLY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CACHE_CONTROL\">HTTP_HEAD_FIELD_CACHE_CONTROL</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_LENGTH\">HTTP_HEAD_FIELD_CONTENT_LENGTH</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_TYPE\">HTTP_HEAD_FIELD_CONTENT_TYPE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_COOKIE\">HTTP_HEAD_FIELD_COOKIE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_EXPIRES\">HTTP_HEAD_FIELD_EXPIRES</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_PRAGMA\">HTTP_HEAD_FIELD_PRAGMA</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_IF_NOT_MATCH\">HTTP_HEAD_FILED_IF_NOT_MATCH</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_SET_COOKIE\">HTTP_HEAD_FILED_SET_COOKIE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_USER_AGENT\">HTTP_HEAD_FILED_USER_AGENT</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#intent\">intent</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#responseStream\">responseStream</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#session\">session</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#SessionConnectionDefaultImpl-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SessionConnectionDefaultImpl</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                            android.content.Intent&nbsp;intent)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.net.URLConnection</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#createConnection--\">createConnection</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#disconnect--\">disconnect</a></span>()</code>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseCode--\">getResponseCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField</a></span>(java.lang.String&nbsp;key)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseHeaderFields--\">getResponseHeaderFields</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#initConnection-java.net.URLConnection-\">initConnection</a></span>(java.net.URLConnection&nbsp;connection)</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#internalConnect--\">internalConnect</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.io.BufferedInputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#internalGetResponseStream--\">internalGetResponseStream</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.com.tencent.sonic.sdk.SonicSessionConnection\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#connect--\">connect</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\">getResponseStream</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"connectionImpl\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>connectionImpl</h4>\n<pre>protected final&nbsp;java.net.URLConnection connectionImpl</pre>\n<div class=\"block\">A default http connection referred to by the <code>com.tencent.sonic.sdk.SonicSession#currUrl</code>.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SessionConnectionDefaultImpl-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SessionConnectionDefaultImpl</h4>\n<pre>public&nbsp;SessionConnectionDefaultImpl(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                                    android.content.Intent&nbsp;intent)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"createConnection--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>createConnection</h4>\n<pre>protected&nbsp;java.net.URLConnection&nbsp;createConnection()</pre>\n</li>\n</ul>\n<a name=\"initConnection-java.net.URLConnection-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>initConnection</h4>\n<pre>protected&nbsp;boolean&nbsp;initConnection(java.net.URLConnection&nbsp;connection)</pre>\n</li>\n</ul>\n<a name=\"internalConnect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>internalConnect</h4>\n<pre>protected&nbsp;int&nbsp;internalConnect()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#internalConnect--\">internalConnect</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"disconnect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>disconnect</h4>\n<pre>public&nbsp;void&nbsp;disconnect()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#disconnect--\">SonicSessionConnection</a></code></span></div>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#disconnect--\">disconnect</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"internalGetResponseStream--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>internalGetResponseStream</h4>\n<pre>protected&nbsp;java.io.BufferedInputStream&nbsp;internalGetResponseStream()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#internalGetResponseStream--\">internalGetResponseStream</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseCode</h4>\n<pre>public&nbsp;int&nbsp;getResponseCode()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseCode--\">getResponseCode</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseHeaderFields--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseHeaderFields</h4>\n<pre>public&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getResponseHeaderFields()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderFields--\">getResponseHeaderFields</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseHeaderField-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getResponseHeaderField</h4>\n<pre>public&nbsp;java.lang.String&nbsp;getResponseHeaderField(java.lang.String&nbsp;key)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>key</code> - the name of a header field.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the value of the named header field.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnection.SessionConnectionDefaultImpl.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSessionConnection\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnection.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionConnection (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionConnection (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":6,\"i2\":6,\"i3\":6,\"i4\":6,\"i5\":10,\"i6\":6,\"i7\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnection.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnection.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionConnection\" class=\"title\">类 SonicSessionConnection</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionConnection</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>直接已知子类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicSessionConnection</span>\nextends java.lang.Object</pre>\n<div class=\"block\">The abstract class <code>SonicSessionConnection</code> is the superclass\n of all classes that represent a communications link between the\n application and a URL. Instances of this class can be used both to\n read from and to write to the resource referenced by the URL</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></span></code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ACCEPT_DIFF\">CUSTOM_HEAD_FILED_ACCEPT_DIFF</a></span></code>\n<div class=\"block\">HTTP header:accept-diff.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_CACHE_OFFLINE\">CUSTOM_HEAD_FILED_CACHE_OFFLINE</a></span></code>\n<div class=\"block\">HTTP header:cache-offline.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_DNS_PREFETCH\">CUSTOM_HEAD_FILED_DNS_PREFETCH</a></span></code>\n<div class=\"block\">HTTP Header:dns-prefetch.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ETAG\">CUSTOM_HEAD_FILED_ETAG</a></span></code>\n<div class=\"block\">HTTP header:eTag.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_HTML_SHA1\">CUSTOM_HEAD_FILED_HTML_SHA1</a></span></code>\n<div class=\"block\">HTTP header: .</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_LINK\">CUSTOM_HEAD_FILED_LINK</a></span></code>\n<div class=\"block\">HTTP Response Header: Link.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_SDK_VERSION\">CUSTOM_HEAD_FILED_SDK_VERSION</a></span></code>\n<div class=\"block\">HTTP Header:sdk_version.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</a></span></code>\n<div class=\"block\">HTTP header:template_change.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_TAG\">CUSTOM_HEAD_FILED_TEMPLATE_TAG</a></span></code>\n<div class=\"block\">HTTP header:template_tag.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#DNS_PREFETCH_ADDRESS\">DNS_PREFETCH_ADDRESS</a></span></code>\n<div class=\"block\">HTTP header:dns-prefetch-address <br>\n This header represents the ip address of the server.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP\">HTTP_HEAD_CSP</a></span></code>\n<div class=\"block\">HTTP Header：Content-Security-Policy.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP_REPORT_ONLY\">HTTP_HEAD_CSP_REPORT_ONLY</a></span></code>\n<div class=\"block\">HTTP Header：Content-Security-Policy-Report-Only.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CACHE_CONTROL\">HTTP_HEAD_FIELD_CACHE_CONTROL</a></span></code>\n<div class=\"block\">HTTP Header : Cache-Control.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_LENGTH\">HTTP_HEAD_FIELD_CONTENT_LENGTH</a></span></code>\n<div class=\"block\">HTTP Header : Content-Length.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_TYPE\">HTTP_HEAD_FIELD_CONTENT_TYPE</a></span></code>\n<div class=\"block\">HTTP Header : Content-Type.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_COOKIE\">HTTP_HEAD_FIELD_COOKIE</a></span></code>\n<div class=\"block\">HTTP Request Header : Cookie.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_EXPIRES\">HTTP_HEAD_FIELD_EXPIRES</a></span></code>\n<div class=\"block\">HTTP Header : Expires.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_PRAGMA\">HTTP_HEAD_FIELD_PRAGMA</a></span></code>\n<div class=\"block\">HTTP 1.0 Header : Pragma.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_IF_NOT_MATCH\">HTTP_HEAD_FILED_IF_NOT_MATCH</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_SET_COOKIE\">HTTP_HEAD_FILED_SET_COOKIE</a></span></code>\n<div class=\"block\">HTTP Header：Set-Cookie.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_USER_AGENT\">HTTP_HEAD_FILED_USER_AGENT</a></span></code>\n<div class=\"block\">HTTP Request Header：User-Agent.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected android.content.Intent</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#intent\">intent</a></span></code>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected java.io.BufferedInputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#responseStream\">responseStream</a></span></code>\n<div class=\"block\">The input stream that reads from this open connection.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>protected <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#session\">session</a></span></code>\n<div class=\"block\">SonicSession Object used by SonicSessionConnection.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#SonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SonicSessionConnection</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                      android.content.Intent&nbsp;intent)</code>\n<div class=\"block\">Constructor</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#connect--\">connect</a></span>()</code>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#disconnect--\">disconnect</a></span>()</code>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseCode--\">getResponseCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField</a></span>(java.lang.String&nbsp;key)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderFields--\">getResponseHeaderFields</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.io.BufferedInputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\">getResponseStream</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected abstract int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#internalConnect--\">internalConnect</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected abstract java.io.BufferedInputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#internalGetResponseStream--\">internalGetResponseStream</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"CUSTOM_HEAD_FILED_ETAG\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_ETAG</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_ETAG</pre>\n<div class=\"block\">HTTP header:eTag. <br>\n This header represents SHA1 value of the whole website, including template and data.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_ACCEPT_DIFF\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_ACCEPT_DIFF</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_ACCEPT_DIFF</pre>\n<div class=\"block\">HTTP header:accept-diff. <br>\n This header represents that client accepts data incremental scene updates or not.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_ACCEPT_DIFF\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_TEMPLATE_TAG\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_TEMPLATE_TAG</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_TEMPLATE_TAG</pre>\n<div class=\"block\">HTTP header:template_tag. <br>\n This header represents SHA1 value of the template file.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</pre>\n<div class=\"block\">HTTP header:template_change. <br>\n This header indicates whether the template file has changed or not.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_CACHE_OFFLINE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_CACHE_OFFLINE</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_CACHE_OFFLINE</pre>\n<div class=\"block\">HTTP header:cache-offline. <br>\n This header indicates whether the website needs to be refreshed or not.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"DNS_PREFETCH_ADDRESS\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>DNS_PREFETCH_ADDRESS</h4>\n<pre>public static final&nbsp;java.lang.String DNS_PREFETCH_ADDRESS</pre>\n<div class=\"block\">HTTP header:dns-prefetch-address <br>\n This header represents the ip address of the server. <br>\n Sonic Connection will use this ip to connect to server to avoid the cost time of DNS resolution.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.DNS_PREFETCH_ADDRESS\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_SDK_VERSION\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_SDK_VERSION</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_SDK_VERSION</pre>\n<div class=\"block\">HTTP Header:sdk_version. <br>\n This header represents the version of SDK.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_SDK_VERSION\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_DNS_PREFETCH\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_DNS_PREFETCH</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_DNS_PREFETCH</pre>\n<div class=\"block\">HTTP Header:dns-prefetch. <br>\n This header indicates that Sonic connection has used the ip represented by <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html#DNS_PREFETCH_ADDRESS\"><code>DNS_PREFETCH_ADDRESS</code></a></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_DNS_PREFETCH\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_HTML_SHA1\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_HTML_SHA1</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_HTML_SHA1</pre>\n<div class=\"block\">HTTP header: . <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_HTML_SHA1\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_CSP\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_CSP</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_CSP</pre>\n<div class=\"block\">HTTP Header：Content-Security-Policy. <br>\n This header represents the HTML CSP.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_CSP\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_CSP_REPORT_ONLY\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_CSP_REPORT_ONLY</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_CSP_REPORT_ONLY</pre>\n<div class=\"block\">HTTP Header：Content-Security-Policy-Report-Only. <br>\n This header represents the HTML Content-Security-Policy-Report-Only.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_CSP_REPORT_ONLY\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FILED_SET_COOKIE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FILED_SET_COOKIE</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FILED_SET_COOKIE</pre>\n<div class=\"block\">HTTP Header：Set-Cookie. <br>\n This header represents the HTML Set-Cookie.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_SET_COOKIE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_CACHE_CONTROL\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_CACHE_CONTROL</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_CACHE_CONTROL</pre>\n<div class=\"block\">HTTP Header : Cache-Control. <br>\n This header represents the strategy of cache control.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_EXPIRES\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_EXPIRES</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_EXPIRES</pre>\n<div class=\"block\">HTTP Header : Expires. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_EXPIRES\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_PRAGMA\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_PRAGMA</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_PRAGMA</pre>\n<div class=\"block\">HTTP 1.0 Header : Pragma. <br>\n This old header represents the old strategy of cache control.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_PRAGMA\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_CONTENT_TYPE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_CONTENT_TYPE</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_CONTENT_TYPE</pre>\n<div class=\"block\">HTTP Header : Content-Type. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CONTENT_TYPE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_CONTENT_LENGTH\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_CONTENT_LENGTH</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_CONTENT_LENGTH</pre>\n<div class=\"block\">HTTP Header : Content-Length. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CONTENT_LENGTH\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FIELD_COOKIE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FIELD_COOKIE</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FIELD_COOKIE</pre>\n<div class=\"block\">HTTP Request Header : Cookie. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FILED_USER_AGENT\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FILED_USER_AGENT</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FILED_USER_AGENT</pre>\n<div class=\"block\">HTTP Request Header：User-Agent. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_USER_AGENT\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"HTTP_HEAD_FILED_IF_NOT_MATCH\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>HTTP_HEAD_FILED_IF_NOT_MATCH</h4>\n<pre>public static final&nbsp;java.lang.String HTTP_HEAD_FILED_IF_NOT_MATCH</pre>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"CUSTOM_HEAD_FILED_LINK\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>CUSTOM_HEAD_FILED_LINK</h4>\n<pre>public static final&nbsp;java.lang.String CUSTOM_HEAD_FILED_LINK</pre>\n<div class=\"block\">HTTP Response Header: Link. <br></div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../constant-values.html#com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_LINK\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"session\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>session</h4>\n<pre>protected final&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a> session</pre>\n<div class=\"block\">SonicSession Object used by SonicSessionConnection.</div>\n</li>\n</ul>\n<a name=\"intent\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>intent</h4>\n<pre>protected final&nbsp;android.content.Intent intent</pre>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</li>\n</ul>\n<a name=\"responseStream\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>responseStream</h4>\n<pre>protected&nbsp;java.io.BufferedInputStream responseStream</pre>\n<div class=\"block\">The input stream that reads from this open connection.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicSessionConnection</h4>\n<pre>public&nbsp;SonicSessionConnection(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                              android.content.Intent&nbsp;intent)</pre>\n<div class=\"block\">Constructor</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>session</code> - The SonicSession instance</dd>\n<dd><code>intent</code> - The intent</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"connect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connect</h4>\n<pre>public&nbsp;int&nbsp;connect()</pre>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the response code of connection</dd>\n</dl>\n</li>\n</ul>\n<a name=\"disconnect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>disconnect</h4>\n<pre>public abstract&nbsp;void&nbsp;disconnect()</pre>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</li>\n</ul>\n<a name=\"getResponseCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseCode</h4>\n<pre>public abstract&nbsp;int&nbsp;getResponseCode()</pre>\n</li>\n</ul>\n<a name=\"getResponseHeaderFields--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseHeaderFields</h4>\n<pre>public abstract&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getResponseHeaderFields()</pre>\n</li>\n</ul>\n<a name=\"getResponseHeaderField-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseHeaderField</h4>\n<pre>public abstract&nbsp;java.lang.String&nbsp;getResponseHeaderField(java.lang.String&nbsp;key)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>key</code> - the name of a header field.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns the value of the named header field.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResponseStream--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResponseStream</h4>\n<pre>public&nbsp;java.io.BufferedInputStream&nbsp;getResponseStream()</pre>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Returns an input stream that reads from this open connection.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"internalConnect--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>internalConnect</h4>\n<pre>protected abstract&nbsp;int&nbsp;internalConnect()</pre>\n</li>\n</ul>\n<a name=\"internalGetResponseStream--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>internalGetResponseStream</h4>\n<pre>protected abstract&nbsp;java.io.BufferedInputStream&nbsp;internalGetResponseStream()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnection.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnection.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionConnectionInterceptor (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionConnectionInterceptor (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnectionInterceptor.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionConnectionInterceptor\" class=\"title\">类 SonicSessionConnectionInterceptor</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionConnectionInterceptor</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicSessionConnectionInterceptor</span>\nextends java.lang.Object</pre>\n<div class=\"block\"><code>SonicSessionConnectionInterceptor</code> provide a <code>SonicSessionConnection</code>.\n If an <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionConfig</code></a>does not set <code>SonicSessionConnectionInterceptor</code>\n sonic will use <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionConnection.SessionConnectionDefaultImpl</code></a>\n as default.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#SonicSessionConnectionInterceptor--\">SonicSessionConnectionInterceptor</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#getConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">getConnection</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n             android.content.Intent&nbsp;intent)</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#getSonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">getSonicSessionConnection</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                         android.content.Intent&nbsp;intent)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicSessionConnectionInterceptor--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicSessionConnectionInterceptor</h4>\n<pre>public&nbsp;SonicSessionConnectionInterceptor()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getConnection</h4>\n<pre>public abstract&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a>&nbsp;getConnection(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                                                     android.content.Intent&nbsp;intent)</pre>\n</li>\n</ul>\n<a name=\"getSonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getSonicSessionConnection</h4>\n<pre>public static&nbsp;<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a>&nbsp;getSonicSessionConnection(<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session,\n                                                               android.content.Intent&nbsp;intent)</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionConnectionInterceptor.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStatistics.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionStatistics (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionStatistics (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStatistics.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStatistics.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionStatistics\" class=\"title\">类 SonicSessionStatistics</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionStatistics</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicSessionStatistics</span>\nextends java.lang.Object</pre>\n<div class=\"block\">The Statistic model specifies the data models which are required to be used to provide\n the performance data described by the specific attributes in a SonicSession.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#cacheVerifyTime\">cacheVerifyTime</a></span></code>\n<div class=\"block\">The time that sonic begin verify local data</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionConnectTime\">connectionConnectTime</a></span></code>\n<div class=\"block\">The http(s) connect<code>URLConnection.connect()</code> response time</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionFlowFinishTime\">connectionFlowFinishTime</a></span></code>\n<div class=\"block\">Sonic flow end time</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionFlowStartTime\">connectionFlowStartTime</a></span></code>\n<div class=\"block\">The time sonic initiate the http(s) request</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionRespondTime\">connectionRespondTime</a></span></code>\n<div class=\"block\">The http(s) getResponseCode<code>HttpURLConnection.getResponseCode()</code> response time</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#diffDataCallbackTime\">diffDataCallbackTime</a></span></code>\n<div class=\"block\">The time when website try get diff data.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#finalMode\">finalMode</a></span></code>\n<div class=\"block\">Sonic final mode<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#finalResultCode\"><code>SonicSession.finalResultCode</code></a></div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#isDirectAddress\">isDirectAddress</a></span></code>\n<div class=\"block\">Is IP direct</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#originalMode\">originalMode</a></span></code>\n<div class=\"block\">Sonic original mode<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcResultCode\"><code>SonicSession.srcResultCode</code></a></div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#sonicFlowStartTime\">sonicFlowStartTime</a></span></code>\n<div class=\"block\">Sonic flow start<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#runSonicFlow-boolean-\"><code>SonicSession.runSonicFlow(boolean)</code></a> time</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>long</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#sonicStartTime\">sonicStartTime</a></span></code>\n<div class=\"block\">Sonic start <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#start--\"><code>SonicSession.start()</code></a> time</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#srcUrl\">srcUrl</a></span></code>\n<div class=\"block\">Original url</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html#SonicSessionStatistics--\">SonicSessionStatistics</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"srcUrl\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>srcUrl</h4>\n<pre>public&nbsp;java.lang.String srcUrl</pre>\n<div class=\"block\">Original url</div>\n</li>\n</ul>\n<a name=\"finalMode\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>finalMode</h4>\n<pre>public&nbsp;int finalMode</pre>\n<div class=\"block\">Sonic final mode<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#finalResultCode\"><code>SonicSession.finalResultCode</code></a></div>\n</li>\n</ul>\n<a name=\"originalMode\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>originalMode</h4>\n<pre>public&nbsp;int originalMode</pre>\n<div class=\"block\">Sonic original mode<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcResultCode\"><code>SonicSession.srcResultCode</code></a></div>\n</li>\n</ul>\n<a name=\"sonicStartTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sonicStartTime</h4>\n<pre>public&nbsp;long sonicStartTime</pre>\n<div class=\"block\">Sonic start <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#start--\"><code>SonicSession.start()</code></a> time</div>\n</li>\n</ul>\n<a name=\"sonicFlowStartTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>sonicFlowStartTime</h4>\n<pre>public&nbsp;long sonicFlowStartTime</pre>\n<div class=\"block\">Sonic flow start<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#runSonicFlow-boolean-\"><code>SonicSession.runSonicFlow(boolean)</code></a> time</div>\n</li>\n</ul>\n<a name=\"cacheVerifyTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>cacheVerifyTime</h4>\n<pre>public&nbsp;long cacheVerifyTime</pre>\n<div class=\"block\">The time that sonic begin verify local data</div>\n</li>\n</ul>\n<a name=\"connectionFlowStartTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connectionFlowStartTime</h4>\n<pre>public&nbsp;long connectionFlowStartTime</pre>\n<div class=\"block\">The time sonic initiate the http(s) request</div>\n</li>\n</ul>\n<a name=\"connectionConnectTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connectionConnectTime</h4>\n<pre>public&nbsp;long connectionConnectTime</pre>\n<div class=\"block\">The http(s) connect<code>URLConnection.connect()</code> response time</div>\n</li>\n</ul>\n<a name=\"connectionRespondTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connectionRespondTime</h4>\n<pre>public&nbsp;long connectionRespondTime</pre>\n<div class=\"block\">The http(s) getResponseCode<code>HttpURLConnection.getResponseCode()</code> response time</div>\n</li>\n</ul>\n<a name=\"connectionFlowFinishTime\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>connectionFlowFinishTime</h4>\n<pre>public&nbsp;long connectionFlowFinishTime</pre>\n<div class=\"block\">Sonic flow end time</div>\n</li>\n</ul>\n<a name=\"isDirectAddress\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isDirectAddress</h4>\n<pre>public&nbsp;boolean isDirectAddress</pre>\n<div class=\"block\">Is IP direct</div>\n</li>\n</ul>\n<a name=\"diffDataCallbackTime\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>diffDataCallbackTime</h4>\n<pre>public&nbsp;long diffDataCallbackTime</pre>\n<div class=\"block\">The time when website try get diff data.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicSessionStatistics--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicSessionStatistics</h4>\n<pre>public&nbsp;SonicSessionStatistics()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStatistics.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStatistics.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStream.Callback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionStream.Callback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionStream.Callback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStream.Callback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"接口 SonicSessionStream.Callback\" class=\"title\">接口 SonicSessionStream.Callback</h2>\n</div>\n<div class=\"contentContainer\">\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已知实现类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dd>\n</dl>\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static interface <span class=\"typeNameLabel\">SonicSessionStream.Callback</span></pre>\n<div class=\"block\">When <code>SonicSessionStream</code> close the stream will invoke the <code>Callback</code></div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose</a></span>(boolean&nbsp;readComplete,\n       java.io.ByteArrayOutputStream&nbsp;outputStream)</code>\n<div class=\"block\">Close callback</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"onClose-boolean-java.io.ByteArrayOutputStream-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onClose</h4>\n<pre>void&nbsp;onClose(boolean&nbsp;readComplete,\n             java.io.ByteArrayOutputStream&nbsp;outputStream)</pre>\n<div class=\"block\">Close callback</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>readComplete</code> - <code>SonicSessionStream</code> data has read completed</dd>\n<dd><code>outputStream</code> - outputStream include <code>memStream</code> data and <code>netStream</code> data</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStream.Callback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicSessionStream.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicSessionStream (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicSessionStream (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStream.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStream.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicSessionStream\" class=\"title\">类 SonicSessionStream</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>java.io.InputStream</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicSessionStream</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>java.io.Closeable, java.lang.AutoCloseable</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicSessionStream</span>\nextends java.io.InputStream</pre>\n<div class=\"block\">A <code>SonicSessionStream</code> obtains input bytes\n from a <code>memStream</code> and a <code>netStream</code>.\n <code>memStream</code>is read data from network, <code>netStream</code>is unread data from network.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static interface&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></span></code>\n<div class=\"block\">When <code>SonicSessionStream</code> close the stream will invoke the <code>Callback</code></div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html#SonicSessionStream-com.tencent.sonic.sdk.SonicSessionStream.Callback-java.io.ByteArrayOutputStream-java.io.BufferedInputStream-\">SonicSessionStream</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>&nbsp;callback,\n                  java.io.ByteArrayOutputStream&nbsp;outputStream,\n                  java.io.BufferedInputStream&nbsp;netStream)</code>\n<div class=\"block\">Constructor</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html#close--\">close</a></span>()</code>\n<div class=\"block\">Closes this input stream and releases any system resources\n associated with the stream and invoke the callback's onClose method</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html#read--\">read</a></span>()</code>\n<div class=\"block\">\n Reads a single byte from this stream and returns it as an integer in the\n range from 0 to 255.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html#read-byte:A-\">read</a></span>(byte[]&nbsp;buffer)</code>\n<div class=\"block\">Reads a byte of data from this input stream\n Equivalent to <code>read(buffer, 0, buffer.length)</code>.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html#read-byte:A-int-int-\">read</a></span>(byte[]&nbsp;buffer,\n    int&nbsp;byteOffset,\n    int&nbsp;byteCount)</code>\n<div class=\"block\">Reads up to <code>byteCount</code> bytes from this stream and stores them in\n the byte array <code>buffer</code> starting at <code>byteOffset</code>.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.io.InputStream\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.io.InputStream</h3>\n<code>available, mark, markSupported, reset, skip</code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicSessionStream-com.tencent.sonic.sdk.SonicSessionStream.Callback-java.io.ByteArrayOutputStream-java.io.BufferedInputStream-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicSessionStream</h4>\n<pre>public&nbsp;SonicSessionStream(<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>&nbsp;callback,\n                          java.io.ByteArrayOutputStream&nbsp;outputStream,\n                          java.io.BufferedInputStream&nbsp;netStream)</pre>\n<div class=\"block\">Constructor</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>callback</code> - Callback</dd>\n<dd><code>outputStream</code> - Read data from network</dd>\n<dd><code>netStream</code> - Unread data from network</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"close--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>close</h4>\n<pre>public&nbsp;void&nbsp;close()\n           throws java.io.IOException</pre>\n<div class=\"block\">Closes this input stream and releases any system resources\n associated with the stream and invoke the callback's onClose method</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>close</code>&nbsp;在接口中&nbsp;<code>java.io.Closeable</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>close</code>&nbsp;在接口中&nbsp;<code>java.lang.AutoCloseable</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>close</code>&nbsp;在类中&nbsp;<code>java.io.InputStream</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.io.IOException</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"read--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>read</h4>\n<pre>public&nbsp;int&nbsp;read()\n         throws java.io.IOException</pre>\n<div class=\"block\"><p>\n Reads a single byte from this stream and returns it as an integer in the\n range from 0 to 255. Returns -1 if the end of the stream has been\n reached. Blocks until one byte has been read, the end of the source\n stream is detected or an exception is thrown.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>read</code>&nbsp;在类中&nbsp;<code>java.io.InputStream</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.io.IOException</code> - if the stream is closed or another IOException occurs.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"read-byte:A-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>read</h4>\n<pre>public&nbsp;int&nbsp;read(@NonNull\n                byte[]&nbsp;buffer)\n         throws java.io.IOException</pre>\n<div class=\"block\">Reads a byte of data from this input stream\n Equivalent to <code>read(buffer, 0, buffer.length)</code>.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>read</code>&nbsp;在类中&nbsp;<code>java.io.InputStream</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.io.IOException</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"read-byte:A-int-int-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>read</h4>\n<pre>public&nbsp;int&nbsp;read(@NonNull\n                byte[]&nbsp;buffer,\n                int&nbsp;byteOffset,\n                int&nbsp;byteCount)\n         throws java.io.IOException</pre>\n<div class=\"block\">Reads up to <code>byteCount</code> bytes from this stream and stores them in\n the byte array <code>buffer</code> starting at <code>byteOffset</code>.\n Returns the number of bytes actually read or -1 if the end of the stream\n has been reached.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>read</code>&nbsp;在类中&nbsp;<code>java.io.InputStream</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>java.lang.IndexOutOfBoundsException</code> - if <code>byteOffset &lt; 0 || byteCount &lt; 0 || byteOffset + byteCount &gt; buffer.length</code>.</dd>\n<dd><code>java.io.IOException</code> - if the stream is closed or another IOException occurs.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicSessionStream.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicSessionStream.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/SonicUtils.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicUtils (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicUtils (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":9,\"i1\":9,\"i2\":9,\"i3\":9,\"i4\":9,\"i5\":9,\"i6\":9,\"i7\":9,\"i8\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicUtils.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtils.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 SonicUtils\" class=\"title\">类 SonicUtils</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.SonicUtils</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicUtils</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Sonic Utils</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#DEFAULT_CHARSET\">DEFAULT_CHARSET</a></span></code>\n<div class=\"block\">the default charset is UTF-8.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#SonicUtils--\">SonicUtils</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>static java.util.HashMap&lt;java.lang.String,java.lang.String&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#getFilteredHeaders-java.util.Map-\">getFilteredHeaders</a></span>(java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;srcHeaders)</code>\n<div class=\"block\">Get filtered headers by session id, this method will return a map of header(k-v) which\n will not contains \"Set-Cookie\", \"Cache-Control\", \"Expires\".</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#getMD5-java.lang.String-\">getMD5</a></span>(java.lang.String&nbsp;content)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#getMime-java.lang.String-\">getMime</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">Get mime type for url simply.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#getSHA1-byte:A-\">getSHA1</a></span>(byte[]&nbsp;contentBytes)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>static void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#log-java.lang.String-int-java.lang.String-\">log</a></span>(java.lang.String&nbsp;tag,\n   int&nbsp;level,\n   java.lang.String&nbsp;message)</code>\n<div class=\"block\">Logger function</div>\n</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#removeResourceCache-java.lang.String-\">removeResourceCache</a></span>(java.lang.String&nbsp;resourceId)</code>\n<div class=\"block\">Remove a unique resource cache.</div>\n</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>static boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#saveResourceFiles-java.lang.String-byte:A-java.util.Map-\">saveResourceFiles</a></span>(java.lang.String&nbsp;resourceName,\n                 byte[]&nbsp;resourceBytes,\n                 java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;headers)</code>\n<div class=\"block\">save resource files, including resource and headers.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#saveSonicResourceData-java.lang.String-java.lang.String-long-\">saveSonicResourceData</a></span>(java.lang.String&nbsp;resourceUrl,\n                     java.lang.String&nbsp;resourceSha1,\n                     long&nbsp;resourceSize)</code>\n<div class=\"block\">save resource data to database, such as resource sha1, resource size etc.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>static boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html#shouldLog-int-\">shouldLog</a></span>(int&nbsp;level)</code>\n<div class=\"block\">Logger function</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"DEFAULT_CHARSET\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>DEFAULT_CHARSET</h4>\n<pre>public static final&nbsp;java.lang.String DEFAULT_CHARSET</pre>\n<div class=\"block\">the default charset is UTF-8.</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicUtils--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicUtils</h4>\n<pre>public&nbsp;SonicUtils()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"shouldLog-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>shouldLog</h4>\n<pre>public static&nbsp;boolean&nbsp;shouldLog(int&nbsp;level)</pre>\n<div class=\"block\">Logger function</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>level</code> - Level of this log，such like Log.DEBUG.</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Should log or not</dd>\n</dl>\n</li>\n</ul>\n<a name=\"log-java.lang.String-int-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>log</h4>\n<pre>public static&nbsp;void&nbsp;log(java.lang.String&nbsp;tag,\n                       int&nbsp;level,\n                       java.lang.String&nbsp;message)</pre>\n<div class=\"block\">Logger function</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>tag</code> - Used to identify the source of a log message.  It usually identifies\n        the class or activity where the log call occurs.</dd>\n<dd><code>level</code> - Level of this log，such like Log.DEBUG.</dd>\n<dd><code>message</code> - The message you would like logged.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"saveSonicResourceData-java.lang.String-java.lang.String-long-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>saveSonicResourceData</h4>\n<pre>public static&nbsp;void&nbsp;saveSonicResourceData(java.lang.String&nbsp;resourceUrl,\n                                         java.lang.String&nbsp;resourceSha1,\n                                         long&nbsp;resourceSize)</pre>\n<div class=\"block\">save resource data to database, such as resource sha1, resource size etc.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceUrl</code> - the resource url</dd>\n<dd><code>resourceSha1</code> - the resource sha1</dd>\n<dd><code>resourceSize</code> - the resource size</dd>\n</dl>\n</li>\n</ul>\n<a name=\"saveResourceFiles-java.lang.String-byte:A-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>saveResourceFiles</h4>\n<pre>public static&nbsp;boolean&nbsp;saveResourceFiles(java.lang.String&nbsp;resourceName,\n                                        byte[]&nbsp;resourceBytes,\n                                        java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;headers)</pre>\n<div class=\"block\">save resource files, including resource and headers.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceName</code> - resource file name</dd>\n<dd><code>resourceBytes</code> - resource bytes content</dd>\n<dd><code>headers</code> - resource headers</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The result of save files. true if all data is saved successfully.</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getFilteredHeaders-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getFilteredHeaders</h4>\n<pre>public static&nbsp;java.util.HashMap&lt;java.lang.String,java.lang.String&gt;&nbsp;getFilteredHeaders(java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;srcHeaders)</pre>\n<div class=\"block\">Get filtered headers by session id, this method will return a map of header(k-v) which\n will not contains \"Set-Cookie\", \"Cache-Control\", \"Expires\".</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>srcHeaders</code> - The source headers</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The headers of sessionId</dd>\n</dl>\n</li>\n</ul>\n<a name=\"removeResourceCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>removeResourceCache</h4>\n<pre>public static&nbsp;void&nbsp;removeResourceCache(java.lang.String&nbsp;resourceId)</pre>\n<div class=\"block\">Remove a unique resource cache.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceId</code> - a unique resource id</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getMime-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getMime</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;getMime(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">Get mime type for url simply.\n (Maybe <code>android.webkit.MimeTypeMap.getMimeTypeFromExtension</code> is better.)</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - target url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>mime type</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSHA1-byte:A-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSHA1</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;getSHA1(byte[]&nbsp;contentBytes)</pre>\n</li>\n</ul>\n<a name=\"getMD5-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getMD5</h4>\n<pre>public static&nbsp;java.lang.String&nbsp;getMD5(java.lang.String&nbsp;content)</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/SonicUtils.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtils.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/StandardSonicSession.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>StandardSonicSession (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"StandardSonicSession (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10,\"i5\":10,\"i6\":10,\"i7\":10,\"i8\":10,\"i9\":10,\"i10\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/StandardSonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"StandardSonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk</div>\n<h2 title=\"类 StandardSonicSession\" class=\"title\">类 StandardSonicSession</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">com.tencent.sonic.sdk.SonicSession</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.StandardSonicSession</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>android.os.Handler.Callback</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">StandardSonicSession</span>\nextends <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>\nimplements android.os.Handler.Callback</pre>\n<div class=\"block\">A subclass of SonicSession.\n StandardSonicSession only uses the way of <a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html#loadUrl-java.lang.String-android.os.Bundle-\"><code>SonicSessionClient.loadUrl(String, Bundle)</code></a>\n (not loadData). When client initiates a resource interception, the user can set response and header\n information (such as csp) for the kernel.\n\n <p>\n See also <a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><code>QuickSonicSession</code></a></div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的字段&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CHROME_FILE_THREAD\">CHROME_FILE_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_NOTIFY_RESULT\">CLIENT_MSG_NOTIFY_RESULT</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_ON_WEB_READY\">CLIENT_MSG_ON_WEB_READY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReady\">clientIsReady</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clientIsReload\">clientIsReload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_BEGIN\">COMMON_MSG_BEGIN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_END\">COMMON_MSG_END</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#config\">config</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createdTime\">createdTime</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#DATA_UPDATE_BUNDLE_PARAMS_DIFF\">DATA_UPDATE_BUNDLE_PARAMS_DIFF</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#diffDataCallback\">diffDataCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_MSG_BEGIN\">FILE_THREAD_MSG_BEGIN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#fileHandler\">fileHandler</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#finalResultCode\">finalResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#id\">id</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#intent\">intent</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload\">isPreload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForDestroy\">isWaitingForDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSaveFile\">isWaitingForSaveFile</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isWaitingForSessionThread\">isWaitingForSessionThread</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#mainHandler\">mainHandler</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_FALSE\">OFFLINE_MODE_FALSE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_HTTP\">OFFLINE_MODE_HTTP</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_STORE\">OFFLINE_MODE_STORE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_TRUE\">OFFLINE_MODE_TRUE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingDiffData\">pendingDiffData</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#pendingWebResourceStream\">pendingWebResourceStream</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#preloadLinks\">preloadLinks</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_NONE\">RESOURCE_INTERCEPT_STATE_NONE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceDownloaderEngine\">resourceDownloaderEngine</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#resourceInterceptState\">resourceInterceptState</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#server\">server</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SESSION_MSG_FORCE_DESTROY\">SESSION_MSG_FORCE_DESTROY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionCallbackList\">sessionCallbackList</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionClient\">sessionClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sessionState\">sessionState</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sId\">sId</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#sNextSessionLogId\">sNextSessionLogId</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\">SONIC_RESULT_CODE_DATA_UPDATE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\">SONIC_RESULT_CODE_FIRST_LOAD</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_HIT_CACHE\">SONIC_RESULT_CODE_HIT_CACHE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\">SONIC_RESULT_CODE_TEMPLATE_CHANGE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_UNKNOWN\">SONIC_RESULT_CODE_UNKNOWN</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcResultCode\">srcResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#srcUrl\">srcUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_DESTROY\">STATE_DESTROY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_NONE\">STATE_NONE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_READY\">STATE_READY</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#STATE_RUNNING\">STATE_RUNNING</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#stateChangedCallbackList\">stateChangedCallbackList</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#statistics\">statistics</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasInterceptInvoked\">wasInterceptInvoked</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#wasOnPageFinishInvoked\">wasOnPageFinishInvoked</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_CODE\">WEB_RESPONSE_CODE</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_DATA\">WEB_RESPONSE_DATA</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_EXTRA\">WEB_RESPONSE_EXTRA</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_LOCAL_REFRESH_TIME\">WEB_RESPONSE_LOCAL_REFRESH_TIME</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_SRC_CODE\">WEB_RESPONSE_SRC_CODE</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#getSrcResultCode--\">getSrcResultCode</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate</a></span>(java.lang.String&nbsp;serverRsp)</code>\n<div class=\"block\">Sonic obtains the difference data between the server and the local data first,then sonic will\n build the template and server data into html.If client did not load url before, the new html\n will be encapsulated as an inputStream<code>ByteArrayInputStream</code>,When client initiates\n a resource interception, sonic provides the inputStream to the kernel.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad</a></span>()</code>\n<div class=\"block\">Sonic will always read the new data from the server until client initiates a resource interception\n If the server data is not read finished sonic will split the read and unread data into a\n bridgedStream<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>, otherwise all the read data will be encapsulated as an\n inputStream<code>ByteArrayInputStream</code>.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError</a></span>(int&nbsp;responseCode)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache</a></span>(java.lang.String&nbsp;localHtml)</code>&nbsp;</td>\n</tr>\n<tr id=\"i5\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i6\" class=\"altColor\">\n<td class=\"colFirst\"><code>protected void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange</a></span>(java.lang.String&nbsp;newHtml)</code>\n<div class=\"block\">Sonic will always read the new data from the server until the local page finish.</div>\n</td>\n</tr>\n<tr id=\"i7\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#handleMessage-android.os.Message-\">handleMessage</a></span>(android.os.Message&nbsp;msg)</code>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n</td>\n</tr>\n<tr id=\"i8\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#onClientReady--\">onClientReady</a></span>()</code>\n<div class=\"block\">Client informs sonic that it is ready.</div>\n</td>\n</tr>\n<tr id=\"i9\" class=\"rowColor\">\n<td class=\"colFirst\"><code>protected java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#onRequestResource-java.lang.String-\">onRequestResource</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n</td>\n</tr>\n<tr id=\"i10\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady</a></span>(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</code>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></h3>\n<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">addSessionCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#addSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">addSessionStateChangedCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#bindClient-com.tencent.sonic.sdk.SonicSessionClient-\">bindClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#canDestroy--\">canDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#clearSessionData--\">clearSessionData</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#createConnectionIntent-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">createConnectionIntent</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy--\">destroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#destroy-boolean-\">destroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#doSaveSonicCache-com.tencent.sonic.sdk.SonicServer-java.lang.String-\">doSaveSonicCache</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCacheHeaders--\">getCacheHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders--\">getCharsetFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders-java.util.Map-\">getCharsetFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getCurrentUrl--\">getCurrentUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getFinalResultCode--\">getFinalResultCode</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getHeaders--\">getHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSessionClient--\">getSessionClient</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getStatistics--\">getStatistics</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_Connection-boolean-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">handleFlow_Connection</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_NotModified--\">handleFlow_NotModified</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isDestroyedOrWaitingForDestroy--\">isDestroyedOrWaitingForDestroy</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isMatchCurrentUrl-java.lang.String-\">isMatchCurrentUrl</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#isPreload--\">isPreload</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#notifyStateChange-int-int-android.os.Bundle-\">notifyStateChange</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientPageFinished-java.lang.String-\">onClientPageFinished</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientRequestResource-java.lang.String-\">onClientRequestResource</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onServerClosed-com.tencent.sonic.sdk.SonicServer-boolean-\">onServerClosed</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postForceDestroyIfNeed--\">postForceDestroyIfNeed</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#postTaskToSaveSonicCache-java.lang.String-\">postTaskToSaveSonicCache</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#refresh--\">refresh</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">removeSessionCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#removeSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">removeSessionStateChangedCallback</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setCookiesFromHeaders-java.util.Map-boolean-\">setCookiesFromHeaders</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#setResult-int-int-boolean-\">setResult</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#shouldSetCookieAsynchronous--\">shouldSetCookieAsynchronous</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#start--\">start</a>, <a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#switchState-int-int-boolean-\">switchState</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getSrcResultCode--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getSrcResultCode</h4>\n<pre>public&nbsp;int&nbsp;getSrcResultCode()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#getSrcResultCode--\">getSrcResultCode</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleMessage-android.os.Message-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleMessage</h4>\n<pre>public&nbsp;boolean&nbsp;handleMessage(android.os.Message&nbsp;msg)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">SonicSession</a></code></span></div>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>handleMessage</code>&nbsp;在接口中&nbsp;<code>android.os.Handler.Callback</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">handleMessage</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"onClientReady--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onClientReady</h4>\n<pre>public&nbsp;boolean&nbsp;onClientReady()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">SonicSession</a></code></span></div>\n<div class=\"block\">Client informs sonic that it is ready.\n Client ready means it's webview has been initialized, can start load url or load data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">onClientReady</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>True if it is set for the first time</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onWebReady</h4>\n<pre>public&nbsp;boolean&nbsp;onWebReady(<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a>&nbsp;callback)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">SonicSession</a></code></span></div>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>callback</code> - Sonic provides the latest data to the page through this callback</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>The result</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onRequestResource-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onRequestResource</h4>\n<pre>protected&nbsp;java.lang.Object&nbsp;onRequestResource(java.lang.String&nbsp;url)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">SonicSession</a></code></span></div>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">onRequestResource</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url of this session</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_LoadLocalCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_LoadLocalCache</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_LoadLocalCache(java.lang.String&nbsp;localHtml)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_TemplateChange-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_TemplateChange</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_TemplateChange(java.lang.String&nbsp;newHtml)</pre>\n<div class=\"block\">Sonic will always read the new data from the server until the local page finish.\n If the server data is not read finished sonic will split the read and unread data\n into a bridgedStream<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>, otherwise all the read data will be\n encapsulated as an inputStream<code>ByteArrayInputStream</code>. When client\n initiates a resource interception, sonic will provide the bridgedStream or inputStream to\n the kernel.\n\n <p>\n If need save and separate data, sonic will save the server data and separate the server\n data to template and data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>newHtml</code> - new Html string from web-server</dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_HttpError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_HttpError</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_HttpError(int&nbsp;responseCode)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_ServiceUnavailable--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_ServiceUnavailable</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_ServiceUnavailable()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_FirstLoad--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleFlow_FirstLoad</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_FirstLoad()</pre>\n<div class=\"block\">Sonic will always read the new data from the server until client initiates a resource interception\n If the server data is not read finished sonic will split the read and unread data into a\n bridgedStream<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>, otherwise all the read data will be encapsulated as an\n inputStream<code>ByteArrayInputStream</code>. When client initiates a resource interception,\n sonic will provide the bridgedStream or inputStream to the kernel.\n\n <p>\n If need save and separate data, sonic will save the server data and separate the server data to template and data</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"handleFlow_DataUpdate-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>handleFlow_DataUpdate</h4>\n<pre>protected&nbsp;void&nbsp;handleFlow_DataUpdate(java.lang.String&nbsp;serverRsp)</pre>\n<div class=\"block\">Sonic obtains the difference data between the server and the local data first,then sonic will\n build the template and server data into html.If client did not load url before, the new html\n will be encapsulated as an inputStream<code>ByteArrayInputStream</code>,When client initiates\n a resource interception, sonic provides the inputStream to the kernel.\n\n If client did load url before, sonic provides the diff data to page when page obtains the diff data.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>serverRsp</code> - Server response data.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/StandardSonicSession.html\" target=\"_top\">框架</a></li>\n<li><a href=\"StandardSonicSession.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#fields.inherited.from.class.com.tencent.sonic.sdk.SonicSession\">字段</a>&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadCache.SonicResourceCache (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadCache.SonicResourceCache (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCache.SonicResourceCache.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCache\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadCache.SonicResourceCache\" class=\"title\">类 SonicDownloadCache.SonicResourceCache</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">com.tencent.sonic.sdk.download.SonicDownloadCache</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicDownloadCache.SonicResourceCache</span>\nextends <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></pre>\n<div class=\"block\">An sub resource cache implementation <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><code>SonicDownloadCache</code></a></div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCache\">\n<!--   -->\n</a>\n<h3>从类继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></h3>\n<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#TAG\">TAG</a></span></code>\n<div class=\"block\">log filter</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#SonicResourceCache--\">SonicResourceCache</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>byte[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#getResourceCache-java.lang.String-\">getResourceCache</a></span>(java.lang.String&nbsp;resourceUrl)</code>\n<div class=\"block\">get the cached content according to the url</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#getResourceCacheHeader-java.lang.String-\">getResourceCacheHeader</a></span>(java.lang.String&nbsp;resourceUrl)</code>\n<div class=\"block\">get the cached response headers according to the url</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCache\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></h3>\n<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getSubResourceCache--\">getSubResourceCache</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<div class=\"block\">log filter</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicResourceCache--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicResourceCache</h4>\n<pre>public&nbsp;SonicResourceCache()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getResourceCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResourceCache</h4>\n<pre>public&nbsp;byte[]&nbsp;getResourceCache(java.lang.String&nbsp;resourceUrl)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCache-java.lang.String-\">SonicDownloadCache</a></code></span></div>\n<div class=\"block\">get the cached content according to the url</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCache-java.lang.String-\">getResourceCache</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceUrl</code> - the download url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>bytes of cached content of the url</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResourceCacheHeader-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getResourceCacheHeader</h4>\n<pre>public&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getResourceCacheHeader(java.lang.String&nbsp;resourceUrl)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从类复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCacheHeader-java.lang.String-\">SonicDownloadCache</a></code></span></div>\n<div class=\"block\">get the cached response headers according to the url</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCacheHeader-java.lang.String-\">getResourceCacheHeader</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceUrl</code> - the download url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>cached headers of the url</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCache.SonicResourceCache.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.classes.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCache\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCache.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadCache (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadCache (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":6,\"i2\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCache.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCache.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadCache\" class=\"title\">类 SonicDownloadCache</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadCache</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>直接已知子类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">SonicDownloadCache</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Sonic download cache manager</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></span></code>\n<div class=\"block\">An sub resource cache implementation <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><code>SonicDownloadCache</code></a></div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#SonicDownloadCache--\">SonicDownloadCache</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract byte[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCache-java.lang.String-\">getResourceCache</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">get the cached content according to the url</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>abstract java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCacheHeader-java.lang.String-\">getResourceCacheHeader</a></span>(java.lang.String&nbsp;url)</code>\n<div class=\"block\">get the cached response headers according to the url</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html#getSubResourceCache--\">getSubResourceCache</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicDownloadCache--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicDownloadCache</h4>\n<pre>public&nbsp;SonicDownloadCache()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getResourceCache-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResourceCache</h4>\n<pre>public abstract&nbsp;byte[]&nbsp;getResourceCache(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">get the cached content according to the url</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - the download url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>bytes of cached content of the url</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getResourceCacheHeader-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getResourceCacheHeader</h4>\n<pre>public abstract&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;getResourceCacheHeader(java.lang.String&nbsp;url)</pre>\n<div class=\"block\">get the cached response headers according to the url</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - the download url</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>cached headers of the url</dd>\n</dl>\n</li>\n</ul>\n<a name=\"getSubResourceCache--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getSubResourceCache</h4>\n<pre>public static&nbsp;<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a>&nbsp;getSubResourceCache()</pre>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Sub resource cache</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCache.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCache.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadCallback.SimpleDownloadCallback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadCallback.SimpleDownloadCallback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10,\"i4\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCallback.SimpleDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadCallback.SimpleDownloadCallback\" class=\"title\">类 SonicDownloadCallback.SimpleDownloadCallback</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dd>\n</dl>\n<dl>\n<dt>直接已知子类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dd>\n</dl>\n<dl>\n<dt>封闭接口:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicDownloadCallback.SimpleDownloadCallback</span>\nextends java.lang.Object\nimplements <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></pre>\n<div class=\"block\">an empty implementation of <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><code>SonicDownloadCallback</code></a></div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCallback\">\n<!--   -->\n</a>\n<h3>从接口继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></h3>\n<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#SimpleDownloadCallback--\">SimpleDownloadCallback</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onError-int-\">onError</a></span>(int&nbsp;errorCode)</code>\n<div class=\"block\">notify download failed.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onFinish--\">onFinish</a></span>()</code>\n<div class=\"block\">notify download finish.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onProgress-int-int-\">onProgress</a></span>(int&nbsp;pro,\n          int&nbsp;total)</code>\n<div class=\"block\">notify the download progress.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onStart--\">onStart</a></span>()</code>\n<div class=\"block\">notify the download start.</div>\n</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></span>(byte[]&nbsp;content,\n         java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</code>\n<div class=\"block\">notify download success.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SimpleDownloadCallback--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SimpleDownloadCallback</h4>\n<pre>public&nbsp;SimpleDownloadCallback()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"onStart--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onStart</h4>\n<pre>public&nbsp;void&nbsp;onStart()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify the download start.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">onStart</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"onProgress-int-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onProgress</h4>\n<pre>public&nbsp;void&nbsp;onProgress(int&nbsp;pro,\n                       int&nbsp;total)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onProgress-int-int-\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify the download progress.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onProgress-int-int-\">onProgress</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>pro</code> - downloaded size</dd>\n<dd><code>total</code> - total size</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onSuccess-byte:A-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onSuccess</h4>\n<pre>public&nbsp;void&nbsp;onSuccess(byte[]&nbsp;content,\n                      java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify download success.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>content</code> - downloaded content bytes</dd>\n<dd><code>rspHeaders</code> - http response headers</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onError</h4>\n<pre>public&nbsp;void&nbsp;onError(int&nbsp;errorCode)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify download failed.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">onError</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>errorCode</code> - error code</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onFinish--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onFinish</h4>\n<pre>public&nbsp;void&nbsp;onFinish()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onFinish--\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify download finish. <code>onSuccess</code> or <code>onError</code></div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onFinish--\">onFinish</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCallback.SimpleDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadCallback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadCallback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadCallback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":6,\"i2\":6,\"i3\":6,\"i4\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"接口 SonicDownloadCallback\" class=\"title\">接口 SonicDownloadCallback</h2>\n</div>\n<div class=\"contentContainer\">\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已知实现类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a>, <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public interface <span class=\"typeNameLabel\">SonicDownloadCallback</span></pre>\n<div class=\"block\">download callback.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">接口和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></span></code>\n<div class=\"block\">an empty implementation of <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><code>SonicDownloadCallback</code></a></div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">onError</a></span>(int&nbsp;errorCode)</code>\n<div class=\"block\">notify download failed.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onFinish--\">onFinish</a></span>()</code>\n<div class=\"block\">notify download finish.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onProgress-int-int-\">onProgress</a></span>(int&nbsp;pro,\n          int&nbsp;total)</code>\n<div class=\"block\">notify the download progress.</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">onStart</a></span>()</code>\n<div class=\"block\">notify the download start.</div>\n</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></span>(byte[]&nbsp;content,\n         java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</code>\n<div class=\"block\">notify download success.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"onStart--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onStart</h4>\n<pre>void&nbsp;onStart()</pre>\n<div class=\"block\">notify the download start.</div>\n</li>\n</ul>\n<a name=\"onProgress-int-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onProgress</h4>\n<pre>void&nbsp;onProgress(int&nbsp;pro,\n                int&nbsp;total)</pre>\n<div class=\"block\">notify the download progress.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>pro</code> - downloaded size</dd>\n<dd><code>total</code> - total size</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onSuccess-byte:A-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onSuccess</h4>\n<pre>void&nbsp;onSuccess(byte[]&nbsp;content,\n               java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</pre>\n<div class=\"block\">notify download success.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>content</code> - downloaded content bytes</dd>\n<dd><code>rspHeaders</code> - http response headers</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onError</h4>\n<pre>void&nbsp;onError(int&nbsp;errorCode)</pre>\n<div class=\"block\">notify download failed.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>errorCode</code> - error code</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onFinish--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onFinish</h4>\n<pre>void&nbsp;onFinish()</pre>\n<div class=\"block\">notify download finish. <code>onSuccess</code> or <code>onError</code></div>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadClient.DownloadTask (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadClient.DownloadTask (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.DownloadTask.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadClient.DownloadTask\" class=\"title\">类 SonicDownloadClient.DownloadTask</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicDownloadClient.DownloadTask</span>\nextends java.lang.Object</pre>\n<div class=\"block\">Task which record the download info</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.util.List&lt;<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mCallbacks\">mCallbacks</a></span></code>\n<div class=\"block\">list of download callback</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mCookie\">mCookie</a></span></code>\n<div class=\"block\">cookie to be set in the http download request</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.io.InputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mInputStream\">mInputStream</a></span></code>\n<div class=\"block\">the network stream or memory stream or the bridge stream</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mIpAddress\">mIpAddress</a></span></code>\n<div class=\"block\">ip address instead of host to launch a http request</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mResourceUrl\">mResourceUrl</a></span></code>\n<div class=\"block\">url of the resource to be download</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mRspHeaders\">mRspHeaders</a></span></code>\n<div class=\"block\">the download request's response headers</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>java.util.concurrent.atomic.AtomicInteger</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mState\">mState</a></span></code>\n<div class=\"block\">the task's download state</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>java.util.concurrent.atomic.AtomicBoolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mWasInterceptInvoked\">mWasInterceptInvoked</a></span></code>\n<div class=\"block\">whether the task's responding resource was intercepted by kernel</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADED\">STATE_DOWNLOADED</a></span></code>\n<div class=\"block\">the task is in download complete state.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADING\">STATE_DOWNLOADING</a></span></code>\n<div class=\"block\">the task is in downloading state.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_INITIATE\">STATE_INITIATE</a></span></code>\n<div class=\"block\">download in initiate state.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_LOAD_FROM_CACHE\">STATE_LOAD_FROM_CACHE</a></span></code>\n<div class=\"block\">the task is load from cache, not from network.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_QUEUEING\">STATE_QUEUEING</a></span></code>\n<div class=\"block\">download in queueing state.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#DownloadTask--\">DownloadTask</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"STATE_INITIATE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_INITIATE</h4>\n<pre>public static final&nbsp;int STATE_INITIATE</pre>\n<div class=\"block\">download in initiate state.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_INITIATE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_QUEUEING\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_QUEUEING</h4>\n<pre>public static final&nbsp;int STATE_QUEUEING</pre>\n<div class=\"block\">download in queueing state.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_QUEUEING\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_DOWNLOADING\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_DOWNLOADING</h4>\n<pre>public static final&nbsp;int STATE_DOWNLOADING</pre>\n<div class=\"block\">the task is in downloading state.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_DOWNLOADING\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_DOWNLOADED\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_DOWNLOADED</h4>\n<pre>public static final&nbsp;int STATE_DOWNLOADED</pre>\n<div class=\"block\">the task is in download complete state.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_DOWNLOADED\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"STATE_LOAD_FROM_CACHE\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>STATE_LOAD_FROM_CACHE</h4>\n<pre>public static final&nbsp;int STATE_LOAD_FROM_CACHE</pre>\n<div class=\"block\">the task is load from cache, not from network.</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_LOAD_FROM_CACHE\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n<a name=\"mResourceUrl\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mResourceUrl</h4>\n<pre>public&nbsp;java.lang.String mResourceUrl</pre>\n<div class=\"block\">url of the resource to be download</div>\n</li>\n</ul>\n<a name=\"mIpAddress\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mIpAddress</h4>\n<pre>public&nbsp;java.lang.String mIpAddress</pre>\n<div class=\"block\">ip address instead of host to launch a http request</div>\n</li>\n</ul>\n<a name=\"mCookie\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mCookie</h4>\n<pre>public&nbsp;java.lang.String mCookie</pre>\n<div class=\"block\">cookie to be set in the http download request</div>\n</li>\n</ul>\n<a name=\"mRspHeaders\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mRspHeaders</h4>\n<pre>public&nbsp;java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt; mRspHeaders</pre>\n<div class=\"block\">the download request's response headers</div>\n</li>\n</ul>\n<a name=\"mInputStream\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mInputStream</h4>\n<pre>public&nbsp;java.io.InputStream mInputStream</pre>\n<div class=\"block\">the network stream or memory stream or the bridge stream</div>\n</li>\n</ul>\n<a name=\"mState\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mState</h4>\n<pre>public&nbsp;java.util.concurrent.atomic.AtomicInteger mState</pre>\n<div class=\"block\">the task's download state</div>\n</li>\n</ul>\n<a name=\"mWasInterceptInvoked\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>mWasInterceptInvoked</h4>\n<pre>public final&nbsp;java.util.concurrent.atomic.AtomicBoolean mWasInterceptInvoked</pre>\n<div class=\"block\">whether the task's responding resource was intercepted by kernel</div>\n</li>\n</ul>\n<a name=\"mCallbacks\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>mCallbacks</h4>\n<pre>public&nbsp;java.util.List&lt;<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>&gt; mCallbacks</pre>\n<div class=\"block\">list of download callback</div>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"DownloadTask--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>DownloadTask</h4>\n<pre>public&nbsp;DownloadTask()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.DownloadTask.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#methods.inherited.from.class.java.lang.Object\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li>方法</li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadClient.SonicDownloadConnection (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadClient.SonicDownloadConnection (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.SonicDownloadConnection.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadClient.SonicDownloadConnection\" class=\"title\">类 SonicDownloadClient.SonicDownloadConnection</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadClient.SonicDownloadConnection</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicDownloadClient.SonicDownloadConnection</span>\nextends java.lang.Object</pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html#SonicDownloadConnection-java.lang.String-\">SonicDownloadConnection</a></span>(java.lang.String&nbsp;url)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html#disconnect--\">disconnect</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicDownloadConnection-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicDownloadConnection</h4>\n<pre>public&nbsp;SonicDownloadConnection(java.lang.String&nbsp;url)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"disconnect--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>disconnect</h4>\n<pre>public&nbsp;void&nbsp;disconnect()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.SonicDownloadConnection.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadClient.SubResourceDownloadCallback (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadClient.SubResourceDownloadCallback (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.SubResourceDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadClient.SubResourceDownloadCallback\" class=\"title\">类 SonicDownloadClient.SubResourceDownloadCallback</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadClient.SubResourceDownloadCallback</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dd>\n</dl>\n<dl>\n<dt>封闭类:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public static class <span class=\"typeNameLabel\">SonicDownloadClient.SubResourceDownloadCallback</span>\nextends <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></pre>\n<div class=\"block\">sub resource download callback.</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.classes.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCallback\">\n<!--   -->\n</a>\n<h3>从接口继承的嵌套类/接口&nbsp;com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></h3>\n<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></code></li>\n</ul>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#SubResourceDownloadCallback-java.lang.String-\">SubResourceDownloadCallback</a></span>(java.lang.String&nbsp;url)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onError-int-\">onError</a></span>(int&nbsp;errorCode)</code>\n<div class=\"block\">notify download failed.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onStart--\">onStart</a></span>()</code>\n<div class=\"block\">notify the download start.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></span>(byte[]&nbsp;content,\n         java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</code>\n<div class=\"block\">notify download success.</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.com.tencent.sonic.sdk.download.SonicDownloadCallback.SimpleDownloadCallback\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></h3>\n<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onFinish--\">onFinish</a>, <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onProgress-int-int-\">onProgress</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SubResourceDownloadCallback-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SubResourceDownloadCallback</h4>\n<pre>public&nbsp;SubResourceDownloadCallback(java.lang.String&nbsp;url)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"onStart--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onStart</h4>\n<pre>public&nbsp;void&nbsp;onStart()</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify the download start.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">onStart</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onStart--\">onStart</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"onSuccess-byte:A-java.util.Map-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onSuccess</h4>\n<pre>public&nbsp;void&nbsp;onSuccess(byte[]&nbsp;content,\n                      java.util.Map&lt;java.lang.String,java.util.List&lt;java.lang.String&gt;&gt;&nbsp;rspHeaders)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify download success.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>content</code> - downloaded content bytes</dd>\n<dd><code>rspHeaders</code> - http response headers</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onError-int-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onError</h4>\n<pre>public&nbsp;void&nbsp;onError(int&nbsp;errorCode)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">SonicDownloadCallback</a></code></span></div>\n<div class=\"block\">notify download failed.</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">onError</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onError-int-\">onError</a></code>&nbsp;在类中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>errorCode</code> - error code</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.SubResourceDownloadCallback.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadClient.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadClient (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadClient (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadClient\" class=\"title\">类 SonicDownloadClient</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadClient</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicDownloadClient</span>\nextends java.lang.Object\nimplements <a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></pre>\n<div class=\"block\">Handles a single HTTP resource download</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== NESTED CLASS SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"nested.class.summary\">\n<!--   -->\n</a>\n<h3>嵌套类概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"嵌套类概要表, 列表嵌套类和解释\">\n<caption><span>嵌套类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></span></code>\n<div class=\"block\">Task which record the download info</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><code>class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SonicDownloadConnection</a></span></code>&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></span></code>\n<div class=\"block\">sub resource download callback.</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html#TAG\">TAG</a></span></code>\n<div class=\"block\">log filter</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html#SonicDownloadClient-com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask-\">SonicDownloadClient</a></span>(<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a>&nbsp;task)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>int</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html#download--\">download</a></span>()</code>\n<div class=\"block\">download the resource and notify download progress</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose</a></span>(boolean&nbsp;readComplete,\n       java.io.ByteArrayOutputStream&nbsp;outputStream)</code>\n<div class=\"block\">Close callback</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<div class=\"block\">log filter</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadClient.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicDownloadClient-com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicDownloadClient</h4>\n<pre>public&nbsp;SonicDownloadClient(<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a>&nbsp;task)</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"download--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>download</h4>\n<pre>public&nbsp;int&nbsp;download()</pre>\n<div class=\"block\">download the resource and notify download progress</div>\n<dl>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>response code</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onClose-boolean-java.io.ByteArrayOutputStream-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>onClose</h4>\n<pre>public&nbsp;void&nbsp;onClose(boolean&nbsp;readComplete,\n                    java.io.ByteArrayOutputStream&nbsp;outputStream)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">SonicSessionStream.Callback</a></code></span></div>\n<div class=\"block\">Close callback</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>readComplete</code> - <code>SonicSessionStream</code> data has read completed</dd>\n<dd><code>outputStream</code> - outputStream include <code>memStream</code> data and <code>netStream</code> data</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadClient.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadClient.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li><a href=\"#nested.class.summary\">嵌套</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/SonicDownloadEngine.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:57 CST 2018 -->\n<title>SonicDownloadEngine (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicDownloadEngine (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadEngine.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.tencent.sonic.sdk.download</div>\n<h2 title=\"类 SonicDownloadEngine\" class=\"title\">类 SonicDownloadEngine</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li>java.lang.Object</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.tencent.sonic.sdk.download.SonicDownloadEngine</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>android.os.Handler.Callback</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicDownloadEngine</span>\nextends java.lang.Object\nimplements android.os.Handler.Callback</pre>\n<div class=\"block\">an download initiator</div>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static java.lang.String</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#TAG\">TAG</a></span></code>\n<div class=\"block\">log filter</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#SonicDownloadEngine-com.tencent.sonic.sdk.download.SonicDownloadCache-\">SonicDownloadEngine</a></span>(<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a>&nbsp;cache)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#addSubResourcePreloadTask-java.util.List-\">addSubResourcePreloadTask</a></span>(java.util.List&lt;java.lang.String&gt;&nbsp;preloadLinks)</code>\n<div class=\"block\">preload the sub resource in the \"sonic-link\" header.</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#download-java.lang.String-java.lang.String-java.lang.String-com.tencent.sonic.sdk.download.SonicDownloadCallback-\">download</a></span>(java.lang.String&nbsp;resourceUrl,\n        java.lang.String&nbsp;ipAddress,\n        java.lang.String&nbsp;cookie,\n        <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>&nbsp;callback)</code>\n<div class=\"block\">start downloading one resource.</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#handleMessage-android.os.Message-\">handleMessage</a></span>(android.os.Message&nbsp;msg)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>java.lang.Object</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html#onRequestSubResource-java.lang.String-com.tencent.sonic.sdk.SonicSession-\">onRequestSubResource</a></span>(java.lang.String&nbsp;url,\n                    <a href=\"../../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</code>\n<div class=\"block\">When the webview initiates a sub resource interception, the client invokes this method to retrieve the data</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.Object</h3>\n<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"TAG\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>TAG</h4>\n<pre>public static final&nbsp;java.lang.String TAG</pre>\n<div class=\"block\">log filter</div>\n<dl>\n<dt><span class=\"seeLabel\">另请参阅:</span></dt>\n<dd><a href=\"../../../../../constant-values.html#com.tencent.sonic.sdk.download.SonicDownloadEngine.TAG\">常量字段值</a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicDownloadEngine-com.tencent.sonic.sdk.download.SonicDownloadCache-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicDownloadEngine</h4>\n<pre>public&nbsp;SonicDownloadEngine(<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a>&nbsp;cache)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>cache</code> - A specific implementation of <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><code>SonicDownloadCache</code></a></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"handleMessage-android.os.Message-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>handleMessage</h4>\n<pre>public&nbsp;boolean&nbsp;handleMessage(android.os.Message&nbsp;msg)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>handleMessage</code>&nbsp;在接口中&nbsp;<code>android.os.Handler.Callback</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"download-java.lang.String-java.lang.String-java.lang.String-com.tencent.sonic.sdk.download.SonicDownloadCallback-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>download</h4>\n<pre>public&nbsp;<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a>&nbsp;download(java.lang.String&nbsp;resourceUrl,\n                                                 java.lang.String&nbsp;ipAddress,\n                                                 java.lang.String&nbsp;cookie,\n                                                 <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>&nbsp;callback)</pre>\n<div class=\"block\">start downloading one resource.\n if the responding cache exists and isn't expire, will use the cache directly and won't launch a http request;\n if the number of downloading tasks is bigger than config, the task will be delayed before downloading pool is free.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>resourceUrl</code> - the resource's url</dd>\n<dd><code>ipAddress</code> - if dns prefetch the ip address, will use the ip instead of host</dd>\n<dd><code>cookie</code> - set the cookie for the download http request</dd>\n<dd><code>callback</code> - a callback used for notify the download progress and result</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>the download task info</dd>\n</dl>\n</li>\n</ul>\n<a name=\"onRequestSubResource-java.lang.String-com.tencent.sonic.sdk.SonicSession-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>onRequestSubResource</h4>\n<pre>public&nbsp;java.lang.Object&nbsp;onRequestSubResource(java.lang.String&nbsp;url,\n                                             <a href=\"../../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a>&nbsp;session)</pre>\n<div class=\"block\">When the webview initiates a sub resource interception, the client invokes this method to retrieve the data</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>url</code> - The url of sub resource</dd>\n<dd><code>session</code> - current sonic session</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n<dd>Return the data to kernel</dd>\n</dl>\n</li>\n</ul>\n<a name=\"addSubResourcePreloadTask-java.util.List-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>addSubResourcePreloadTask</h4>\n<pre>public&nbsp;void&nbsp;addSubResourcePreloadTask(java.util.List&lt;java.lang.String&gt;&nbsp;preloadLinks)</pre>\n<div class=\"block\">preload the sub resource in the \"sonic-link\" header.</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>preloadLinks</code> - The links which need to be preloaded.</dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicDownloadEngine.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk.download (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\"><a href=\"../../../../../com/tencent/sonic/sdk/download/package-summary.html\" target=\"classFrame\">com.tencent.sonic.sdk.download</a></h1>\n<div class=\"indexContainer\">\n<h2 title=\"接口\">接口</h2>\n<ul title=\"接口\">\n<li><a href=\"SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicDownloadCallback</span></a></li>\n</ul>\n<h2 title=\"类\">类</h2>\n<ul title=\"类\">\n<li><a href=\"SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCache</a></li>\n<li><a href=\"SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCache.SonicResourceCache</a></li>\n<li><a href=\"SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadCallback.SimpleDownloadCallback</a></li>\n<li><a href=\"SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient</a></li>\n<li><a href=\"SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient.DownloadTask</a></li>\n<li><a href=\"SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadClient.SubResourceDownloadCallback</a></li>\n<li><a href=\"SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\" target=\"classFrame\">SonicDownloadEngine</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-summary.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk.download (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.tencent.sonic.sdk.download (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li class=\"navBarCell1Rev\">程序包</li>\n<li>类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/package-summary.html\">上一个程序包</a></li>\n<li>下一个程序包</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"程序包\" class=\"title\">程序包&nbsp;com.tencent.sonic.sdk.download</h1>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"接口概要表, 列表接口和解释\">\n<caption><span>接口概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">接口</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">download callback.</div>\n</td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"类概要表, 列表类和解释\">\n<caption><span>类概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">类</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Sonic download cache manager</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></td>\n<td class=\"colLast\">\n<div class=\"block\">An sub resource cache implementation <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><code>SonicDownloadCache</code></a></div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">an empty implementation of <a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><code>SonicDownloadCallback</code></a></div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Handles a single HTTP resource download</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Task which record the download info</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">sub resource download callback.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></td>\n<td class=\"colLast\">\n<div class=\"block\">an download initiator</div>\n</td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li class=\"navBarCell1Rev\">程序包</li>\n<li>类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/package-summary.html\">上一个程序包</a></li>\n<li>下一个程序包</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/download/package-tree.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk.download 类分层结构 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.tencent.sonic.sdk.download \\u7C7B\\u5206\\u5C42\\u7ED3\\u6784 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/package-tree.html\">上一个</a></li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">程序包com.tencent.sonic.sdk.download的分层结构</h1>\n<span class=\"packageHierarchyLabel\">程序包分层结构:</span>\n<ul class=\"horizontal\">\n<li><a href=\"../../../../../overview-tree.html\">所有程序包</a></li>\n</ul>\n</div>\n<div class=\"contentContainer\">\n<h2 title=\"类分层结构\">类分层结构</h2>\n<ul>\n<li type=\"circle\">java.lang.Object\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache</span></a>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache.SonicResourceCache</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCallback.SimpleDownloadCallback</span></a> (implements com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SubResourceDownloadCallback</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient</span></a> (implements com.tencent.sonic.sdk.<a href=\"../../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.DownloadTask</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SonicDownloadConnection</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadEngine</span></a> (implements android.os.Handler.Callback)</li>\n</ul>\n</li>\n</ul>\n<h2 title=\"接口分层结构\">接口分层结构</h2>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"../../../../../com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">SonicDownloadCallback</span></a></li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../../../com/tencent/sonic/sdk/package-tree.html\">上一个</a></li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../../index.html?com/tencent/sonic/sdk/download/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\"><a href=\"../../../../com/tencent/sonic/sdk/package-summary.html\" target=\"classFrame\">com.tencent.sonic.sdk</a></h1>\n<div class=\"indexContainer\">\n<h2 title=\"接口\">接口</h2>\n<ul title=\"接口\">\n<li><a href=\"SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicDiffDataCallback</span></a></li>\n<li><a href=\"SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicSession.Callback</span></a></li>\n<li><a href=\"SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\" target=\"classFrame\"><span class=\"interfaceName\">SonicSessionStream.Callback</span></a></li>\n</ul>\n<h2 title=\"类\">类</h2>\n<ul title=\"类\">\n<li><a href=\"QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">QuickSonicSession</a></li>\n<li><a href=\"SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicCacheInterceptor</a></li>\n<li><a href=\"SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConfig</a></li>\n<li><a href=\"SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConfig.Builder</a></li>\n<li><a href=\"SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicConstants</a></li>\n<li><a href=\"SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicDBHelper</a></li>\n<li><a href=\"SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicEngine</a></li>\n<li><a href=\"SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicFileUtils</a></li>\n<li><a href=\"SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicResourceDataHelper</a></li>\n<li><a href=\"SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicResourceDataHelper.ResourceData</a></li>\n<li><a href=\"SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicRuntime</a></li>\n<li><a href=\"SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicServer</a></li>\n<li><a href=\"SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSession</a></li>\n<li><a href=\"SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionClient</a></li>\n<li><a href=\"SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConfig</a></li>\n<li><a href=\"SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConfig.Builder</a></li>\n<li><a href=\"SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnection</a></li>\n<li><a href=\"SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnection.SessionConnectionDefaultImpl</a></li>\n<li><a href=\"SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionConnectionInterceptor</a></li>\n<li><a href=\"SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionStatistics</a></li>\n<li><a href=\"SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicSessionStream</a></li>\n<li><a href=\"SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">SonicUtils</a></li>\n<li><a href=\"StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\" target=\"classFrame\">StandardSonicSession</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-summary.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.tencent.sonic.sdk (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li class=\"navBarCell1Rev\">程序包</li>\n<li>类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个程序包</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/download/package-summary.html\">下一个程序包</a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"程序包\" class=\"title\">程序包&nbsp;com.tencent.sonic.sdk</h1>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"接口概要表, 列表接口和解释\">\n<caption><span>接口概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">接口</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">This interface is used to call the difference data between local and server data\n to the client.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">The interface is used to inform the listeners that the state of the\n session has changed.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></td>\n<td class=\"colLast\">\n<div class=\"block\">When <code>SonicSessionStream</code> close the stream will invoke the <code>Callback</code></div>\n</td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"类概要表, 列表类和解释\">\n<caption><span>类概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">类</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></td>\n<td class=\"colLast\">\n<div class=\"block\">A subclass of SonicSession.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></td>\n<td class=\"colLast\">\n<div class=\"block\"><code>SonicCacheInterceptor</code> provide local data.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Sonic global config</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Builder for SonicConfig</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Sonic constants</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></td>\n<td class=\"colLast\">\n<div class=\"block\">SonicDBHelper interacts with the database, such as managing database creation and\n the version management.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Interacts with the overall SonicSessions running in the system.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Interact with the overall file operations.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></td>\n<td class=\"colLast\">\n<div class=\"block\">SonicResourceDataHelper manages the resource database.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></td>\n<td class=\"colLast\">\n<div class=\"block\">resource data structure</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></td>\n<td class=\"colLast\">\n<div class=\"block\"><code>SonicRuntime</code> is a class which interacts with the overall running information in the system,\n including Context, UA, ID (which is the unique identification for the saved data) and other information.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Instances of this class can be used to read server response from SonicSessionConnection.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></td>\n<td class=\"colLast\">\n<div class=\"block\">In Sonic, <code>SonicSession</code>s are used to manage the entire process,include\n obtain the latest data from the server, provide local and latest\n data to kernel, separate html to template and data, build template\n and data to html and so on.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></td>\n<td class=\"colLast\">\n<div class=\"block\"><code>SonicSessionClient</code> is a thin API class that delegates its public API to\n a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></td>\n<td class=\"colLast\">\n<div class=\"block\">The sonicSession configurations.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Builder for SonicSessionConfig</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></td>\n<td class=\"colLast\">\n<div class=\"block\">The abstract class <code>SonicSessionConnection</code> is the superclass\n of all classes that represent a communications link between the\n application and a URL.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a></td>\n<td class=\"colLast\">\n<div class=\"block\"><code>SonicSessionConnectionInterceptor</code> provide a <code>SonicSessionConnection</code>.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></td>\n<td class=\"colLast\">\n<div class=\"block\">The Statistic model specifies the data models which are required to be used to provide\n the performance data described by the specific attributes in a SonicSession.</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></td>\n<td class=\"colLast\">\n<div class=\"block\">A <code>SonicSessionStream</code> obtains input bytes\n from a <code>memStream</code> and a <code>netStream</code>.</div>\n</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></td>\n<td class=\"colLast\">\n<div class=\"block\">Sonic Utils</div>\n</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></td>\n<td class=\"colLast\">\n<div class=\"block\">A subclass of SonicSession.</div>\n</td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li class=\"navBarCell1Rev\">程序包</li>\n<li>类</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个程序包</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/download/package-summary.html\">下一个程序包</a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/com/tencent/sonic/sdk/package-tree.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>com.tencent.sonic.sdk 类分层结构 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.tencent.sonic.sdk \\u7C7B\\u5206\\u5C42\\u7ED3\\u6784 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/download/package-tree.html\">下一个</a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">程序包com.tencent.sonic.sdk的分层结构</h1>\n<span class=\"packageHierarchyLabel\">程序包分层结构:</span>\n<ul class=\"horizontal\">\n<li><a href=\"../../../../overview-tree.html\">所有程序包</a></li>\n</ul>\n</div>\n<div class=\"contentContainer\">\n<h2 title=\"类分层结构\">类分层结构</h2>\n<ul>\n<li type=\"circle\">java.lang.Object\n<ul>\n<li type=\"circle\">java.io.InputStream (implements java.io.Closeable)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStream</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicCacheInterceptor</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig.Builder</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConstants</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicEngine</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicFileUtils</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper.ResourceData</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicRuntime</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicServer</span></a> (implements com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSession</span></a> (implements android.os.Handler.Callback)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">QuickSonicSession</span></a> (implements android.os.Handler.Callback)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">StandardSonicSession</span></a> (implements android.os.Handler.Callback)</li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionClient</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig.Builder</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection</span></a>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection.SessionConnectionDefaultImpl</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnectionInterceptor</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStatistics</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicUtils</span></a></li>\n<li type=\"circle\">android.database.sqlite.SQLiteOpenHelper\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicDBHelper</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h2 title=\"接口分层结构\">接口分层结构</h2>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicDiffDataCallback</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSession.Callback</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"../../../../com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSessionStream.Callback</span></a></li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../overview-summary.html\">概览</a></li>\n<li><a href=\"package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li><a href=\"../../../../com/tencent/sonic/sdk/download/package-tree.html\">下一个</a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/tencent/sonic/sdk/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/constant-values.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>常量字段值 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u5E38\\u91CF\\u5B57\\u6BB5\\u503C (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?constant-values.html\" target=\"_top\">框架</a></li>\n<li><a href=\"constant-values.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"常量字段值\" class=\"title\">常量字段值</h1>\n<h2 title=\"目录\">目录</h2>\n<ul>\n<li><a href=\"#com.tencent\">com.tencent.*</a></li>\n</ul>\n</div>\n<div class=\"constantValuesContainer\"><a name=\"com.tencent\">\n<!--   -->\n</a>\n<h2 title=\"com.tencent\">com.tencent.*</h2>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicCacheInterceptor.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicCacheInterceptor\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_BUILD_HTML_ERROR\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_BUILD_HTML_ERROR\">ERROR_CODE_BUILD_HTML_ERROR</a></code></td>\n<td class=\"colLast\"><code>-1008</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_IOE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_IOE\">ERROR_CODE_CONNECT_IOE</a></code></td>\n<td class=\"colLast\"><code>-901</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_NPE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_NPE\">ERROR_CODE_CONNECT_NPE</a></code></td>\n<td class=\"colLast\"><code>-903</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_CONNECT_TOE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_TOE\">ERROR_CODE_CONNECT_TOE</a></code></td>\n<td class=\"colLast\"><code>-902</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_DATA_VERIFY_FAIL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_DATA_VERIFY_FAIL\">ERROR_CODE_DATA_VERIFY_FAIL</a></code></td>\n<td class=\"colLast\"><code>-1001</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_MAKE_DIR_ERROR\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MAKE_DIR_ERROR\">ERROR_CODE_MAKE_DIR_ERROR</a></code></td>\n<td class=\"colLast\"><code>-1003</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_MERGE_DIFF_DATA_FAIL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MERGE_DIFF_DATA_FAIL\">ERROR_CODE_MERGE_DIFF_DATA_FAIL</a></code></td>\n<td class=\"colLast\"><code>-1006</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SERVER_DATA_EXCEPTION\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SERVER_DATA_EXCEPTION\">ERROR_CODE_SERVER_DATA_EXCEPTION</a></code></td>\n<td class=\"colLast\"><code>-1007</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SPLIT_HTML_FAIL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SPLIT_HTML_FAIL\">ERROR_CODE_SPLIT_HTML_FAIL</a></code></td>\n<td class=\"colLast\"><code>-1005</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_SUCCESS\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SUCCESS\">ERROR_CODE_SUCCESS</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_UNKNOWN\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_UNKNOWN\">ERROR_CODE_UNKNOWN</a></code></td>\n<td class=\"colLast\"><code>-1</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.ERROR_CODE_WRITE_FILE_FAIL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_WRITE_FILE_FAIL\">ERROR_CODE_WRITE_FILE_FAIL</a></code></td>\n<td class=\"colLast\"><code>-1004</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SESSION_MODE_DEFAULT\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_DEFAULT\">SESSION_MODE_DEFAULT</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SESSION_MODE_QUICK\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_QUICK\">SESSION_MODE_QUICK</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SONIC_PARAMETER_NAME_PREFIX\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_PARAMETER_NAME_PREFIX\">SONIC_PARAMETER_NAME_PREFIX</a></code></td>\n<td class=\"colLast\"><code>\"sonic_\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SONIC_REMAIN_PARAMETER_NAMES\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_NAMES\">SONIC_REMAIN_PARAMETER_NAMES</a></code></td>\n<td class=\"colLast\"><code>\"sonic_remain_params\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">SONIC_REMAIN_PARAMETER_SPLIT_CHAR</a></code></td>\n<td class=\"colLast\"><code>\";\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SONIC_SDK_LOG_PREFIX\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_SDK_LOG_PREFIX\">SONIC_SDK_LOG_PREFIX</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicConstants.SONIC_VERSION_NUM\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_VERSION_NUM\">SONIC_VERSION_NUM</a></code></td>\n<td class=\"colLast\"><code>\"2.0.0\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicResourceDataHelper.CREATE_TABLE_SQL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html#CREATE_TABLE_SQL\">CREATE_TABLE_SQL</a></code></td>\n<td class=\"colLast\"><code>\"CREATE TABLE IF NOT EXISTS ResourceData ( id  integer PRIMARY KEY autoincrement , resourceID text not null , resourceSha1 text not null , resourceSize integer default 0 , resourceUpdateTime integer default 0 , cacheExpiredTime integer default 0 ); \"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicServer.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicServer.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicServer\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.CHROME_FILE_THREAD\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#CHROME_FILE_THREAD\">CHROME_FILE_THREAD</a></code></td>\n<td class=\"colLast\"><code>\"Chrome_FileThread\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.CLIENT_MSG_NOTIFY_RESULT\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_NOTIFY_RESULT\">CLIENT_MSG_NOTIFY_RESULT</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.CLIENT_MSG_ON_WEB_READY\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_ON_WEB_READY\">CLIENT_MSG_ON_WEB_READY</a></code></td>\n<td class=\"colLast\"><code>2</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.COMMON_MSG_BEGIN\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_BEGIN\">COMMON_MSG_BEGIN</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.COMMON_MSG_END\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_END\">COMMON_MSG_END</a></code></td>\n<td class=\"colLast\"><code>4</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.DATA_UPDATE_BUNDLE_PARAMS_DIFF\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#DATA_UPDATE_BUNDLE_PARAMS_DIFF\">DATA_UPDATE_BUNDLE_PARAMS_DIFF</a></code></td>\n<td class=\"colLast\"><code>\"_diff_data_\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.FILE_THREAD_MSG_BEGIN\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_MSG_BEGIN\">FILE_THREAD_MSG_BEGIN</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</a></code></td>\n<td class=\"colLast\"><code>2</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_FALSE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_FALSE\">OFFLINE_MODE_FALSE</a></code></td>\n<td class=\"colLast\"><code>\"false\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_HTTP\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_HTTP\">OFFLINE_MODE_HTTP</a></code></td>\n<td class=\"colLast\"><code>\"http\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_STORE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_STORE\">OFFLINE_MODE_STORE</a></code></td>\n<td class=\"colLast\"><code>\"store\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_TRUE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_TRUE\">OFFLINE_MODE_TRUE</a></code></td>\n<td class=\"colLast\"><code>\"true\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</a></code></td>\n<td class=\"colLast\"><code>2</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.RESOURCE_INTERCEPT_STATE_NONE\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_NONE\">RESOURCE_INTERCEPT_STATE_NONE</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SESSION_MSG_FORCE_DESTROY\">\n<!--   -->\n</a><code>protected&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SESSION_MSG_FORCE_DESTROY\">SESSION_MSG_FORCE_DESTROY</a></code></td>\n<td class=\"colLast\"><code>3</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_DATA_UPDATE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\">SONIC_RESULT_CODE_DATA_UPDATE</a></code></td>\n<td class=\"colLast\"><code>200</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_FIRST_LOAD\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\">SONIC_RESULT_CODE_FIRST_LOAD</a></code></td>\n<td class=\"colLast\"><code>1000</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_HIT_CACHE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_HIT_CACHE\">SONIC_RESULT_CODE_HIT_CACHE</a></code></td>\n<td class=\"colLast\"><code>304</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_TEMPLATE_CHANGE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\">SONIC_RESULT_CODE_TEMPLATE_CHANGE</a></code></td>\n<td class=\"colLast\"><code>2000</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.SONIC_RESULT_CODE_UNKNOWN\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_UNKNOWN\">SONIC_RESULT_CODE_UNKNOWN</a></code></td>\n<td class=\"colLast\"><code>-1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.STATE_DESTROY\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_DESTROY\">STATE_DESTROY</a></code></td>\n<td class=\"colLast\"><code>3</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.STATE_NONE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_NONE\">STATE_NONE</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.STATE_READY\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_READY\">STATE_READY</a></code></td>\n<td class=\"colLast\"><code>2</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.STATE_RUNNING\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_RUNNING\">STATE_RUNNING</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicSession\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_CODE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_CODE\">WEB_RESPONSE_CODE</a></code></td>\n<td class=\"colLast\"><code>\"code\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_DATA\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_DATA\">WEB_RESPONSE_DATA</a></code></td>\n<td class=\"colLast\"><code>\"result\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_EXTRA\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_EXTRA\">WEB_RESPONSE_EXTRA</a></code></td>\n<td class=\"colLast\"><code>\"extra\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_LOCAL_REFRESH_TIME\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_LOCAL_REFRESH_TIME\">WEB_RESPONSE_LOCAL_REFRESH_TIME</a></code></td>\n<td class=\"colLast\"><code>\"local_refresh_time\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSession.WEB_RESPONSE_SRC_CODE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_SRC_CODE\">WEB_RESPONSE_SRC_CODE</a></code></td>\n<td class=\"colLast\"><code>\"srcCode\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_ACCEPT_DIFF\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ACCEPT_DIFF\">CUSTOM_HEAD_FILED_ACCEPT_DIFF</a></code></td>\n<td class=\"colLast\"><code>\"accept-diff\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_CACHE_OFFLINE\">CUSTOM_HEAD_FILED_CACHE_OFFLINE</a></code></td>\n<td class=\"colLast\"><code>\"cache-offline\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_DNS_PREFETCH\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_DNS_PREFETCH\">CUSTOM_HEAD_FILED_DNS_PREFETCH</a></code></td>\n<td class=\"colLast\"><code>\"sonic-dns-prefetch\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ETAG\">CUSTOM_HEAD_FILED_ETAG</a></code></td>\n<td class=\"colLast\"><code>\"eTag\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_HTML_SHA1\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_HTML_SHA1\">CUSTOM_HEAD_FILED_HTML_SHA1</a></code></td>\n<td class=\"colLast\"><code>\"sonic-html-sha1\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_LINK\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_LINK\">CUSTOM_HEAD_FILED_LINK</a></code></td>\n<td class=\"colLast\"><code>\"sonic-link\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_SDK_VERSION\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_SDK_VERSION\">CUSTOM_HEAD_FILED_SDK_VERSION</a></code></td>\n<td class=\"colLast\"><code>\"sonic-sdk-version\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</a></code></td>\n<td class=\"colLast\"><code>\"template-change\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_TAG\">CUSTOM_HEAD_FILED_TEMPLATE_TAG</a></code></td>\n<td class=\"colLast\"><code>\"template-tag\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.DNS_PREFETCH_ADDRESS\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#DNS_PREFETCH_ADDRESS\">DNS_PREFETCH_ADDRESS</a></code></td>\n<td class=\"colLast\"><code>\"dns-prefetch-address\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_CSP\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP\">HTTP_HEAD_CSP</a></code></td>\n<td class=\"colLast\"><code>\"Content-Security-Policy\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_CSP_REPORT_ONLY\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP_REPORT_ONLY\">HTTP_HEAD_CSP_REPORT_ONLY</a></code></td>\n<td class=\"colLast\"><code>\"Content-Security-Policy-Report-Only\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CACHE_CONTROL\">HTTP_HEAD_FIELD_CACHE_CONTROL</a></code></td>\n<td class=\"colLast\"><code>\"Cache-Control\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CONTENT_LENGTH\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_LENGTH\">HTTP_HEAD_FIELD_CONTENT_LENGTH</a></code></td>\n<td class=\"colLast\"><code>\"Content-Length\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_CONTENT_TYPE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_TYPE\">HTTP_HEAD_FIELD_CONTENT_TYPE</a></code></td>\n<td class=\"colLast\"><code>\"Content-Type\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_COOKIE\">HTTP_HEAD_FIELD_COOKIE</a></code></td>\n<td class=\"colLast\"><code>\"Cookie\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_EXPIRES\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_EXPIRES\">HTTP_HEAD_FIELD_EXPIRES</a></code></td>\n<td class=\"colLast\"><code>\"Expires\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_PRAGMA\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_PRAGMA\">HTTP_HEAD_FIELD_PRAGMA</a></code></td>\n<td class=\"colLast\"><code>\"Pragma\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_IF_NOT_MATCH\">HTTP_HEAD_FILED_IF_NOT_MATCH</a></code></td>\n<td class=\"colLast\"><code>\"If-None-Match\"</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_SET_COOKIE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_SET_COOKIE\">HTTP_HEAD_FILED_SET_COOKIE</a></code></td>\n<td class=\"colLast\"><code>\"Set-Cookie\"</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FILED_USER_AGENT\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_USER_AGENT\">HTTP_HEAD_FILED_USER_AGENT</a></code></td>\n<td class=\"colLast\"><code>\"User-Agent\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadCache.SonicResourceCache.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicDownloadCache\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicDownloadClient\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_DOWNLOADED\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADED\">STATE_DOWNLOADED</a></code></td>\n<td class=\"colLast\"><code>3</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_DOWNLOADING\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADING\">STATE_DOWNLOADING</a></code></td>\n<td class=\"colLast\"><code>2</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_INITIATE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_INITIATE\">STATE_INITIATE</a></code></td>\n<td class=\"colLast\"><code>0</code></td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_LOAD_FROM_CACHE\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_LOAD_FROM_CACHE\">STATE_LOAD_FROM_CACHE</a></code></td>\n<td class=\"colLast\"><code>4</code></td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask.STATE_QUEUEING\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_QUEUEING\">STATE_QUEUEING</a></code></td>\n<td class=\"colLast\"><code>1</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"constantsSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"常量字段值表, 列表常量字段和值\">\n<caption><span>com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th scope=\"col\">常量字段</th>\n<th class=\"colLast\" scope=\"col\">值</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a name=\"com.tencent.sonic.sdk.download.SonicDownloadEngine.TAG\">\n<!--   -->\n</a><code>public&nbsp;static&nbsp;final&nbsp;java.lang.String</code></td>\n<td><code><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#TAG\">TAG</a></code></td>\n<td class=\"colLast\"><code>\"SonicSdk_SonicDownloadEngine\"</code></td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?constant-values.html\" target=\"_top\">框架</a></li>\n<li><a href=\"constant-values.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/deprecated-list.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>已过时的列表 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u5DF2\\u8FC7\\u65F6\\u7684\\u5217\\u8868 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li class=\"navBarCell1Rev\">已过时</li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?deprecated-list.html\" target=\"_top\">框架</a></li>\n<li><a href=\"deprecated-list.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"已过时的 API\" class=\"title\">已过时的 API</h1>\n<h2 title=\"目录\">目录</h2>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li class=\"navBarCell1Rev\">已过时</li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?deprecated-list.html\" target=\"_top\">框架</a></li>\n<li><a href=\"deprecated-list.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/help-doc.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>API 帮助 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"API \\u5E2E\\u52A9 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li class=\"navBarCell1Rev\">帮助</li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?help-doc.html\" target=\"_top\">框架</a></li>\n<li><a href=\"help-doc.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">此 API 文档的组织方式</h1>\n<div class=\"subTitle\">此 API (应用程序编程接口) 文档包含对应于导航栏中的项目的页面, 如下所述。</div>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h2>概览</h2>\n<p><a href=\"overview-summary.html\">概览</a> 页面是此 API 文档的首页, 提供了所有程序包的列表及其概要。此页面也可能包含这些程序包的总体说明。</p>\n</li>\n<li class=\"blockList\">\n<h2>程序包</h2>\n<p>每个程序包都有一个页面, 其中包含它的类和接口的列表及其概要。此页面可以包含六个类别:</p>\n<ul>\n<li>接口 (斜体)</li>\n<li>类</li>\n<li>枚举</li>\n<li>异常错误</li>\n<li>错误</li>\n<li>注释类型</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>类/接口</h2>\n<p>每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:</p>\n<ul>\n<li>类继承图</li>\n<li>直接子类</li>\n<li>所有已知子接口</li>\n<li>所有已知实现类</li>\n<li>类/接口声明</li>\n<li>类/接口说明</li>\n</ul>\n<ul>\n<li>嵌套类概要</li>\n<li>字段概要</li>\n<li>构造器概要</li>\n<li>方法概要</li>\n</ul>\n<ul>\n<li>字段详细资料</li>\n<li>构造器详细资料</li>\n<li>方法详细资料</li>\n</ul>\n<p>每个概要条目都包含该项目的详细说明的第一句。概要条目按字母顺序排列, 而详细说明则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。</p>\n</li>\n<li class=\"blockList\">\n<h2>注释类型</h2>\n<p>每个注释类型都有各自的页面, 其中包含以下部分:</p>\n<ul>\n<li>注释类型声明</li>\n<li>注释类型说明</li>\n<li>必需元素概要</li>\n<li>可选元素概要</li>\n<li>元素详细资料</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>枚举</h2>\n<p>每个枚举都有各自的页面, 其中包含以下部分:</p>\n<ul>\n<li>枚举声明</li>\n<li>枚举说明</li>\n<li>枚举常量概要</li>\n<li>枚举常量详细资料</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>树 (类分层结构)</h2>\n<p>对于所有程序包, 有一个<a href=\"overview-tree.html\">类分层结构</a>页面, 以及每个程序包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从<code>java.lang.Object</code>开始, 按继承结构对类进行排列。接口不从<code>java.lang.Object</code>继承。</p>\n<ul>\n<li>查看“概览”页面时, 单击 \"树\" 将显示所有程序包的分层结构。</li>\n<li>查看特定程序包, 类或接口页面时, 单击 \"树\" 将仅显示该程序包的分层结构。</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>已过时的 API</h2>\n<p><a href=\"deprecated-list.html\">已过时的 API</a> 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API, 所以建议不要使用已过时的 API。在将来的实现过程中, 可能会删除已过时的 API。</p>\n</li>\n<li class=\"blockList\">\n<h2>索引</h2>\n<p><a href=\"index-all.html\">索引</a> 包含按字母顺序排列的所有类, 接口, 构造器, 方法和字段的列表。</p>\n</li>\n<li class=\"blockList\">\n<h2>上一个/下一个</h2>\n<p>这些链接使您可以转至下一个或上一个类, 接口, 程序包或相关页面。</p>\n</li>\n<li class=\"blockList\">\n<h2>框架/无框架</h2>\n<p>这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。</p>\n</li>\n<li class=\"blockList\">\n<h2>所有类</h2>\n<p><a href=\"allclasses-noframe.html\">所有类</a>链接显示所有类和接口 (除了非静态嵌套类型)。</p>\n</li>\n<li class=\"blockList\">\n<h2>序列化表格</h2>\n<p>每个可序列化或可外部化的类都有其序列化字段和方法的说明。此信息对重新实现者有用, 而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接, 但您可以通过下列方式获取此信息: 转至任何序列化类, 然后单击类说明的 \"另请参阅\" 部分中的 \"序列化表格\"。</p>\n</li>\n<li class=\"blockList\">\n<h2>常量字段值</h2>\n<p><a href=\"constant-values.html\">常量字段值</a>页面列出了静态最终字段及其值。</p>\n</li>\n</ul>\n<span class=\"emphasizedPhrase\">此帮助文件适用于使用标准 doclet 生成的 API 文档。</span></div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li class=\"navBarCell1Rev\">帮助</li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?help-doc.html\" target=\"_top\">框架</a></li>\n<li><a href=\"help-doc.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/index-all.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>索引 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7D22\\u5F15 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li class=\"navBarCell1Rev\">索引</li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?index-all.html\" target=\"_top\">框架</a></li>\n<li><a href=\"index-all.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"contentContainer\"><a href=\"#I:A\">A</a>&nbsp;<a href=\"#I:B\">B</a>&nbsp;<a href=\"#I:C\">C</a>&nbsp;<a href=\"#I:D\">D</a>&nbsp;<a href=\"#I:E\">E</a>&nbsp;<a href=\"#I:F\">F</a>&nbsp;<a href=\"#I:G\">G</a>&nbsp;<a href=\"#I:H\">H</a>&nbsp;<a href=\"#I:I\">I</a>&nbsp;<a href=\"#I:L\">L</a>&nbsp;<a href=\"#I:M\">M</a>&nbsp;<a href=\"#I:N\">N</a>&nbsp;<a href=\"#I:O\">O</a>&nbsp;<a href=\"#I:P\">P</a>&nbsp;<a href=\"#I:Q\">Q</a>&nbsp;<a href=\"#I:R\">R</a>&nbsp;<a href=\"#I:S\">S</a>&nbsp;<a href=\"#I:T\">T</a>&nbsp;<a href=\"#I:V\">V</a>&nbsp;<a href=\"#I:W\">W</a>&nbsp;<a name=\"I:A\">\n<!--   -->\n</a>\n<h2 class=\"title\">A</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#addSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">addSessionCallback(SonicSessionCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#addSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">addSessionStateChangedCallback(SonicSession.Callback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#addSubResourcePreloadTask-java.util.List-\">addSubResourcePreloadTask(List&lt;String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>\n<div class=\"block\">preload the sub resource in the \"sonic-link\" header.</div>\n</dd>\n</dl>\n<a name=\"I:B\">\n<!--   -->\n</a>\n<h2 class=\"title\">B</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#bindClient-com.tencent.sonic.sdk.SonicSessionClient-\">bindClient(SonicSessionClient)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#bindSession-com.tencent.sonic.sdk.SonicSession-\">bindSession(SonicSession)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">Bind a sonic session to current client</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#build--\">build()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#build--\">build()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#Builder--\">Builder()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#Builder--\">Builder()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:C\">\n<!--   -->\n</a>\n<h2 class=\"title\">C</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#cachedResponseHeaders\">cachedResponseHeaders</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">Cached response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code></div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#cacheVerifyTime\">cacheVerifyTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">The time that sonic begin verify local data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html#callback-java.lang.String-\">callback(String)</a></span> - 接口 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicDiffDataCallback</a></dt>\n<dd>\n<div class=\"block\">Called when sonic processes the local data and the server data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#canDestroy--\">canDestroy()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#CHROME_FILE_THREAD\">CHROME_FILE_THREAD</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Name of chrome file thread</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#cleanCache--\">cleanCache()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Removes all of the cache from <a href=\"com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>SonicEngine.preloadSessionPool</code></a> and deletes file caches from SDCard.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#clearHistory--\">clearHistory()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#clearSessionData--\">clearSessionData()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#clearSessionData--\">clearSessionData()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_NOTIFY_RESULT\">CLIENT_MSG_NOTIFY_RESULT</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The message to record sonic mode.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#CLIENT_MSG_ON_WEB_READY\">CLIENT_MSG_ON_WEB_READY</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The message of page ready, its means page want to get the latest session data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#clientIsReady\">clientIsReady</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the client is ready.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#clientIsReload\">clientIsReload</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Indicate current session is reload or not.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#clientReady--\">clientReady()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">Notify client is ready to accept data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html#close--\">close()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dt>\n<dd>\n<div class=\"block\">Closes this input stream and releases any system resources\n associated with the stream and invoke the callback's onClose method</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a> - 程序包 com.tencent.sonic.sdk</dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a> - 程序包 com.tencent.sonic.sdk.download</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_BEGIN\">COMMON_MSG_BEGIN</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#COMMON_MSG_END\">COMMON_MSG_END</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#config\">config</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#connect--\">connect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#connect--\">connect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">Opens a communications link to the resource referenced by Sonic session</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionConnectTime\">connectionConnectTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">The http(s) connect<code>URLConnection.connect()</code> response time</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionFlowFinishTime\">connectionFlowFinishTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Sonic flow end time</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionFlowStartTime\">connectionFlowStartTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">The time sonic initiate the http(s) request</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#connectionImpl\">connectionImpl</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">A session connection implement.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#connectionImpl\">connectionImpl</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>\n<div class=\"block\">A default http connection referred to by the <code>com.tencent.sonic.sdk.SonicSession#currUrl</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#connectionRespondTime\">connectionRespondTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">The http(s) getResponseCode<code>HttpURLConnection.getResponseCode()</code> response time</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#context\">context</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">A context for this runtime, it's expected to be ApplicationContext</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html#CREATE_TABLE_SQL\">CREATE_TABLE_SQL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></dt>\n<dd>\n<div class=\"block\">The create table sql</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#createConnection--\">createConnection()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#createConnectionIntent-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">createConnectionIntent(SonicDataHelper.SessionData)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#createdTime\">createdTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The time of current session created.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\">createInstance(SonicRuntime, SonicConfig)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Create SonicEngine instance.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#createSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">createSession(String, SonicSessionConfig)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#createWebResourceResponse-java.lang.String-java.lang.String-java.io.InputStream-java.util.Map-\">createWebResourceResponse(String, String, InputStream, Map&lt;String, String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ACCEPT_DIFF\">CUSTOM_HEAD_FILED_ACCEPT_DIFF</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:accept-diff.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_CACHE_OFFLINE\">CUSTOM_HEAD_FILED_CACHE_OFFLINE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:cache-offline.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_DNS_PREFETCH\">CUSTOM_HEAD_FILED_DNS_PREFETCH</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header:dns-prefetch.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_ETAG\">CUSTOM_HEAD_FILED_ETAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:eTag.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_HTML_SHA1\">CUSTOM_HEAD_FILED_HTML_SHA1</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header: .</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_LINK\">CUSTOM_HEAD_FILED_LINK</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Response Header: Link.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_SDK_VERSION\">CUSTOM_HEAD_FILED_SDK_VERSION</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header:sdk_version.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_CHANGE\">CUSTOM_HEAD_FILED_TEMPLATE_CHANGE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:template_change.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#CUSTOM_HEAD_FILED_TEMPLATE_TAG\">CUSTOM_HEAD_FILED_TEMPLATE_TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:template_tag.</div>\n</dd>\n</dl>\n<a name=\"I:D\">\n<!--   -->\n</a>\n<h2 class=\"title\">D</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#DATA_UPDATE_BUNDLE_PARAMS_DIFF\">DATA_UPDATE_BUNDLE_PARAMS_DIFF</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#dataString\">dataString</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#DEFAULT_CHARSET\">DEFAULT_CHARSET</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">the default charset is UTF-8.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#destroy--\">destroy()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#destroy-boolean-\">destroy(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#diffDataCallback\">diffDataCallback</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#diffDataCallbackTime\">diffDataCallbackTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">The time when website try get diff data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html#disconnect--\">disconnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SonicDownloadConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#disconnect--\">disconnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#disconnect--\">disconnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">Disconnect the communications link to the resource referenced by Sonic session</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#disconnect--\">disconnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#DNS_PREFETCH_ADDRESS\">DNS_PREFETCH_ADDRESS</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP header:dns-prefetch-address <br>\n This header represents the ip address of the server.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#doSaveSonicCache-com.tencent.sonic.sdk.SonicServer-java.lang.String-\">doSaveSonicCache(SonicServer, String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html#download--\">download()</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dt>\n<dd>\n<div class=\"block\">download the resource and notify download progress</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#download-java.lang.String-java.lang.String-java.lang.String-com.tencent.sonic.sdk.download.SonicDownloadCallback-\">download(String, String, String, SonicDownloadCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>\n<div class=\"block\">start downloading one resource.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#DownloadTask--\">DownloadTask()</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:E\">\n<!--   -->\n</a>\n<h2 class=\"title\">E</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html#equals-java.lang.Object-\">equals(Object)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_BUILD_HTML_ERROR\">ERROR_CODE_BUILD_HTML_ERROR</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Build template and data to html failed</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_IOE\">ERROR_CODE_CONNECT_IOE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Http(s) connection error : IO Exception</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_NPE\">ERROR_CODE_CONNECT_NPE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Http(s) connection error : nullPointer in native</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_CONNECT_TOE\">ERROR_CODE_CONNECT_TOE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Http(s) connection error : time out</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_DATA_VERIFY_FAIL\">ERROR_CODE_DATA_VERIFY_FAIL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Verify local file failed</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MAKE_DIR_ERROR\">ERROR_CODE_MAKE_DIR_ERROR</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Failed to create sonic directory</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_MERGE_DIFF_DATA_FAIL\">ERROR_CODE_MERGE_DIFF_DATA_FAIL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Obtain difference data between server and local data failed</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SERVER_DATA_EXCEPTION\">ERROR_CODE_SERVER_DATA_EXCEPTION</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Server data exception</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SPLIT_HTML_FAIL\">ERROR_CODE_SPLIT_HTML_FAIL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Separate html to template and data failed</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_SUCCESS\">ERROR_CODE_SUCCESS</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Success</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_UNKNOWN\">ERROR_CODE_UNKNOWN</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Unknown</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#ERROR_CODE_WRITE_FILE_FAIL\">ERROR_CODE_WRITE_FILE_FAIL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">File save failed</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#expiredTime\">expiredTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></dt>\n<dd>\n<div class=\"block\">Indicates when local resource cache is expired.</div>\n</dd>\n</dl>\n<a name=\"I:F\">\n<!--   -->\n</a>\n<h2 class=\"title\">F</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_MSG_BEGIN\">FILE_THREAD_MSG_BEGIN</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE\">FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The message of saving sonic cache while server close.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED\">FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The message of saving sonic cache while session finish.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#fileHandler\">fileHandler</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#fileHandlerThread\">fileHandlerThread</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">This handle thread use to save sonic cache.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#finalMode\">finalMode</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Sonic final mode<a href=\"com/tencent/sonic/sdk/SonicSession.html#finalResultCode\"><code>SonicSession.finalResultCode</code></a></div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#finalResultCode\">finalResultCode</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic final mode.</div>\n</dd>\n</dl>\n<a name=\"I:G\">\n<!--   -->\n</a>\n<h2 class=\"title\">G</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html#getAllResourceDataColumn--\">getAllResourceDataColumn()</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html#getCacheData-com.tencent.sonic.sdk.SonicSession-\">getCacheData(SonicSession)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getCacheHeaders--\">getCacheHeaders()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Get header info from local cache headers</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders--\">getCharsetFromHeaders()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Get the charset from the latest response http header.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getCharsetFromHeaders-java.util.Map-\">getCharsetFromHeaders(Map&lt;String, String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#getConfig--\">getConfig()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#getConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">getConnection(SonicSession, Intent)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getContext--\">getContext()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getCookie-java.lang.String-\">getCookie(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Get cookies of the input url, this method will be called before sonic session make a\n session connection to request data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getCurrentUrl--\">getCurrentUrl()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getCurrentUserAccount--\">getCurrentUserAccount()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Get the current user account, this method will be called when makeSessionId's params is\n account related.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#getDiffData-com.tencent.sonic.sdk.SonicDiffDataCallback-\">getDiffData(SonicDiffDataCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">The page execute a java script function to invoke a native method by javascript interface,\n this callback will be called when sonic has finished diff data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getFileThreadLooper--\">getFileThreadLooper()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Return the looper of HandleThread which use to save sonic cache.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#getFilteredHeaders-java.util.Map-\">getFilteredHeaders(Map&lt;String, List&lt;String&gt;&gt;)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">Get filtered headers by session id, this method will return a map of header(k-v) which\n will not contains \"Set-Cookie\", \"Cache-Control\", \"Expires\".</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getFinalResultCode--\">getFinalResultCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#getHeaderFromLocalCache-java.lang.String-\">getHeaderFromLocalCache(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>\n<div class=\"block\">Get headers from local cache file</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getHeaders--\">getHeaders()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Get header info with the original url of current session.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getHostDirectAddress-java.lang.String-\">getHostDirectAddress(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Get the direct address of a url(host)，format as[ip:port]，the default http port is 80 and\n 443 for https.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html#getInstance--\">getInstance()</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#getInstance--\">getInstance()</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Returns a SonicEngine instance\n \n Make sure <a href=\"com/tencent/sonic/sdk/SonicEngine.html#createInstance-com.tencent.sonic.sdk.SonicRuntime-com.tencent.sonic.sdk.SonicConfig-\"><code>SonicEngine.createInstance(SonicRuntime, SonicConfig)</code></a> has been called.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#getMD5-java.lang.String-\">getMD5(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#getMime-java.lang.String-\">getMime(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">Get mime type for url simply.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getQueryParameterNames-android.net.Uri-\">getQueryParameterNames(Uri)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Returns a set of the unique names of all query parameters.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCache-java.lang.String-\">getResourceCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></dt>\n<dd>\n<div class=\"block\">get the cached content according to the url</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#getResourceCache-java.lang.String-\">getResourceCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html#getResourceCacheHeader-java.lang.String-\">getResourceCacheHeader(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></dt>\n<dd>\n<div class=\"block\">get the cached response headers according to the url</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#getResourceCacheHeader-java.lang.String-\">getResourceCacheHeader(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html#getResourceData-java.lang.String-\">getResourceData(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></dt>\n<dd>\n<div class=\"block\">Get sonic ResourceData by unique resource id</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getResponseCode--\">getResponseCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseCode--\">getResponseCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseCode--\">getResponseCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getResponseData-boolean-\">getResponseData(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">Return current cached server response data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseHeaderField-java.lang.String-\">getResponseHeaderField(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getResponseHeaderFields--\">getResponseHeaderFields()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">return response headers which contains response headers from server and custom response headers from\n  <code>com.tencent.sonic.sdk.SonicSessionConfig</code>\n  note: server response headers have high priority than custom headers!</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseHeaderFields--\">getResponseHeaderFields()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#getResponseHeaderFields--\">getResponseHeaderFields()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getResponseStream-java.util.concurrent.atomic.AtomicBoolean-\">getResponseStream(AtomicBoolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">Read all of data from <a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\"><code>SonicSessionConnection.getResponseStream()</code></a> into byte array output stream <code>outputStream</code> until\n <code>breakCondition</code> is true when <code>breakCondition</code> is not null.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#getResponseStream--\">getResponseStream()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#getRuntime--\">getRuntime()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getSessionClient--\">getSessionClient()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#getSHA1-byte:A-\">getSHA1(byte[])</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getSonicCacheDir--\">getSonicCacheDir()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getSonicResourceCacheDir--\">getSonicResourceCacheDir()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">The resource cache root dir which resource cache will be storage.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#getSonicResourceHeaderPath-java.lang.String-\">getSonicResourceHeaderPath(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#getSonicResourcePath-java.lang.String-\">getSonicResourcePath(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#getSonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">getSonicSessionConnection(SonicSession, Intent)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getSonicSharedPreferences--\">getSonicSharedPreferences()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">get SharedPreferences of sonic.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getSrcResultCode--\">getSrcResultCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#getSrcResultCode--\">getSrcResultCode()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#getStatistics--\">getStatistics()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html#getSubResourceCache--\">getSubResourceCache()</a></span> - 类 中的静态方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getTemplate--\">getTemplate()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#getUpdatedData--\">getUpdatedData()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>\n<div class=\"block\">If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#getUserAgent--\">getUserAgent()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Get user agent of current runtime, this method will be called before sonic session make a\n session connection to request data.</div>\n</dd>\n</dl>\n<a name=\"I:H\">\n<!--   -->\n</a>\n<h2 class=\"title\">H</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_Connection-boolean-com.tencent.sonic.sdk.SonicDataHelper.SessionData-\">handleFlow_Connection(boolean, SonicDataHelper.SessionData)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Initiate a network request to obtain server data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>\n<div class=\"block\">In this case sonic obtains the difference data between the server and the local\n data first,then sonic will build the template and server data into html,\n then send a <code>CLIENT_CORE_MSG_DATA_UPDATE</code> message.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Handle data update <a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\"><code>SonicSession.SONIC_RESULT_CODE_DATA_UPDATE</code></a> logic.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_DataUpdate-java.lang.String-\">handleFlow_DataUpdate(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic obtains the difference data between the server and the local data first,then sonic will\n build the template and server data into html.If client did not load url before, the new html\n will be encapsulated as an inputStream<code>ByteArrayInputStream</code>,When client initiates\n a resource interception, sonic provides the inputStream to the kernel.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>\n<div class=\"block\">In this case sonic will always read the new data from the server until the client\n initiates a resource interception.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Handle sonic first <a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\"><code>SonicSession.SONIC_RESULT_CODE_FIRST_LOAD</code></a> logic.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_FirstLoad--\">handleFlow_FirstLoad()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic will always read the new data from the server until client initiates a resource interception\n If the server data is not read finished sonic will split the read and unread data into a\n bridgedStream<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><code>SonicSessionStream</code></a>, otherwise all the read data will be encapsulated as an\n inputStream<code>ByteArrayInputStream</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_HttpError-int-\">handleFlow_HttpError(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>\n<div class=\"block\">Handle load local cache of html if exist.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_LoadLocalCache-java.lang.String-\">handleFlow_LoadLocalCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_NotModified--\">handleFlow_NotModified()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_ServiceUnavailable--\">handleFlow_ServiceUnavailable()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>\n<div class=\"block\">In this case sonic will always read the new data from the server until the local page finish.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Handle template update <a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\"><code>SonicSession.SONIC_RESULT_CODE_TEMPLATE_CHANGE</code></a> logic.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleFlow_TemplateChange-java.lang.String-\">handleFlow_TemplateChange(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic will always read the new data from the server until the local page finish.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#handleMessage-android.os.Message-\">handleMessage(Message)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#handleMessage-android.os.Message-\">handleMessage(Message)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#handleMessage-android.os.Message-\">handleMessage(Message)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Subclasses must implement this to receive messages.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#handleMessage-android.os.Message-\">handleMessage(Message)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP\">HTTP_HEAD_CSP</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header：Content-Security-Policy.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_CSP_REPORT_ONLY\">HTTP_HEAD_CSP_REPORT_ONLY</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header：Content-Security-Policy-Report-Only.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CACHE_CONTROL\">HTTP_HEAD_FIELD_CACHE_CONTROL</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header : Cache-Control.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_LENGTH\">HTTP_HEAD_FIELD_CONTENT_LENGTH</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header : Content-Length.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_CONTENT_TYPE\">HTTP_HEAD_FIELD_CONTENT_TYPE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header : Content-Type.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_COOKIE\">HTTP_HEAD_FIELD_COOKIE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Request Header : Cookie.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_EXPIRES\">HTTP_HEAD_FIELD_EXPIRES</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header : Expires.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FIELD_PRAGMA\">HTTP_HEAD_FIELD_PRAGMA</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP 1.0 Header : Pragma.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_IF_NOT_MATCH\">HTTP_HEAD_FILED_IF_NOT_MATCH</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_SET_COOKIE\">HTTP_HEAD_FILED_SET_COOKIE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Header：Set-Cookie.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#HTTP_HEAD_FILED_USER_AGENT\">HTTP_HEAD_FILED_USER_AGENT</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">HTTP Request Header：User-Agent.</div>\n</dd>\n</dl>\n<a name=\"I:I\">\n<!--   -->\n</a>\n<h2 class=\"title\">I</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#id\">id</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#initConnection-java.net.URLConnection-\">initConnection(URLConnection)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#initSonicDB--\">initSonicDB()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Init sonic DB which will upgrade to new version of database.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#intent\">intent</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#intent\">intent</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">This intent saves all of the initialization param.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#internalConnect--\">internalConnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#internalConnect--\">internalConnect()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#internalGetResponseStream--\">internalGetResponseStream()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#internalGetResponseStream--\">internalGetResponseStream()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isDestroyedOrWaitingForDestroy--\">isDestroyedOrWaitingForDestroy()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#isDirectAddress\">isDirectAddress</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Is IP direct</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#isGetInstanceAllowed--\">isGetInstanceAllowed()</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Check if <a href=\"com/tencent/sonic/sdk/SonicEngine.html#getInstance--\"><code>SonicEngine.getInstance()</code></a> is ready or not.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isMatchCurrentUrl-java.lang.String-\">isMatchCurrentUrl(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the incoming url matches the current url,it will\n ignore url parameters</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#isNetworkValid--\">isNetworkValid()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">This method is used to judge is network valid or not</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isPreload\">isPreload</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether current session is preload.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isPreload--\">isPreload()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#isSonicAvailable--\">isSonicAvailable()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Whether Sonic Service is available or not</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#isSonicUrl-java.lang.String-\">isSonicUrl(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">This method is used to judge the input url is support sonic or not, when this method return\n true, it means it's allow to create a sonic session for this url.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html#isUpgrading--\">isUpgrading()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></dt>\n<dd>\n<div class=\"block\">Indicates whether is upgrading or not.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isWaitingForDestroy\">isWaitingForDestroy</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the session is waiting for destroy.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isWaitingForSaveFile\">isWaitingForSaveFile</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether it is waiting for the file to be saved.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#isWaitingForSessionThread\">isWaitingForSessionThread</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the session is waiting for data.</div>\n</dd>\n</dl>\n<a name=\"I:L\">\n<!--   -->\n</a>\n<h2 class=\"title\">L</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrl-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-\">loadDataWithBaseUrl(String, String, String, String, String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#loadDataWithBaseUrlAndHeader-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.lang.String-java.util.HashMap-\">loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap&lt;String, String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#loadUrl-java.lang.String-android.os.Bundle-\">loadUrl(String, Bundle)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">We add this method to decoupling webview since some application may use x5 webview or others.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#log-java.lang.String-int-java.lang.String-\">log(String, int, String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#log-java.lang.String-int-java.lang.String-\">log(String, int, String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">Logger function</div>\n</dd>\n</dl>\n<a name=\"I:M\">\n<!--   -->\n</a>\n<h2 class=\"title\">M</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#mainHandler\">mainHandler</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#makeSessionId-java.lang.String-boolean-\">makeSessionId(String, boolean)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Create session ID</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#makeSessionId-java.lang.String-boolean-\">makeSessionId(String, boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Make a unique session id for the url, it can be account related.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mCallbacks\">mCallbacks</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">list of download callback</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mCookie\">mCookie</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">cookie to be set in the http download request</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mInputStream\">mInputStream</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the network stream or memory stream or the bridge stream</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mIpAddress\">mIpAddress</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">ip address instead of host to launch a http request</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mResourceUrl\">mResourceUrl</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">url of the resource to be download</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mRspHeaders\">mRspHeaders</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the download request's response headers</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mState\">mState</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the task's download state</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#mWasInterceptInvoked\">mWasInterceptInvoked</a></span> - 类 中的变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">whether the task's responding resource was intercepted by kernel</div>\n</dd>\n</dl>\n<a name=\"I:N\">\n<!--   -->\n</a>\n<h2 class=\"title\">N</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html#next--\">next()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#notifyError-com.tencent.sonic.sdk.SonicSessionClient-java.lang.String-int-\">notifyError(SonicSessionClient, String, int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Notify error for host application to do report or statics</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#notifyStateChange-int-int-android.os.Bundle-\">notifyStateChange(int, int, Bundle)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">When the session state changes, notify the listeners.</div>\n</dd>\n</dl>\n<a name=\"I:O\">\n<!--   -->\n</a>\n<h2 class=\"title\">O</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_FALSE\">OFFLINE_MODE_FALSE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_HTTP\">OFFLINE_MODE_HTTP</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_STORE\">OFFLINE_MODE_STORE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#OFFLINE_MODE_TRUE\">OFFLINE_MODE_TRUE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The value of \"cache-offline\" in http(s) response headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onClientPageFinished-java.lang.String-\">onClientPageFinished(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#onClientReady--\">onClientReady()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onClientReady--\">onClientReady()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Client informs sonic that it is ready.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#onClientReady--\">onClientReady()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onClientRequestResource-java.lang.String-\">onClientRequestResource(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">When the webview initiates a resource interception, the client invokes the method to retrieve the data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose(boolean, ByteArrayOutputStream)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose(boolean, ByteArrayOutputStream)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html#onClose-boolean-java.io.ByteArrayOutputStream-\">onClose(boolean, ByteArrayOutputStream)</a></span> - 接口 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a></dt>\n<dd>\n<div class=\"block\">Close callback</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html#onCreate-android.database.sqlite.SQLiteDatabase-\">onCreate(SQLiteDatabase)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></dt>\n<dd>\n<div class=\"block\">Called when the database is created for the first time.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onError-int-\">onError(int)</a></span> - 接口 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dt>\n<dd>\n<div class=\"block\">notify download failed.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onError-int-\">onError(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onError-int-\">onError(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onFinish--\">onFinish()</a></span> - 接口 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dt>\n<dd>\n<div class=\"block\">notify download finish.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onFinish--\">onFinish()</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onProgress-int-int-\">onProgress(int, int)</a></span> - 接口 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dt>\n<dd>\n<div class=\"block\">notify the download progress.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onProgress-int-int-\">onProgress(int, int)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#onRequestResource-java.lang.String-\">onRequestResource(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onRequestResource-java.lang.String-\">onRequestResource(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">When the webview initiates a main resource interception, the client invokes this method to retrieve the data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#onRequestResource-java.lang.String-\">onRequestResource(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#onRequestSubResource-java.lang.String-com.tencent.sonic.sdk.SonicSession-\">onRequestSubResource(String, SonicSession)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>\n<div class=\"block\">When the webview initiates a sub resource interception, the client invokes this method to retrieve the data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onServerClosed-com.tencent.sonic.sdk.SonicServer-boolean-\">onServerClosed(SonicServer, boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">If the kernel obtain inputStream from a <code>SonicSessionStream</code>, the inputStream\n will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream\n close.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html#onSessionStateChange-com.tencent.sonic.sdk.SonicSession-int-int-android.os.Bundle-\">onSessionStateChange(SonicSession, int, int, Bundle)</a></span> - 接口 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSession.Callback</a></dt>\n<dd>\n<div class=\"block\">When the session's state changes, this method will be invoked.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onStart--\">onStart()</a></span> - 接口 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dt>\n<dd>\n<div class=\"block\">notify the download start.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onStart--\">onStart()</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onStart--\">onStart()</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess(byte[], Map&lt;String, List&lt;String&gt;&gt;)</a></span> - 接口 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a></dt>\n<dd>\n<div class=\"block\">notify download success.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess(byte[], Map&lt;String, List&lt;String&gt;&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#onSuccess-byte:A-java.util.Map-\">onSuccess(byte[], Map&lt;String, List&lt;String&gt;&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html#onUpgrade-android.database.sqlite.SQLiteDatabase-int-int-\">onUpgrade(SQLiteDatabase, int, int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicDBHelper</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady(SonicDiffDataCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">QuickSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady(SonicDiffDataCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Client will call this method to obtain the update data when the page shows the content.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html#onWebReady-com.tencent.sonic.sdk.SonicDiffDataCallback-\">onWebReady(SonicDiffDataCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">StandardSonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#originalMode\">originalMode</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Sonic original mode<a href=\"com/tencent/sonic/sdk/SonicSession.html#srcResultCode\"><code>SonicSession.srcResultCode</code></a></div>\n</dd>\n</dl>\n<a name=\"I:P\">\n<!--   -->\n</a>\n<h2 class=\"title\">P</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#pageFinish-java.lang.String-\">pageFinish(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">We need to tell the session when onPageFinished is called by WebViewClient since to make a\n better reload when current hit template-changed case.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#pendingDiffData\">pendingDiffData</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The difference data between local and server data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#pendingWebResourceStream\">pendingWebResourceStream</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The response for client interception.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#postForceDestroyIfNeed--\">postForceDestroyIfNeed()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Destroy the session if it is waiting for destroy and it is can be destroyed.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#postTaskToMainThread-java.lang.Runnable-long-\">postTaskToMainThread(Runnable, long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Post a task in main thread</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#postTaskToSaveSonicCache-java.lang.String-\">postTaskToSaveSonicCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#postTaskToSessionThread-java.lang.Runnable-\">postTaskToSessionThread(Runnable)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Post a task to session thread(a high priority thread is better)</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#postTaskToThread-java.lang.Runnable-long-\">postTaskToThread(Runnable, long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Post a task to the thread(a io thread is better) which used to separate template and data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#preCreateSession-java.lang.String-com.tencent.sonic.sdk.SonicSessionConfig-\">preCreateSession(String, SonicSessionConfig)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">This method will preCreate sonic session .</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#preloadLinks\">preloadLinks</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:Q\">\n<!--   -->\n</a>\n<h2 class=\"title\">Q</h2>\n<dl>\n<dt><a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">QuickSonicSession</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">A subclass of SonicSession.</div>\n</dd>\n</dl>\n<a name=\"I:R\">\n<!--   -->\n</a>\n<h2 class=\"title\">R</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html#read--\">read()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dt>\n<dd>\n<div class=\"block\">\n Reads a single byte from this stream and returns it as an integer in the\n range from 0 to 255.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html#read-byte:A-\">read(byte[])</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dt>\n<dd>\n<div class=\"block\">Reads a byte of data from this input stream\n Equivalent to <code>read(buffer, 0, buffer.length)</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html#read-byte:A-int-int-\">read(byte[], int, int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dt>\n<dd>\n<div class=\"block\">Reads up to <code>byteCount</code> bytes from this stream and stores them in\n the byte array <code>buffer</code> starting at <code>byteOffset</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#readFileToBytes-java.io.File-\">readFileToBytes(File)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#refresh--\">refresh()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#removeResourceCache-java.lang.String-\">removeResourceCache(String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">Remove a unique resource cache.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#removeSessionCache-java.lang.String-\">removeSessionCache(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">Removes the sessionId and its corresponding SonicSession from <a href=\"com/tencent/sonic/sdk/SonicEngine.html#preloadSessionPool\"><code>SonicEngine.preloadSessionPool</code></a>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#removeSessionCallback-com.tencent.sonic.sdk.SonicSessionCallback-\">removeSessionCallback(SonicSessionCallback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#removeSessionStateChangedCallback-com.tencent.sonic.sdk.SonicSession.Callback-\">removeSessionStateChangedCallback(SonicSession.Callback)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#requestIntent\">requestIntent</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#requestResource-java.lang.String-\">requestResource(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>\n<div class=\"block\">Webview ask the host client to intercept request, this method should be called when webview\n call shouldInterceptRequest.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#reset--\">reset()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></dt>\n<dd>\n<div class=\"block\">Reset data</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD\">RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Resource Intercept State : intercepting in file thread</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD\">RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Resource Intercept State : intercepting in other thread(may be IOThread or other else)</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#RESOURCE_INTERCEPT_STATE_NONE\">RESOURCE_INTERCEPT_STATE_NONE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Resource Intercept State : none</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#ResourceData--\">ResourceData()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#resourceDownloaderEngine\">resourceDownloaderEngine</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic sub resource downloader</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#resourceInterceptState\">resourceInterceptState</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Resource intercept state, include <code>RESOURCE_INTERCEPT_STATE_NONE</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</code>,\n <code>RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</code>\n More about it at {https://codereview.chromium.org/1350553005/#ps20001}</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#resourceSha1\">resourceSha1</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></dt>\n<dd>\n<div class=\"block\">The sha1 of resource</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html#resourceSize\">resourceSize</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper.ResourceData</a></dt>\n<dd>\n<div class=\"block\">The size of resource</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#responseCode\">responseCode</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#responseStream\">responseStream</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">The input stream that reads from this open connection.</div>\n</dd>\n</dl>\n<a name=\"I:S\">\n<!--   -->\n</a>\n<h2 class=\"title\">S</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#saveResourceFiles-java.lang.String-byte:A-java.util.Map-\">saveResourceFiles(String, byte[], Map&lt;String, List&lt;String&gt;&gt;)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">save resource files, including resource and headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#saveSonicResourceData-java.lang.String-java.lang.String-long-\">saveSonicResourceData(String, String, long)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">save resource data to database, such as resource sha1, resource size etc.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#separateTemplateAndData--\">separateTemplateAndData()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#server\">server</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic server</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#serverRsp\">serverRsp</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#session\">session</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#session\">session</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">SonicSession Object used by SonicSessionConnection.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_DEFAULT\">SESSION_MODE_DEFAULT</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">SonicSession mode : StandardSonicSession</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SESSION_MODE_QUICK\">SESSION_MODE_QUICK</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">SonicSession mode : QuickSonicSession</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SESSION_MSG_FORCE_DESTROY\">SESSION_MSG_FORCE_DESTROY</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The message of forced to destroy the session.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#sessionCallbackList\">sessionCallbackList</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#sessionClient\">sessionClient</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html#SessionConnectionDefaultImpl-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SessionConnectionDefaultImpl(SonicSession, Intent)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection.SessionConnectionDefaultImpl</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#sessionState\">sessionState</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session state, include <code>STATE_NONE</code>, <code>STATE_RUNNING</code>,\n <code>STATE_READY</code> and <code>STATE_DESTROY</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setAcceptDiff-boolean-\">setAcceptDiff(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setAutoInitDBWhenCreate-boolean-\">setAutoInitDBWhenCreate(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setAutoStartWhenCreate-boolean-\">setAutoStartWhenCreate(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheCheckTimeInterval-long-\">setCacheCheckTimeInterval(long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">setCacheInterceptor(SonicCacheInterceptor)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheMaxSize-long-\">setCacheMaxSize(long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setCacheVerifyWithSha1-boolean-\">setCacheVerifyWithSha1(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setConnectionInterceptor-com.tencent.sonic.sdk.SonicSessionConnectionInterceptor-\">setConnectionInterceptor(SonicSessionConnectionInterceptor)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setConnectTimeoutMillis-int-\">setConnectTimeoutMillis(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#setCookie-java.lang.String-java.util.List-\">setCookie(String, List&lt;String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Set cookies to webview after session connection response with cookies in it's headers.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#setCookiesFromHeaders-java.util.Map-boolean-\">setCookiesFromHeaders(Map&lt;String, List&lt;String&gt;&gt;, boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Set cookies to webview from headers</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCustomRequestHeaders-java.util.Map-\">setCustomRequestHeaders(Map&lt;String, String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setCustomResponseHeaders-java.util.Map-\">setCustomResponseHeaders(Map&lt;String, String&gt;)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setGetCookieWhenSessionCreate-boolean-\">setGetCookieWhenSessionCreate(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setIsAccountRelated-boolean-\">setIsAccountRelated(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setMaxNumOfDownloadingTasks-int-\">setMaxNumOfDownloadingTasks(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setMaxPreloadSessionCount-int-\">setMaxPreloadSessionCount(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setPreloadSessionExpiredTimeMillis-long-\">setPreloadSessionExpiredTimeMillis(long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReadBufferSize-int-\">setReadBufferSize(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReadTimeoutMillis-int-\">setReadTimeoutMillis(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setReloadInBadNetwork-boolean-\">setReloadInBadNetwork(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setResourceCacheMaxSize-long-\">setResourceCacheMaxSize(long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#setResult-int-int-boolean-\">setResult(int, int, boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Record the sonic mode, notify the result to page if necessary.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSessionMode-int-\">setSessionMode(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setSonicCacheMaxAge-int-\">setSonicCacheMaxAge(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSupportCacheControl-boolean-\">setSupportCacheControl(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setSupportLocalServer-boolean-\">setSupportLocalServer(boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html#setUnavailableTime-long-\">setUnavailableTime(long)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html#setUseSonicCacheInBadNetworkToastMessage-java.lang.String-\">setUseSonicCacheInBadNetworkToastMessage(String)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConfig.Builder</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#shouldLog-int-\">shouldLog(int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Logger function</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#shouldLog-int-\">shouldLog(int)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>\n<div class=\"block\">Logger function</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#shouldSetCookieAsynchronous--\">shouldSetCookieAsynchronous()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether should set cookie asynchronous or not , if <code>onClientRequestResource</code> is calling\n in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may\n cause deadlock\n More about it see {https://issuetracker.google.com/issues/36989494#c8}\n Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#showToast-java.lang.CharSequence-int-\">showToast(CharSequence, int)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>\n<div class=\"block\">Show toast</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#sId\">sId</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The integer id of current session</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html#SimpleDownloadCallback--\">SimpleDownloadCallback()</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCallback.SimpleDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#sNextSessionLogId\">sNextSessionLogId</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Log id</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.html#SONIC_MAX_NUM_OF_DOWNLOADING_TASK\">SONIC_MAX_NUM_OF_DOWNLOADING_TASK</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></dt>\n<dd>\n<div class=\"block\">The max number of tasks which is downloading in the same time.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_PARAMETER_NAME_PREFIX\">SONIC_PARAMETER_NAME_PREFIX</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">Sonic parameter prefix</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_NAMES\">SONIC_REMAIN_PARAMETER_NAMES</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">This parameter in url will be as part of session id，and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_REMAIN_PARAMETER_SPLIT_CHAR\">SONIC_REMAIN_PARAMETER_SPLIT_CHAR</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_DATA_UPDATE\">SONIC_RESULT_CODE_DATA_UPDATE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic mode : data update.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_FIRST_LOAD\">SONIC_RESULT_CODE_FIRST_LOAD</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic mode : first load.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_HIT_CACHE\">SONIC_RESULT_CODE_HIT_CACHE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic mode : 304.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_TEMPLATE_CHANGE\">SONIC_RESULT_CODE_TEMPLATE_CHANGE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic mode : template change.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#SONIC_RESULT_CODE_UNKNOWN\">SONIC_RESULT_CODE_UNKNOWN</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic mode : unknown.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_SDK_LOG_PREFIX\">SONIC_SDK_LOG_PREFIX</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">SonicSDK log prefix</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SONIC_VERSION_NUM\">SONIC_VERSION_NUM</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>\n<div class=\"block\">SonicSDK version</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicCacheInterceptor</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\"><code>SonicCacheInterceptor</code> provide local data.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html#SonicCacheInterceptor-com.tencent.sonic.sdk.SonicCacheInterceptor-\">SonicCacheInterceptor(SonicCacheInterceptor)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Sonic global config</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig.Builder</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Builder for SonicConfig</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConstants</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Sonic constants</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConstants.html#SonicConstants--\">SonicConstants()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConstants</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicDBHelper</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">SonicDBHelper interacts with the database, such as managing database creation and\n the version management.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicDiffDataCallback</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的接口</dt>\n<dd>\n<div class=\"block\">This interface is used to call the difference data between local and server data\n to the client.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">Sonic download cache manager</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html#SonicDownloadCache--\">SonicDownloadCache()</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache.SonicResourceCache</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">An sub resource cache implementation <a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><code>SonicDownloadCache</code></a></div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">SonicDownloadCallback</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的接口</dt>\n<dd>\n<div class=\"block\">download callback.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCallback.SimpleDownloadCallback</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">an empty implementation of <a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><code>SonicDownloadCallback</code></a></div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">Handles a single HTTP resource download</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html#SonicDownloadClient-com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask-\">SonicDownloadClient(SonicDownloadClient.DownloadTask)</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.DownloadTask</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">Task which record the download info</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SonicDownloadConnection</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SubResourceDownloadCallback</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">sub resource download callback.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html#SonicDownloadConnection-java.lang.String-\">SonicDownloadConnection(String)</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SonicDownloadConnection</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadEngine</span></a> - <a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a>中的类</dt>\n<dd>\n<div class=\"block\">an download initiator</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#SonicDownloadEngine-com.tencent.sonic.sdk.download.SonicDownloadCache-\">SonicDownloadEngine(SonicDownloadCache)</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicEngine</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Interacts with the overall SonicSessions running in the system.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicFileUtils</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Interact with the overall file operations.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#SonicFileUtils--\">SonicFileUtils()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#sonicFlowStartTime\">sonicFlowStartTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Sonic flow start<a href=\"com/tencent/sonic/sdk/SonicSession.html#runSonicFlow-boolean-\"><code>SonicSession.runSonicFlow(boolean)</code></a> time</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#SonicResourceCache--\">SonicResourceCache()</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">SonicResourceDataHelper manages the resource database.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html#SonicResourceDataHelper--\">SonicResourceDataHelper()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\">SonicResourceDataHelper</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper.ResourceData</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">resource data structure</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicRuntime</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\"><code>SonicRuntime</code> is a class which interacts with the overall running information in the system,\n including Context, UA, ID (which is the unique identification for the saved data) and other information.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicRuntime.html#SonicRuntime-android.content.Context-\">SonicRuntime(Context)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\">SonicRuntime</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicServer</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Instances of this class can be used to read server response from SonicSessionConnection.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#SonicServer-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SonicServer(SonicSession, Intent)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSession</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">In Sonic, <code>SonicSession</code>s are used to manage the entire process,include\n obtain the latest data from the server, provide local and latest\n data to kernel, separate html to template and data, build template\n and data to html and so on.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSession.Callback</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的接口</dt>\n<dd>\n<div class=\"block\">The interface is used to inform the listeners that the state of the\n session has changed.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionClient</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\"><code>SonicSessionClient</code> is a thin API class that delegates its public API to\n a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionClient.html#SonicSessionClient--\">SonicSessionClient()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionClient</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">The sonicSession configurations.</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig.Builder</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Builder for SonicSessionConfig</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">The abstract class <code>SonicSessionConnection</code> is the superclass\n of all classes that represent a communications link between the\n application and a URL.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html#SonicSessionConnection-com.tencent.sonic.sdk.SonicSession-android.content.Intent-\">SonicSessionConnection(SonicSession, Intent)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnection</a></dt>\n<dd>\n<div class=\"block\">Constructor</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection.SessionConnectionDefaultImpl</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnectionInterceptor</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\"><code>SonicSessionConnectionInterceptor</code> provide a <code>SonicSessionConnection</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html#SonicSessionConnectionInterceptor--\">SonicSessionConnectionInterceptor()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionConnectionInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStatistics</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">The Statistic model specifies the data models which are required to be used to provide\n the performance data described by the specific attributes in a SonicSession.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#SonicSessionStatistics--\">SonicSessionStatistics()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStream</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">A <code>SonicSessionStream</code> obtains input bytes\n from a <code>memStream</code> and a <code>netStream</code>.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStream.html#SonicSessionStream-com.tencent.sonic.sdk.SonicSessionStream.Callback-java.io.ByteArrayOutputStream-java.io.BufferedInputStream-\">SonicSessionStream(SonicSessionStream.Callback, ByteArrayOutputStream, BufferedInputStream)</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStream</a></dt>\n<dd>\n<div class=\"block\">Constructor</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSessionStream.Callback</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的接口</dt>\n<dd>\n<div class=\"block\">When <code>SonicSessionStream</code> close the stream will invoke the <code>Callback</code></div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#sonicStartTime\">sonicStartTime</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Sonic start <a href=\"com/tencent/sonic/sdk/SonicSession.html#start--\"><code>SonicSession.start()</code></a> time</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicUtils</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">Sonic Utils</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicUtils.html#SonicUtils--\">SonicUtils()</a></span> - 类 的构造器com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicUtils</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#srcResultCode\">srcResultCode</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Sonic original mode.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#srcUrl\">srcUrl</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The original url</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html#srcUrl\">srcUrl</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSessionStatistics</a></dt>\n<dd>\n<div class=\"block\">Original url</div>\n</dd>\n<dt><a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">StandardSonicSession</span></a> - <a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a>中的类</dt>\n<dd>\n<div class=\"block\">A subclass of SonicSession.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#start--\">start()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Start the sonic process</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_DESTROY\">STATE_DESTROY</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session state : destroyed.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADED\">STATE_DOWNLOADED</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the task is in download complete state.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_DOWNLOADING\">STATE_DOWNLOADING</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the task is in downloading state.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_INITIATE\">STATE_INITIATE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">download in initiate state.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_LOAD_FROM_CACHE\">STATE_LOAD_FROM_CACHE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">the task is load from cache, not from network.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_NONE\">STATE_NONE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session state : original.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html#STATE_QUEUEING\">STATE_QUEUEING</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.DownloadTask</a></dt>\n<dd>\n<div class=\"block\">download in queueing state.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_READY\">STATE_READY</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session state : ready.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#STATE_RUNNING\">STATE_RUNNING</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session state : running.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#stateChangedCallbackList\">stateChangedCallbackList</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#statistics\">statistics</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Session statics var</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html#SubResourceDownloadCallback-java.lang.String-\">SubResourceDownloadCallback(String)</a></span> - 类 的构造器com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient.SubResourceDownloadCallback</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#switchState-int-int-boolean-\">switchState(int, int, boolean)</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:T\">\n<!--   -->\n</a>\n<h2 class=\"title\">T</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadCache.SonicResourceCache</a></dt>\n<dd>\n<div class=\"block\">log filter</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadClient</a></dt>\n<dd>\n<div class=\"block\">log filter</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\">SonicDownloadEngine</a></dt>\n<dd>\n<div class=\"block\">log filter</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\">SonicCacheInterceptor</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#TAG\">TAG</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Log filter</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicServer.html#templateString\">templateString</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\">SonicServer</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicEngine.html#trimSonicCache--\">trimSonicCache()</a></span> - 类 中的方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\">SonicEngine</a></dt>\n<dd>\n<div class=\"block\">It will Post a task to trim sonic cache\n if the last time of check sonic cache exceed <a href=\"com/tencent/sonic/sdk/SonicConfig.html#SONIC_CACHE_CHECK_TIME_INTERVAL\"><code>SonicConfig.SONIC_CACHE_CHECK_TIME_INTERVAL</code></a>.</div>\n</dd>\n</dl>\n<a name=\"I:V\">\n<!--   -->\n</a>\n<h2 class=\"title\">V</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicConfig.html#VERIFY_CACHE_FILE_WITH_SHA1\">VERIFY_CACHE_FILE_WITH_SHA1</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\">SonicConfig</a></dt>\n<dd>\n<div class=\"block\">Whether verify file by compare SHA1.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicFileUtils.html#verifyData-byte:A-java.lang.String-\">verifyData(byte[], String)</a></span> - 类 中的静态方法com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\">SonicFileUtils</a></dt>\n<dd>\n<div class=\"block\">This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.</div>\n</dd>\n</dl>\n<a name=\"I:W\">\n<!--   -->\n</a>\n<h2 class=\"title\">W</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#wasInterceptInvoked\">wasInterceptInvoked</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the client initiates a resource interception.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#wasOnPageFinishInvoked\">wasOnPageFinishInvoked</a></span> - 类 中的变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">Whether the local html is loaded, it is used only the template changes.</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_CODE\">WEB_RESPONSE_CODE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The result keyword to page : the value is <code>finalResultCode</code></div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_DATA\">WEB_RESPONSE_DATA</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The all data keyword to page</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_EXTRA\">WEB_RESPONSE_EXTRA</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_LOCAL_REFRESH_TIME\">WEB_RESPONSE_LOCAL_REFRESH_TIME</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/tencent/sonic/sdk/SonicSession.html#WEB_RESPONSE_SRC_CODE\">WEB_RESPONSE_SRC_CODE</a></span> - 类 中的静态变量com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\">SonicSession</a></dt>\n<dd>\n<div class=\"block\">The result keyword to page : the value is <code>srcResultCode</code></div>\n</dd>\n</dl>\n<a href=\"#I:A\">A</a>&nbsp;<a href=\"#I:B\">B</a>&nbsp;<a href=\"#I:C\">C</a>&nbsp;<a href=\"#I:D\">D</a>&nbsp;<a href=\"#I:E\">E</a>&nbsp;<a href=\"#I:F\">F</a>&nbsp;<a href=\"#I:G\">G</a>&nbsp;<a href=\"#I:H\">H</a>&nbsp;<a href=\"#I:I\">I</a>&nbsp;<a href=\"#I:L\">L</a>&nbsp;<a href=\"#I:M\">M</a>&nbsp;<a href=\"#I:N\">N</a>&nbsp;<a href=\"#I:O\">O</a>&nbsp;<a href=\"#I:P\">P</a>&nbsp;<a href=\"#I:Q\">Q</a>&nbsp;<a href=\"#I:R\">R</a>&nbsp;<a href=\"#I:S\">S</a>&nbsp;<a href=\"#I:T\">T</a>&nbsp;<a href=\"#I:V\">V</a>&nbsp;<a href=\"#I:W\">W</a>&nbsp;</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li class=\"navBarCell1Rev\">索引</li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?index-all.html\" target=\"_top\">框架</a></li>\n<li><a href=\"index-all.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/index.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>sdk 3.0.0 API</title>\n<script type=\"text/javascript\">\n    tmpTargetPage = \"\" + window.location.search;\n    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n        tmpTargetPage = tmpTargetPage.substring(1);\n    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n        tmpTargetPage = \"undefined\";\n    targetPage = tmpTargetPage;\n    function validURL(url) {\n        try {\n            url = decodeURIComponent(url);\n        }\n        catch (error) {\n            return false;\n        }\n        var pos = url.indexOf(\".html\");\n        if (pos == -1 || pos != url.length - 5)\n            return false;\n        var allowNumber = false;\n        var allowSep = false;\n        var seenDot = false;\n        for (var i = 0; i < url.length - 5; i++) {\n            var ch = url.charAt(i);\n            if ('a' <= ch && ch <= 'z' ||\n                    'A' <= ch && ch <= 'Z' ||\n                    ch == '$' ||\n                    ch == '_' ||\n                    ch.charCodeAt(0) > 127) {\n                allowNumber = true;\n                allowSep = true;\n            } else if ('0' <= ch && ch <= '9'\n                    || ch == '-') {\n                if (!allowNumber)\n                     return false;\n            } else if (ch == '/' || ch == '.') {\n                if (!allowSep)\n                    return false;\n                allowNumber = false;\n                allowSep = false;\n                if (ch == '.')\n                     seenDot = true;\n                if (ch == '/' && seenDot)\n                     return false;\n            } else {\n                return false;\n            }\n        }\n        return true;\n    }\n    function loadFrames() {\n        if (targetPage != \"\" && targetPage != \"undefined\")\n             top.classFrame.location = top.targetPage;\n    }\n</script>\n</head>\n<frameset cols=\"20%,80%\" title=\"Documentation frame\" onload=\"top.loadFrames()\">\n<frameset rows=\"30%,70%\" title=\"Left frames\" onload=\"top.loadFrames()\">\n<frame src=\"overview-frame.html\" name=\"packageListFrame\" title=\"所有程序包\">\n<frame src=\"allclasses-frame.html\" name=\"packageFrame\" title=\"所有类和接口 (除了非静态嵌套类型)\">\n</frameset>\n<frame src=\"overview-summary.html\" name=\"classFrame\" title=\"程序包, 类和接口说明\" scrolling=\"yes\">\n<noframes>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<h2>框架预警</h2>\n<p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href=\"overview-summary.html\">非框架版本</a>。</p>\n</noframes>\n</frameset>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/overview-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>概览列表 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<div class=\"indexHeader\"><span><a href=\"allclasses-frame.html\" target=\"packageFrame\">所有类</a></span></div>\n<div class=\"indexContainer\">\n<h2 title=\"程序包\">程序包</h2>\n<ul title=\"程序包\">\n<li><a href=\"com/tencent/sonic/sdk/package-frame.html\" target=\"packageFrame\">com.tencent.sonic.sdk</a></li>\n<li><a href=\"com/tencent/sonic/sdk/download/package-frame.html\" target=\"packageFrame\">com.tencent.sonic.sdk.download</a></li>\n</ul>\n</div>\n<p>&nbsp;</p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/overview-summary.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>概览 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u6982\\u89C8 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li class=\"navBarCell1Rev\">概览</li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">sdk 3.0.0 API</h1>\n</div>\n<div class=\"contentContainer\">\n<table class=\"overviewSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"程序包表, 列表程序包和解释\">\n<caption><span>程序包</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">程序包</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"com/tencent/sonic/sdk/package-summary.html\">com.tencent.sonic.sdk</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"com/tencent/sonic/sdk/download/package-summary.html\">com.tencent.sonic.sdk.download</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n</tbody>\n</table>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li class=\"navBarCell1Rev\">概览</li>\n<li>程序包</li>\n<li>类</li>\n<li><a href=\"overview-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/overview-tree.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_152-release) on Wed Apr 18 15:55:58 CST 2018 -->\n<title>类分层结构 (sdk 3.0.0 API)</title>\n<meta name=\"date\" content=\"2018-04-18\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B\\u5206\\u5C42\\u7ED3\\u6784 (sdk 3.0.0 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">所有程序包的分层结构</h1>\n<span class=\"packageHierarchyLabel\">程序包分层结构:</span>\n<ul class=\"horizontal\">\n<li><a href=\"com/tencent/sonic/sdk/package-tree.html\">com.tencent.sonic.sdk</a>, </li>\n<li><a href=\"com/tencent/sonic/sdk/download/package-tree.html\">com.tencent.sonic.sdk.download</a></li>\n</ul>\n</div>\n<div class=\"contentContainer\">\n<h2 title=\"类分层结构\">类分层结构</h2>\n<ul>\n<li type=\"circle\">java.lang.Object\n<ul>\n<li type=\"circle\">java.io.InputStream (implements java.io.Closeable)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStream</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicCacheInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicCacheInterceptor</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConfig.Builder</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicConstants.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicConstants</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache</span></a>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCache.SonicResourceCache.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCache.SonicResourceCache</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.SimpleDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadCallback.SimpleDownloadCallback</span></a> (implements com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\">SonicDownloadCallback</a>)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SubResourceDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SubResourceDownloadCallback</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient</span></a> (implements com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.DownloadTask.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.DownloadTask</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadClient.SonicDownloadConnection.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadClient.SonicDownloadConnection</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadEngine.html\" title=\"com.tencent.sonic.sdk.download中的类\"><span class=\"typeNameLink\">SonicDownloadEngine</span></a> (implements android.os.Handler.Callback)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicEngine.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicEngine</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicFileUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicFileUtils</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicResourceDataHelper.ResourceData.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicResourceDataHelper.ResourceData</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicRuntime.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicRuntime</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicServer.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicServer</span></a> (implements com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\">SonicSessionStream.Callback</a>)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSession</span></a> (implements android.os.Handler.Callback)\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/QuickSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">QuickSonicSession</span></a> (implements android.os.Handler.Callback)</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/StandardSonicSession.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">StandardSonicSession</span></a> (implements android.os.Handler.Callback)</li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionClient.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionClient</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConfig.Builder.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConfig.Builder</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection</span></a>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnection.SessionConnectionDefaultImpl.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnection.SessionConnectionDefaultImpl</span></a></li>\n</ul>\n</li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionConnectionInterceptor</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStatistics.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicSessionStatistics</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicUtils.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicUtils</span></a></li>\n<li type=\"circle\">android.database.sqlite.SQLiteOpenHelper\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDBHelper.html\" title=\"com.tencent.sonic.sdk中的类\"><span class=\"typeNameLink\">SonicDBHelper</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h2 title=\"接口分层结构\">接口分层结构</h2>\n<ul>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicDiffDataCallback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicDiffDataCallback</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.download.<a href=\"com/tencent/sonic/sdk/download/SonicDownloadCallback.html\" title=\"com.tencent.sonic.sdk.download中的接口\"><span class=\"typeNameLink\">SonicDownloadCallback</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSession.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSession.Callback</span></a></li>\n<li type=\"circle\">com.tencent.sonic.sdk.<a href=\"com/tencent/sonic/sdk/SonicSessionStream.Callback.html\" title=\"com.tencent.sonic.sdk中的接口\"><span class=\"typeNameLink\">SonicSessionStream.Callback</span></a></li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"overview-summary.html\">概览</a></li>\n<li>程序包</li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n</body>\n</html>\n"
  },
  {
    "path": "sonic-android/docs/javadoc/package-list",
    "content": "com.tencent.sonic.sdk\ncom.tencent.sonic.sdk.download\n"
  },
  {
    "path": "sonic-android/docs/javadoc/script.js",
    "content": "function show(type)\n{\n    count = 0;\n    for (var key in methods) {\n        var row = document.getElementById(key);\n        if ((methods[key] &  type) != 0) {\n            row.style.display = '';\n            row.className = (count++ % 2) ? rowColor : altColor;\n        }\n        else\n            row.style.display = 'none';\n    }\n    updateTabs(type);\n}\n\nfunction updateTabs(type)\n{\n    for (var value in tabs) {\n        var sNode = document.getElementById(tabs[value][0]);\n        var spanNode = sNode.firstChild;\n        if (value == type) {\n            sNode.className = activeTableTab;\n            spanNode.innerHTML = tabs[value][1];\n        }\n        else {\n            sNode.className = tableTab;\n            spanNode.innerHTML = \"<a href=\\\"javascript:show(\"+ value + \");\\\">\" + tabs[value][1] + \"</a>\";\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/docs/javadoc/stylesheet.css",
    "content": "/* Javadoc style sheet */\n/*\nOverall document style\n*/\n\n@import url('resources/fonts/dejavu.css');\n\nbody {\n    background-color:#ffffff;\n    color:#353833;\n    font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;\n    font-size:14px;\n    margin:0;\n}\na:link, a:visited {\n    text-decoration:none;\n    color:#4A6782;\n}\na:hover, a:focus {\n    text-decoration:none;\n    color:#bb7a2a;\n}\na:active {\n    text-decoration:none;\n    color:#4A6782;\n}\na[name] {\n    color:#353833;\n}\na[name]:hover {\n    text-decoration:none;\n    color:#353833;\n}\npre {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n}\nh1 {\n    font-size:20px;\n}\nh2 {\n    font-size:18px;\n}\nh3 {\n    font-size:16px;\n    font-style:italic;\n}\nh4 {\n    font-size:13px;\n}\nh5 {\n    font-size:12px;\n}\nh6 {\n    font-size:11px;\n}\nul {\n    list-style-type:disc;\n}\ncode, tt {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n    margin-top:8px;\n    line-height:1.4em;\n}\ndt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n}\ntable tr td dt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    vertical-align:top;\n    padding-top:4px;\n}\nsup {\n    font-size:8px;\n}\n/*\nDocument title and Copyright styles\n*/\n.clear {\n    clear:both;\n    height:0px;\n    overflow:hidden;\n}\n.aboutLanguage {\n    float:right;\n    padding:0px 21px;\n    font-size:11px;\n    z-index:200;\n    margin-top:-9px;\n}\n.legalCopy {\n    margin-left:.5em;\n}\n.bar a, .bar a:link, .bar a:visited, .bar a:active {\n    color:#FFFFFF;\n    text-decoration:none;\n}\n.bar a:hover, .bar a:focus {\n    color:#bb7a2a;\n}\n.tab {\n    background-color:#0066FF;\n    color:#ffffff;\n    padding:8px;\n    width:5em;\n    font-weight:bold;\n}\n/*\nNavigation bar styles\n*/\n.bar {\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    padding:.8em .5em .4em .8em;\n    height:auto;/*height:1.8em;*/\n    font-size:11px;\n    margin:0;\n}\n.topNav {\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px; \n}\n.bottomNav {\n    margin-top:10px;\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav {\n    background-color:#dee3e9;\n    float:left;\n    width:100%;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav div {\n    clear:left;\n    float:left;\n    padding:0 0 5px 6px;\n    text-transform:uppercase;\n}\nul.navList, ul.subNavList {\n    float:left;\n    margin:0 25px 0 0;\n    padding:0;\n}\nul.navList li{\n    list-style:none;\n    float:left;\n    padding: 5px 6px;\n    text-transform:uppercase;\n}\nul.subNavList li{\n    list-style:none;\n    float:left;\n}\n.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {\n    color:#FFFFFF;\n    text-decoration:none;\n    text-transform:uppercase;\n}\n.topNav a:hover, .bottomNav a:hover {\n    text-decoration:none;\n    color:#bb7a2a;\n    text-transform:uppercase;\n}\n.navBarCell1Rev {\n    background-color:#F8981D;\n    color:#253441;\n    margin: auto 5px;\n}\n.skipNav {\n    position:absolute;\n    top:auto;\n    left:-9999px;\n    overflow:hidden;\n}\n/*\nPage header and footer styles\n*/\n.header, .footer {\n    clear:both;\n    margin:0 20px;\n    padding:5px 0 0 0;\n}\n.indexHeader {\n    margin:10px;\n    position:relative;\n}\n.indexHeader span{\n    margin-right:15px;\n}\n.indexHeader h1 {\n    font-size:13px;\n}\n.title {\n    color:#2c4557;\n    margin:10px 0;\n}\n.subTitle {\n    margin:5px 0 0 0;\n}\n.header ul {\n    margin:0 0 15px 0;\n    padding:0;\n}\n.footer ul {\n    margin:20px 0 5px 0;\n}\n.header ul li, .footer ul li {\n    list-style:none;\n    font-size:13px;\n}\n/*\nHeading styles\n*/\ndiv.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList li.blockList h3 {\n    padding:0;\n    margin:15px 0;\n}\nul.blockList li.blockList h2 {\n    padding:0px 0 20px 0;\n}\n/*\nPage layout container styles\n*/\n.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {\n    clear:both;\n    padding:10px 20px;\n    position:relative;\n}\n.indexContainer {\n    margin:10px;\n    position:relative;\n    font-size:12px;\n}\n.indexContainer h2 {\n    font-size:13px;\n    padding:0 0 3px 0;\n}\n.indexContainer ul {\n    margin:0;\n    padding:0;\n}\n.indexContainer ul li {\n    list-style:none;\n    padding-top:2px;\n}\n.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {\n    font-size:12px;\n    font-weight:bold;\n    margin:10px 0 0 0;\n    color:#4E4E4E;\n}\n.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {\n    margin:5px 0 10px 0px;\n    font-size:14px;\n    font-family:'DejaVu Sans Mono',monospace;\n}\n.serializedFormContainer dl.nameValue dt {\n    margin-left:1px;\n    font-size:1.1em;\n    display:inline;\n    font-weight:bold;\n}\n.serializedFormContainer dl.nameValue dd {\n    margin:0 0 0 1px;\n    font-size:1.1em;\n    display:inline;\n}\n/*\nList styles\n*/\nul.horizontal li {\n    display:inline;\n    font-size:0.9em;\n}\nul.inheritance {\n    margin:0;\n    padding:0;\n}\nul.inheritance li {\n    display:inline;\n    list-style:none;\n}\nul.inheritance li ul.inheritance {\n    margin-left:15px;\n    padding-left:15px;\n    padding-top:1px;\n}\nul.blockList, ul.blockListLast {\n    margin:10px 0 10px 0;\n    padding:0;\n}\nul.blockList li.blockList, ul.blockListLast li.blockList {\n    list-style:none;\n    margin-bottom:15px;\n    line-height:1.4;\n}\nul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {\n    padding:0px 20px 5px 10px;\n    border:1px solid #ededed; \n    background-color:#f8f8f8;\n}\nul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {\n    padding:0 0 5px 8px;\n    background-color:#ffffff;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockList {\n    margin-left:0;\n    padding-left:0;\n    padding-bottom:15px;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {\n    list-style:none;\n    border-bottom:none;\n    padding-bottom:0;\n}\ntable tr td dl, table tr td dl dt, table tr td dl dd {\n    margin-top:0;\n    margin-bottom:1px;\n}\n/*\nTable styles\n*/\n.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {\n    width:100%;\n    border-left:1px solid #EEE; \n    border-right:1px solid #EEE; \n    border-bottom:1px solid #EEE; \n}\n.overviewSummary, .memberSummary  {\n    padding:0px;\n}\n.overviewSummary caption, .memberSummary caption, .typeSummary caption,\n.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {\n    position:relative;\n    text-align:left;\n    background-repeat:no-repeat;\n    color:#253441;\n    font-weight:bold;\n    clear:none;\n    overflow:hidden;\n    padding:0px;\n    padding-top:10px;\n    padding-left:1px;\n    margin:0px;\n    white-space:pre;\n}\n.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,\n.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,\n.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,\n.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,\n.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,\n.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,\n.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,\n.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {\n    color:#FFFFFF;\n}\n.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,\n.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    padding-bottom:7px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    border: none;\n    height:16px;\n}\n.memberSummary caption span.activeTableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    height:16px;\n}\n.memberSummary caption span.tableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#4D7A97;\n    height:16px;\n}\n.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {\n    padding-top:0px;\n    padding-left:0px;\n    padding-right:0px;\n    background-image:none;\n    float:none;\n    display:inline;\n}\n.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,\n.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {\n    display:none;\n    width:5px;\n    position:relative;\n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .activeTableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative; \n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .tableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative;\n    background-color:#4D7A97;\n    float:left;\n\n}\n.overviewSummary td, .memberSummary td, .typeSummary td,\n.useSummary td, .constantsSummary td, .deprecatedSummary td {\n    text-align:left;\n    padding:0px 0px 12px 10px;\n}\nth.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,\ntd.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{\n    vertical-align:top;\n    padding-right:0px;\n    padding-top:8px;\n    padding-bottom:3px;\n}\nth.colFirst, th.colLast, th.colOne, .constantsSummary th {\n    background:#dee3e9;\n    text-align:left;\n    padding:8px 3px 3px 7px;\n}\ntd.colFirst, th.colFirst {\n    white-space:nowrap;\n    font-size:13px;\n}\ntd.colLast, th.colLast {\n    font-size:13px;\n}\ntd.colOne, th.colOne {\n    font-size:13px;\n}\n.overviewSummary td.colFirst, .overviewSummary th.colFirst,\n.useSummary td.colFirst, .useSummary th.colFirst,\n.overviewSummary td.colOne, .overviewSummary th.colOne,\n.memberSummary td.colFirst, .memberSummary th.colFirst,\n.memberSummary td.colOne, .memberSummary th.colOne,\n.typeSummary td.colFirst{\n    width:25%;\n    vertical-align:top;\n}\ntd.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 {\n    font-weight:bold;\n}\n.tableSubHeadingColor {\n    background-color:#EEEEFF;\n}\n.altColor {\n    background-color:#FFFFFF;\n}\n.rowColor {\n    background-color:#EEEEEF;\n}\n/*\nContent styles\n*/\n.description pre {\n    margin-top:0;\n}\n.deprecatedContent {\n    margin:0;\n    padding:10px 0;\n}\n.docSummary {\n    padding:0;\n}\n\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    font-style:normal;\n}\n\ndiv.block {\n    font-size:14px;\n    font-family:'DejaVu Serif', Georgia, \"Times New Roman\", Times, serif;\n}\n\ntd.colLast div {\n    padding-top:0px;\n}\n\n\ntd.colLast a {\n    padding-bottom:3px;\n}\n/*\nFormatting effect styles\n*/\n.sourceLineNo {\n    color:green;\n    padding:0 30px 0 0;\n}\nh1.hidden {\n    visibility:hidden;\n    overflow:hidden;\n    font-size:10px;\n}\n.block {\n    display:block;\n    margin:3px 10px 2px 0px;\n    color:#474747;\n}\n.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,\n.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,\n.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {\n    font-weight:bold;\n}\n.deprecationComment, .emphasizedPhrase, .interfaceName {\n    font-style:italic;\n}\n\ndiv.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,\ndiv.block div.block span.interfaceName {\n    font-style:normal;\n}\n\ndiv.contentContainer ul.blockList li.blockList h2{\n    padding-bottom:0px;\n}\n"
  },
  {
    "path": "sonic-android/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Jun 19 17:11:15 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-3.5-all.zip\n"
  },
  {
    "path": "sonic-android/gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "sonic-android/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "sonic-android/sample/.gitignore",
    "content": ".gradle\n/build\n# Ignore Gradle GUI config\ngradle-app.setting\n\n# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)\n!gradle-wrapper.jar\n\n# Cache of project\n.gradletasknamecache\n\n.DS_Store\nnode_modules\n\n# Built application files\n*.apk\n*.ap_\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\n\n# Gradle files\n.gradle/\n*.iml\n/*/*.iml\n.idea\n/*/.idea/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\ngradle.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n/*/.idea\n\n/buildSdk\n\n\n"
  },
  {
    "path": "sonic-android/sample/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n    defaultConfig {\n        applicationId \"com.tencent.sonic\"\n        minSdkVersion 19\n        targetSdkVersion 25\n        versionCode 3\n        versionName \"3.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n\n    // compile sdk from jcenter\n     compile 'com.tencent.sonic:sdk:3.1.0'\n\n    // compile sonic-sdk from local path\n//     compile project(path: ':sdk')\n\n    compile 'com.android.support:appcompat-v7:25.2.0'\n    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'\n    compile 'com.android.support:design:25.3.1'\n    testCompile 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "sonic-android/sample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/lovekidchen/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "sonic-android/sample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.tencent.sonic\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".demo.MainActivity\" android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".demo.BrowserActivity\" android:screenOrientation=\"portrait\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "sonic-android/sample/src/main/assets/sonic-demo-index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <script type=\"application/javascript\">\n        var _pageTime = {};\n        _pageTime.startTime = new Date;\n    </script>\n    <title>SONIC</title>\n    <style>\n        body {\n            margin: 0;\n            padding: 0;\n            font-size: 14px;\n            color: #777;\n            margin-top: 20px;\n        }\n        .sonic-wrapper {\n            padding: 0 12px;\n        }\n        .sonic-wrapper h1 {\n            font-size: 18px;\n            font-weight: 400;\n            color: #000;\n        }\n        .sonic-wrapper h2 {\n            font-size: 14px;\n            color: #000;\n        }\n        .sonic-wrapper p {\n            font-size: 14px;\n            color: #777;\n            line-height: 1.6em;\n        }\n        .sonic-wrapper img {\n            width: 100%;\n        }\n        .sonic-wrapper table {\n            width: 100%;\n        }\n        .sonic-wrapper table img {\n            width: 100%;\n        }\n        .sonic_des {display:none;}\n    </style>\n</head>\n<body>\n<div class=\"sonic-wrapper\">\n    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\n    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\n    <span id=\"data1Content\">\n    <!--sonicdiff-data1-->\n    <p>示例：</p>\n    <img src=\"//mc.vip.qq.com/img/img-1.png?max_age=2592000\" alt=\"\">\n    <!--sonicdiff-data1-end-->\n    </span>\n    <span id=\"des0\" class=\"sonic_des\">\n        <h2>非Sonic模式 点击到页面打开耗时:<span id=\"pageTime0\"></span></h2>\n        <p>普通直出的方式</p>\n    </span>\n    <span id=\"des1\" class=\"sonic_des\">\n        <h2>首次访问 点击到页面打开耗时:<span id=\"pageTime1\"></span></h2>\n        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\n    </span>\n    <span id=\"des2\" class=\"sonic_des\">\n        <h2>模版更新 点击到页面打开耗时:<span id=\"pageTime2\"></span></h2>\n        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\n    </span>\n    <span id=\"des3\" class=\"sonic_des\">\n        <h2>数据更新 点击到页面打开耗时:<span id=\"pageTime3\"></span></h2>\n        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\n    </span>\n    <span id=\"des4\" class=\"sonic_des\">\n        <h2>完全缓存 点击到页面打开耗时:<span id=\"pageTime4\"></span></h2>\n        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\n    </span>\n        <h2>页面打开速度效果对比</h2>\n    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\n\n    <table>\n        <tr>\n            <td>原有直出页面：</td>\n            <td>Sonic改造页面：</td>\n        </tr>\n        <tr>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\" alt=\"\"></td>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\" alt=\"\"></td>\n        </tr>\n    </table>\n        <h2>Sonic实现原理简介</h2>\n    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\n</div>\n<script>\n    _pageTime.jsendtTime = new Date();\n</script>\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\" id=\"seajsnode\"></script>\n<script>;var BJ_REPORT=function(r){if(r.BJ_REPORT)return r.BJ_REPORT;var e=[],n={},t={id:0,pid:0,uin:0,url:\"//badjs.vip.qq.com/badjs\",combo:1,ext:null,level:4,ignore:[],random:0,delay:100,submit:null,repeat:1,pvrandom:0,errrandom:0,furl:\"0\"},o=2,i=0,a=function(r,e){return Object.prototype.toString.call(r)===\"[object \"+(e||\"Object\")+\"]\"},u=function(r){var e=typeof r;return\"object\"===e&&!!r},c=function(r){return null===r?!0:a(r,\"Number\")?!1:!r},s=r.onerror;r.onerror=function(e,n,t,o,u){var c=e;i++,u&&u.stack&&(c=f(u)),a(c,\"Event\")&&(c+=c.type?\"--\"+c.type+\"--\"+(c.target?c.target.tagName+\"::\"+c.target.src:\"\"):\"\"),y.push({msg:c,target:n,rowNum:t,colNum:o}),j(),s&&s.apply(r,arguments)};var d=function(r){try{if(r.stack){var e=r.stack.match(\"https?://[^\\n]+\");e=e?e[0]:\"\";var n=e.match(\":(\\\\d+):(\\\\d+)\");n||(n=[0,0,0]);var t=f(r);return{msg:t,rowNum:n[1],colNum:n[2],target:e.replace(n[0],\"\")}}return r.name&&r.message&&r.description?{msg:JSON.stringify(r)}:r}catch(o){return r}},f=function(r){var e=r.stack.replace(/\\n/gi,\"\").split(/\\bat\\b/).slice(0,9).join(\"@\").replace(/\\?[^:]+/gi,\"\"),n=r.toString();return e.indexOf(n)<0&&(e=n+\"@\"+e),e},p=function(r,e){var n=[],o=[],i=[];if(u(r)){r.level=r.level||t.level;for(var a in r){var s=r[a];if(!c(s)){if(u(s))try{s=JSON.stringify(s)}catch(d){s=\"[BJ_REPORT detect value stringify error] \"+d.toString()}i.push(a+\":\"+s),n.push(a+\"=\"+encodeURIComponent(s)),o.push(a+\"[\"+e+\"]=\"+encodeURIComponent(s))}}}return[o.join(\"&\"),i.join(\",\"),n.join(\"&\")]},l=[],m=function(r){var e=new RegExp(\"badjspv\");if(e.test(r)||(r=g(r)),t.submit)t.submit(r);else{var n=new Image;l.push(n),n.src=r}},v=function(){var r=!1,e=new RegExp(\"debug=1\"),n=new RegExp(\"badjs=1\");n.test(document.cookie)&&(r=!0),(n.test(document.location.href)||e.test(document.location.href))&&(r=!0);var t=navigator.userAgent.toLowerCase();return/sq\\_[\\d\\.]+\\_\\d+\\_hdb/.test(t)&&(r=!0),r},g=function(r){return r+=\"&ic=\"+i,v()&&(r+=\"&ig=1\"),r},h=function(r){if(!u(r))return!0;var e=r.msg,o=n[e]=(parseInt(n[e],10)||0)+1;return o>t.repeat},R=[],b=0,j=function(r){if(t.report){for(;e.length;){var n=!1,o=e.shift();if(!h(o)){var i=p(o,R.length);if(a(t.ignore,\"Array\"))for(var u=0,c=t.ignore.length;c>u;u++){var s=t.ignore[u];if(a(s,\"RegExp\")&&s.test(i[1])||a(s,\"Function\")&&s(o,i[1])){n=!0;break}}n||(t.combo?R.push(i[0]):m(t.report+i[2]+\"&_t=\"+ +new Date),t.onReport&&t.onReport(t.id,o))}}var d=R.length;if(d){var f=function(){clearTimeout(b),m(t.report+R.join(\"&\")+\"&count=\"+R.length+\"&_t=\"+ +new Date),b=0,R=[]};r?f():b||(b=setTimeout(f,t.delay))}}},y={push:function(r){if(1===t.random||v());else{var n=Math.round(9*Math.random()+1);if(0===t.errrandom){if(9!=n)return y}else{var o=10*t.errrandom/10;if(o>=1||t.errrandom<.1);else{for(var i=10*t.errrandom,a=[],c=1;i>=c;c++)a.push(c);if(!_(n,a))return y}}}var s=u(r)?d(r):{msg:r};return t.ext&&!s.ext&&(s.ext=t.ext),e.push(s),j(),y},report:function(r){return r&&y.push(r),j(!0),y},info:function(r){return r?(u(r)?r.level=2:r={msg:r,level:2},y.push(r),y):y},debug:function(r){return r?(u(r)?r.level=1:r={msg:r,level:1},y.push(r),y):y},init:function(r){if(u(r))for(var n in r)t[n]=r[n];var i=parseInt(t.id,10);return i&&(w(),/qq\\.com$/gi.test(location.hostname)&&(t.url||(t.url=\"//badjs.vip.qq.com/badjs\"),t.uin||(t.uin=parseInt((document.cookie.match(/\\buin=\\D+(\\d+)/)||[])[1],10))),t.report=(t.url||\"/badjs\")+\"?id=\"+i+\"&pid=\"+t.pid+\"&uin=\"+t.uin+\"&v=\"+o+\"&from=\"+encodeURIComponent(y.referrer())+\"&furl=\"+encodeURIComponent(t.furl)+\"&\"),e.length&&j(),y},referrer:function(){var r=\"\";try{r=window.top.document.referrer}catch(e){if(window.parent)try{r=window.parent.document.referrer}catch(n){r=\"\"}}return\"\"===r&&(r=document.referrer),r},__onerror__:r.onerror},_=function(r,e){for(var n in e)if(r==e[n])return!0},w=function(){var r=\"//badjs.vip.qq.com/badjspv?id=\"+t.id+\"&pid=\"+t.pid+\"&v=\"+o+\"&furl=\"+encodeURIComponent(t.furl);if(1==t.random||v())m(r);else{var e=Math.round(99*Math.random()+1);if(0===t.pvrandom)9==e&&m(r);else{var n=100*t.pvrandom/100;if(n>=1||t.pvrandom<.01)m(r);else{for(var i=100*t.pvrandom,a=[],u=1;i>=u;u++)a.push(u);_(e,a)&&m(r)}}}};return\"undefined\"!=typeof console&&console.error&&setTimeout(function(){var r=((location.hash||\"\").match(/([#&])BJ_ERROR=([^&$]+)/)||[])[2];r&&console.error(\"BJ_ERROR\",decodeURIComponent(r).replace(/(:\\d+:\\d+)\\s*/g,\"$1\\n\"))},0),y}(window);\"undefined\"!=typeof exports&&(\"undefined\"!=typeof module&&module.exports&&(exports=module.exports=BJ_REPORT),exports.BJ_REPORT=BJ_REPORT);</script>\n<script>\n    if(window.BJ_REPORT) {\n        (function(){\n            var bjParam = {id:38,pvrandom:0.1,errrandom:1,furl:'h5.vip.qq.com/p/sonic/mc/vipcenterv5', ignore:[/(QzoneApp|publicTube|load failed|DCReport|qw is not defined|object Event|XMLHttpRequest)/i]};\n                        BJ_REPORT.init(bjParam);\n        })();\n    }\n    seajs.config({\n        base: 'http://imgcache.gtimg.cn/club/platform/examples/',\n        localcache:{\n            //浏览器缓存时间\n            maxAge: 2592000,\n            openLocalStorageCache: 0\n        },\n        maxFile : {\n\n        },\n        debug:1,\n        //别名\n        alias:{\n            'zepto': 'lib/zepto/zepto'\n        },\n        paths:{\n            'lib' : 'http://imgcache.gtimg.cn/club/platform/lib'\n        },\n        manifest:{\n            \"lib/zepto/zepto\": \"1.1.3\",\n            \"lib/sonic/sonic\": \"3-1\"\n        }\n    });\n\n    seajs.use([\"zepto\", \"lib/sonic/sonic\"],function($, sonic){\n        /**\n         * 后置函数 sonic或普通模式 执行页面初始化等操作\n         */\n        function afterInit(sonicStatus){\n            $('.sonic_des').css('display', 'none');\n            $('#des'+sonicStatus).css('display', 'block');\n            //耗时分析(上报)\n            var performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\n            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\n            $(\"#pageTime\"+sonicStatus).text(pageTime+'ms');\n        }\n                /**\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\n         * @param sonicStatus\n         * @param reportSonicStatus\n         * @param sonicUpdateData\n         */\n        window.sonicStartTime = new Date;\n        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\n            if(sonicStatus == 1){\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\n            }else if(sonicStatus == 2){\n\n            }else if(sonicStatus == 3){\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\n                var html = '';\n                var id = '';\n                var elementObj = '';\n                for(var key in sonicUpdateData){\n                    id = key.substring(1,key.length-1);\n                    html = sonicUpdateData[key];\n                    elementObj = document.getElementById(id+'Content');\n                    elementObj.innerHTML = html;\n                }\n\n            }else if(sonicStatus == 4){\n\n            }\n            afterInit(reportSonicStatus);\n        });\n            });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/BrowserActivity.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.annotation.TargetApi;\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.design.widget.FloatingActionButton;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.webkit.WebResourceRequest;\nimport android.webkit.WebResourceResponse;\nimport android.webkit.WebSettings;\nimport android.webkit.WebView;\nimport android.webkit.WebViewClient;\nimport android.widget.Toast;\n\nimport com.tencent.sonic.R;\nimport com.tencent.sonic.sdk.SonicCacheInterceptor;\nimport com.tencent.sonic.sdk.SonicConfig;\nimport com.tencent.sonic.sdk.SonicConstants;\nimport com.tencent.sonic.sdk.SonicEngine;\nimport com.tencent.sonic.sdk.SonicSession;\nimport com.tencent.sonic.sdk.SonicSessionConfig;\nimport com.tencent.sonic.sdk.SonicSessionConnection;\nimport com.tencent.sonic.sdk.SonicSessionConnectionInterceptor;\n\nimport java.io.BufferedInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n *  A demo browser activity\n *  In this demo there are three modes,\n *  sonic mode: sonic mode means webview loads html by sonic,\n *  offline mode: offline mode means webview loads html from local offline packages,\n *  default mode: default mode means webview loads html in the normal way.\n *\n */\n\npublic class BrowserActivity extends Activity {\n\n\n    public final static String PARAM_URL = \"param_url\";\n\n    public final static String PARAM_MODE = \"param_mode\";\n\n    private SonicSession sonicSession;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Intent intent = getIntent();\n        String url = intent.getStringExtra(PARAM_URL);\n        int mode = intent.getIntExtra(PARAM_MODE, -1);\n        if (TextUtils.isEmpty(url) || -1 == mode) {\n            finish();\n            return;\n        }\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);\n\n        // init sonic engine if necessary, or maybe u can do this when application created\n        if (!SonicEngine.isGetInstanceAllowed()) {\n            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());\n        }\n\n        SonicSessionClientImpl sonicSessionClient = null;\n\n        // if it's sonic mode , startup sonic session at first time\n        if (MainActivity.MODE_DEFAULT != mode) { // sonic mode\n            SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n            sessionConfigBuilder.setSupportLocalServer(true);\n\n            // if it's offline pkg mode, we need to intercept the session connection\n            if (MainActivity.MODE_SONIC_WITH_OFFLINE_CACHE == mode) {\n                sessionConfigBuilder.setCacheInterceptor(new SonicCacheInterceptor(null) {\n                    @Override\n                    public String getCacheData(SonicSession session) {\n                        return null; // offline pkg does not need cache\n                    }\n                });\n\n                sessionConfigBuilder.setConnectionInterceptor(new SonicSessionConnectionInterceptor() {\n                    @Override\n                    public SonicSessionConnection getConnection(SonicSession session, Intent intent) {\n                        return new OfflinePkgSessionConnection(BrowserActivity.this, session, intent);\n                    }\n                });\n            }\n\n            // create sonic session and run sonic flow\n            sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());\n            if (null != sonicSession) {\n                sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());\n            } else {\n                // this only happen when a same sonic session is already running,\n                // u can comment following codes to feedback as a default mode.\n                // throw new UnknownError(\"create session fail!\");\n                Toast.makeText(this, \"create sonic session fail!\", Toast.LENGTH_LONG).show();\n            }\n        }\n\n        // start init flow ...\n        // in the real world, the init flow may cost a long time as startup\n        // runtime、init configs....\n        setContentView(R.layout.activity_browser);\n\n        FloatingActionButton btnFab = (FloatingActionButton) findViewById(R.id.btn_refresh);\n        btnFab.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (sonicSession != null) {\n                    sonicSession.refresh();\n                }\n            }\n        });\n\n        // init webview\n        WebView webView = (WebView) findViewById(R.id.webview);\n        webView.setWebViewClient(new WebViewClient() {\n            @Override\n            public void onPageFinished(WebView view, String url) {\n                super.onPageFinished(view, url);\n                if (sonicSession != null) {\n                    sonicSession.getSessionClient().pageFinish(url);\n                }\n            }\n\n            @TargetApi(21)\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {\n                return shouldInterceptRequest(view, request.getUrl().toString());\n            }\n\n            @Override\n            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {\n                if (sonicSession != null) {\n                    return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);\n                }\n                return null;\n            }\n        });\n\n        WebSettings webSettings = webView.getSettings();\n\n        // add java script interface\n        // note:if api level lower than 17(android 4.2), addJavascriptInterface has security\n        // issue, please use x5 or see https://developer.android.com/reference/android/webkit/\n        // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)\n        webSettings.setJavaScriptEnabled(true);\n        webView.removeJavascriptInterface(\"searchBoxJavaBridge_\");\n        intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis());\n        webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), \"sonic\");\n\n        // init webview settings\n        webSettings.setAllowContentAccess(true);\n        webSettings.setDatabaseEnabled(true);\n        webSettings.setDomStorageEnabled(true);\n        webSettings.setAppCacheEnabled(true);\n        webSettings.setSavePassword(false);\n        webSettings.setSaveFormData(false);\n        webSettings.setUseWideViewPort(true);\n        webSettings.setLoadWithOverviewMode(true);\n\n\n        // webview is ready now, just tell session client to bind\n        if (sonicSessionClient != null) {\n            sonicSessionClient.bindWebView(webView);\n            sonicSessionClient.clientReady();\n        } else { // default mode\n            webView.loadUrl(url);\n        }\n    }\n\n    @Override\n    public void onBackPressed() {\n        super.onBackPressed();\n    }\n\n    @Override\n    protected void onDestroy() {\n        if (null != sonicSession) {\n            sonicSession.destroy();\n            sonicSession = null;\n        }\n        super.onDestroy();\n    }\n\n\n    private static class OfflinePkgSessionConnection extends SonicSessionConnection {\n\n        private final WeakReference<Context> context;\n\n        public OfflinePkgSessionConnection(Context context, SonicSession session, Intent intent) {\n            super(session, intent);\n            this.context = new WeakReference<Context>(context);\n        }\n\n        @Override\n        protected int internalConnect() {\n            Context ctx = context.get();\n            if (null != ctx) {\n                try {\n                    InputStream offlineHtmlInputStream = ctx.getAssets().open(\"sonic-demo-index.html\");\n                    responseStream = new BufferedInputStream(offlineHtmlInputStream);\n                    return SonicConstants.ERROR_CODE_SUCCESS;\n                } catch (Throwable e) {\n                    e.printStackTrace();\n                }\n            }\n            return SonicConstants.ERROR_CODE_UNKNOWN;\n        }\n\n        @Override\n        protected BufferedInputStream internalGetResponseStream() {\n            return responseStream;\n        }\n\n        @Override\n        protected String internalGetCustomHeadFieldEtag() {\n            return SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG;\n        }\n\n        @Override\n        public void disconnect() {\n            if (null != responseStream) {\n                try {\n                    responseStream.close();\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n\n        @Override\n        public int getResponseCode() {\n            return 200;\n        }\n\n        @Override\n        public Map<String, List<String>> getResponseHeaderFields() {\n            return new HashMap<>(0);\n        }\n\n        @Override\n        public String getResponseHeaderField(String key) {\n            return \"\";\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/MainActivity.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.support.design.widget.FloatingActionButton;\nimport android.view.View;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.widget.Button;\nimport android.widget.Toast;\n\nimport com.tencent.sonic.R;\nimport com.tencent.sonic.sdk.SonicConfig;\nimport com.tencent.sonic.sdk.SonicEngine;\nimport com.tencent.sonic.sdk.SonicSessionConfig;\n\n\n/**\n * main activity of this sample\n */\npublic class MainActivity extends Activity {\n\n    public static final int MODE_DEFAULT = 0;\n\n    public static final int MODE_SONIC = 1;\n\n    public static final int MODE_SONIC_WITH_OFFLINE_CACHE = 2;\n\n    private static final int PERMISSION_REQUEST_CODE_STORAGE = 1;\n\n    private String DEMO_URL;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        // full screen\n        requestWindowFeature(Window.FEATURE_NO_TITLE);\n        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,\n                WindowManager.LayoutParams.FLAG_FULLSCREEN);\n\n        setContentView(R.layout.activity_main);\n\n        // clean up cache btn\n        Button btnReset = (Button) findViewById(R.id.btn_reset);\n        btnReset.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                SonicEngine.getInstance().cleanCache();\n            }\n        });\n\n        // default btn\n        Button btnDefault = (Button) findViewById(R.id.btn_default_mode);\n        btnDefault.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                startBrowserActivity(MODE_DEFAULT);\n            }\n        });\n\n        // preload btn\n        Button btnSonicPreload = (Button) findViewById(R.id.btn_sonic_preload);\n        btnSonicPreload.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();\n                sessionConfigBuilder.setSupportLocalServer(true);\n\n                // preload session\n                boolean preloadSuccess = SonicEngine.getInstance().preCreateSession(DEMO_URL, sessionConfigBuilder.build());\n                Toast.makeText(getApplicationContext(), preloadSuccess ? \"Preload start up success!\" : \"Preload start up fail!\", Toast.LENGTH_LONG).show();\n            }\n        });\n\n        // sonic mode load btn\n        Button btnSonic = (Button) findViewById(R.id.btn_sonic);\n        btnSonic.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                startBrowserActivity(MODE_SONIC);\n            }\n        });\n\n        // load sonic with offline cache\n        Button btnSonicWithOfflineCache = (Button) findViewById(R.id.btn_sonic_with_offline);\n        btnSonicWithOfflineCache.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                startBrowserActivity(MODE_SONIC_WITH_OFFLINE_CACHE);\n            }\n        });\n\n        if (hasPermission()) {\n            init();\n        } else {\n            requestPermission();\n        }\n\n        final UrlListAdapter urlListAdapter = new UrlListAdapter(MainActivity.this);\n\n        FloatingActionButton btnFab = (FloatingActionButton) findViewById(R.id.btn_fab);\n        btnFab.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                UrlSelector.launch(MainActivity.this, urlListAdapter, new UrlSelector.OnUrlChangedListener() {\n                    @Override\n                    public void urlChanged(String url) {\n                        DEMO_URL = url;\n                    }\n                });\n            }\n        });\n\n        DEMO_URL = urlListAdapter.getCheckedUrl();\n    }\n\n    private void init() {\n        // init sonic engine\n        if (!SonicEngine.isGetInstanceAllowed()) {\n            SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());\n        }\n    }\n\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        }\n        return true;\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_STORAGE);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {\n        if (PERMISSION_REQUEST_CODE_STORAGE == requestCode) {\n            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {\n                requestPermission();\n            } else {\n                init();\n            }\n            return;\n        }\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults);\n    }\n\n    private void startBrowserActivity(int mode) {\n        Intent intent = new Intent(this, BrowserActivity.class);\n        intent.putExtra(BrowserActivity.PARAM_URL, DEMO_URL);\n        intent.putExtra(BrowserActivity.PARAM_MODE, mode);\n        intent.putExtra(SonicJavaScriptInterface.PARAM_CLICK_TIME, System.currentTimeMillis());\n        startActivityForResult(intent, -1);\n    }\n\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicJavaScriptInterface.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\n\nimport android.content.Intent;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.webkit.JavascriptInterface;\n\nimport com.tencent.sonic.sdk.SonicDiffDataCallback;\n\nimport org.json.JSONObject;\n\n/**\n * Sonic javaScript Interface (Android API Level >= 17)\n */\n\npublic class SonicJavaScriptInterface {\n\n    private final SonicSessionClientImpl sessionClient;\n\n    private final Intent intent;\n\n    public static final String PARAM_CLICK_TIME = \"clickTime\";\n\n    public static final String PARAM_LOAD_URL_TIME = \"loadUrlTime\";\n\n    public SonicJavaScriptInterface(SonicSessionClientImpl sessionClient, Intent intent) {\n        this.sessionClient = sessionClient;\n        this.intent = intent;\n    }\n\n    @JavascriptInterface\n    public void getDiffData() {\n        // the callback function of demo page is hardcode as 'getDiffDataCallback'\n        getDiffData2(\"getDiffDataCallback\");\n    }\n\n    @JavascriptInterface\n    public void getDiffData2(final String jsCallbackFunc) {\n        if (null != sessionClient) {\n            sessionClient.getDiffData(new SonicDiffDataCallback() {\n                @Override\n                public void callback(final String resultData) {\n                    Runnable callbackRunnable = new Runnable() {\n                        @Override\n                        public void run() {\n                            String jsCode = \"javascript:\" + jsCallbackFunc + \"('\"+ toJsString(resultData) + \"')\";\n                            sessionClient.getWebView().loadUrl(jsCode);\n                        }\n                    };\n                    if (Looper.getMainLooper() == Looper.myLooper()) {\n                        callbackRunnable.run();\n                    } else {\n                        new Handler(Looper.getMainLooper()).post(callbackRunnable);\n                    }\n                }\n            });\n        }\n    }\n\n    @JavascriptInterface\n    public String getPerformance() {\n        long clickTime = intent.getLongExtra(PARAM_CLICK_TIME, -1);\n        long loadUrlTime = intent.getLongExtra(PARAM_LOAD_URL_TIME, -1);\n        try {\n            JSONObject result = new JSONObject();\n            result.put(PARAM_CLICK_TIME, clickTime);\n            result.put(PARAM_LOAD_URL_TIME, loadUrlTime);\n            return result.toString();\n        } catch (Exception e) {\n\n        }\n\n        return \"\";\n    }\n\n    /*\n    * * From RFC 4627, \"All Unicode characters may be placed within the quotation marks except\n    * for the characters that must be escaped: quotation mark,\n    * reverse solidus, and the control characters (U+0000 through U+001F).\"\n    */\n    private static String toJsString(String value) {\n        if (value == null) {\n            return \"null\";\n        }\n        StringBuilder out = new StringBuilder(1024);\n        for (int i = 0, length = value.length(); i < length; i++) {\n            char c = value.charAt(i);\n\n\n            switch (c) {\n                case '\"':\n                case '\\\\':\n                case '/':\n                    out.append('\\\\').append(c);\n                    break;\n\n                case '\\t':\n                    out.append(\"\\\\t\");\n                    break;\n\n                case '\\b':\n                    out.append(\"\\\\b\");\n                    break;\n\n                case '\\n':\n                    out.append(\"\\\\n\");\n                    break;\n\n                case '\\r':\n                    out.append(\"\\\\r\");\n                    break;\n\n                case '\\f':\n                    out.append(\"\\\\f\");\n                    break;\n\n                default:\n                    if (c <= 0x1F) {\n                        out.append(String.format(\"\\\\u%04x\", (int) c));\n                    } else {\n                        out.append(c);\n                    }\n                    break;\n            }\n\n        }\n        return out.toString();\n    }\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicRuntimeImpl.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.content.Context;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.webkit.CookieManager;\nimport android.webkit.CookieSyncManager;\nimport android.webkit.WebResourceResponse;\n\nimport com.tencent.sonic.BuildConfig;\nimport com.tencent.sonic.sdk.SonicRuntime;\nimport com.tencent.sonic.sdk.SonicSessionClient;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * the sonic host application must implement SonicRuntime to do right things.\n */\n\npublic class SonicRuntimeImpl extends SonicRuntime {\n\n    public SonicRuntimeImpl(Context context) {\n        super(context);\n    }\n\n    /**\n     * 获取用户UA信息\n     * @return\n     */\n    @Override\n    public String getUserAgent() {\n        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\";\n    }\n\n    /**\n     * 获取用户ID信息\n     * @return\n     */\n    @Override\n    public String getCurrentUserAccount() {\n        return \"sonic-demo-master\";\n    }\n\n    @Override\n    public String getCookie(String url) {\n        CookieManager cookieManager = CookieManager.getInstance();\n        return cookieManager.getCookie(url);\n    }\n\n    @Override\n    public void log(String tag, int level, String message) {\n        switch (level) {\n            case Log.ERROR:\n                Log.e(tag, message);\n                break;\n            case Log.INFO:\n                Log.i(tag, message);\n                break;\n            default:\n                Log.d(tag, message);\n        }\n    }\n\n    @Override\n    public Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map<String, String> headers) {\n        WebResourceResponse resourceResponse =  new WebResourceResponse(mimeType, encoding, data);\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            resourceResponse.setResponseHeaders(headers);\n        }\n        return resourceResponse;\n    }\n\n    @Override\n    public void showToast(CharSequence text, int duration) {\n\n    }\n\n    @Override\n    public void notifyError(SonicSessionClient client, String url, int errorCode) {\n\n    }\n\n    @Override\n    public boolean isSonicUrl(String url) {\n        return true;\n    }\n\n    @Override\n    public boolean setCookie(String url, List<String> cookies) {\n        if (!TextUtils.isEmpty(url) && cookies != null && cookies.size() > 0) {\n            CookieManager cookieManager = CookieManager.getInstance();\n            for (String cookie : cookies) {\n                cookieManager.setCookie(url, cookie);\n            }\n            return true;\n        }\n        return false;\n    }\n\n    @Override\n    public boolean isNetworkValid() {\n        return true;\n    }\n\n    @Override\n    public void postTaskToThread(Runnable task, long delayMillis) {\n        Thread thread = new Thread(task, \"SonicThread\");\n        thread.start();\n    }\n\n    @Override\n    public File getSonicCacheDir() {\n        if (BuildConfig.DEBUG) {\n            String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"sonic/\";\n            File file = new File(path.trim());\n            if(!file.exists()){\n                file.mkdir();\n            }\n            return file;\n        }\n       return super.getSonicCacheDir();\n    }\n\n    @Override\n    public String getHostDirectAddress(String url) {\n        return null;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/SonicSessionClientImpl.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.os.Bundle;\nimport android.webkit.WebView;\n\nimport com.tencent.sonic.sdk.SonicSessionClient;\n\nimport java.util.HashMap;\n\n/**\n *  a implement of SonicSessionClient which need to connect webview and content data.\n */\n\npublic class SonicSessionClientImpl extends SonicSessionClient {\n\n    private WebView webView;\n\n    public void bindWebView(WebView webView) {\n        this.webView = webView;\n    }\n\n    public WebView getWebView() {\n        return webView;\n    }\n\n    @Override\n    public void loadUrl(String url, Bundle extraData) {\n        webView.loadUrl(url);\n    }\n\n    @Override\n    public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {\n        webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);\n    }\n\n\n    @Override\n    public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap<String, String> headers) {\n        loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);\n    }\n\n    public void destroy() {\n        if (null != webView) {\n            webView.destroy();\n            webView = null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/UrlListAdapter.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.text.TextUtils;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.BaseAdapter;\nimport android.widget.ImageButton;\nimport android.widget.RadioButton;\nimport android.widget.TextView;\n\nimport com.tencent.sonic.R;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\n\npublic class UrlListAdapter extends BaseAdapter {\n    public static final String PREFERENCE_URLS = \"urls\";\n    public static final String PREFERENCE_CHECKED_INDEX = \"checked_index\";\n\n    public static final int MODE_NORMAL = 1;\n    public static final int MODE_EDIT = 2;\n\n    private static final String DEFAULT_URL = \"http://mc.vip.qq.com/demo/indexv3\";\n\n    private ArrayList<String> urls;\n    private LayoutInflater mInflater;\n    private int checkedIndex;\n    private int mode = MODE_NORMAL;\n\n    private SharedPreferences sharedPreferences;\n\n    public UrlListAdapter(Context context) {\n        mInflater = LayoutInflater.from(context);\n        sharedPreferences = context.getSharedPreferences(\"list_adapter\", 0);\n        init();\n    }\n\n    void init() {\n        restore();\n        toggleNormalMode();\n    }\n\n    private void restore() {\n        urls = deserialize(sharedPreferences.getString(PREFERENCE_URLS, \"\"));\n        if (urls.isEmpty()) {\n            urls.add(DEFAULT_URL);\n        }\n\n        checkedIndex = sharedPreferences.getInt(PREFERENCE_CHECKED_INDEX, 0);\n    }\n\n    private String serialize(ArrayList<String> stringArrayList) {\n        return TextUtils.join(\";\", stringArrayList);\n    }\n\n    private ArrayList<String> deserialize(String serializedString) {\n        if (serializedString.isEmpty()) {\n            return new ArrayList<>();\n        }\n        return new ArrayList<>(Arrays.asList(serializedString.split(\";\")));\n    }\n\n    String getCheckedUrl() {\n        return (checkedIndex >= 0 && checkedIndex < urls.size()) ? urls.get(checkedIndex) : DEFAULT_URL;\n    }\n\n    void addNewItem(String url) {\n        urls.add(url);\n        notifyDataSetChanged();\n    }\n\n    void toggleNormalMode() {\n        mode = MODE_NORMAL;\n        notifyDataSetChanged();\n    }\n\n    void toggleEditMode() {\n        mode = MODE_EDIT;\n        notifyDataSetChanged();\n    }\n\n    void setChecked(int index) {\n        if (mode == MODE_NORMAL) {\n            checkedIndex = index;\n            notifyDataSetChanged();\n        }\n    }\n\n    @Override\n    public int getCount() {\n        return urls.size();\n    }\n\n    @Override\n    public Object getItem(int position) {\n        return null;\n    }\n\n    @Override\n    public long getItemId(int position) {\n        return 0;\n    }\n\n    @Override\n    public View getView(final int position, View convertView, ViewGroup parent) {\n        ViewHolder holder;\n        if (convertView == null) {\n            holder = new ViewHolder();\n            convertView = mInflater.inflate(R.layout.list_item_url, null);\n            holder.radioButton = (RadioButton) convertView.findViewById(R.id.radio);\n            holder.textUrl = (TextView) convertView.findViewById(R.id.text_url);\n            holder.btnDelete = (ImageButton) convertView.findViewById(R.id.btn_delete);\n            convertView.setTag(holder);\n        } else {\n            holder = (ViewHolder) convertView.getTag();\n        }\n\n        if (mode == MODE_EDIT && position == 0) {\n            holder.btnDelete.setVisibility(View.INVISIBLE);\n        } else {\n            holder.btnDelete.setVisibility(mode == MODE_EDIT ? View.VISIBLE : View.INVISIBLE);\n        }\n\n        if (mode == MODE_EDIT) {\n            holder.radioButton.setVisibility(View.GONE);\n        } else {\n            holder.radioButton.setChecked(checkedIndex == position);\n            holder.radioButton.setVisibility(View.VISIBLE);\n        }\n\n        holder.textUrl.setText(urls.get(position));\n\n        holder.btnDelete.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (position == checkedIndex) {\n                    checkedIndex = 0;\n                }\n                urls.remove(position);\n                notifyDataSetChanged();\n            }\n        });\n\n        return convertView;\n    }\n\n    void persist() {\n        SharedPreferences.Editor editor = sharedPreferences.edit();\n        editor.putString(PREFERENCE_URLS, serialize(urls));\n        editor.putInt(PREFERENCE_CHECKED_INDEX, checkedIndex);\n        editor.apply();\n    }\n\n    private class ViewHolder {\n        RadioButton radioButton;\n        TextView textUrl;\n        ImageButton btnDelete;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/java/com/tencent/sonic/demo/UrlSelector.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.demo;\n\nimport android.app.AlertDialog;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.util.Patterns;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.AdapterView;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.ImageButton;\nimport android.widget.ListView;\nimport android.widget.Toast;\n\nimport com.tencent.sonic.R;\n\n\npublic class UrlSelector {\n    static void launch(final Context context, final UrlListAdapter urlListAdapter, final OnUrlChangedListener listener) {\n        urlListAdapter.init();\n        final View view = LayoutInflater.from(context).inflate(R.layout.dialog_url, null);\n\n        ListView listView = (ListView) view.findViewById(R.id.listView);\n        listView.setAdapter(urlListAdapter);\n        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n            @Override\n            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n                urlListAdapter.setChecked(position);\n            }\n        });\n\n        final ImageButton btnAddItem = (ImageButton) view.findViewById(R.id.btn_add_item);\n        btnAddItem.setActivated(false);\n\n        final EditText textNewUrl = (EditText) view.findViewById(R.id.text_new_url);\n        textNewUrl.addTextChangedListener(new TextWatcher() {\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n            }\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\n            }\n\n            @Override\n            public void afterTextChanged(Editable s) {\n                btnAddItem.setActivated(Patterns.WEB_URL.matcher(s.toString()).matches());\n            }\n        });\n\n        btnAddItem.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (btnAddItem.isActivated()) {\n                    urlListAdapter.addNewItem(textNewUrl.getText().toString());\n                    textNewUrl.setText(R.string.http_prefix);\n                    textNewUrl.setSelection(textNewUrl.getText().length());\n                } else {\n                    Toast.makeText(context, R.string.illegal_url, Toast.LENGTH_SHORT).show();\n                }\n            }\n        });\n\n        AlertDialog.Builder builder = new AlertDialog.Builder(context);\n        builder.setTitle(R.string.set_custom_url);\n        builder.setCancelable(false);\n        builder.setView(view);\n        builder.setPositiveButton(R.string.close, null);\n        final AlertDialog alertDialog = builder.create();\n\n        final View viewAddItem = view.findViewById(R.id.add_item);\n        final Button btnEdit = (Button) view.findViewById(R.id.btn_edit);\n        btnEdit.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                btnEdit.setVisibility(View.INVISIBLE);\n                urlListAdapter.toggleEditMode();\n                viewAddItem.setVisibility(View.VISIBLE);\n\n                alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.finish);\n            }\n        });\n\n        alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {\n            @Override\n            public void onShow(final DialogInterface dialog) {\n                final Button okButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);\n                okButton.setOnClickListener(new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        if (okButton.getText().equals(context.getString(R.string.finish))) {\n                            urlListAdapter.toggleNormalMode();\n                            viewAddItem.setVisibility(View.GONE);\n                            btnEdit.setVisibility(View.VISIBLE);\n                            okButton.setText(R.string.close);\n                        } else if (okButton.getText().equals(context.getString(R.string.close))) {\n                            urlListAdapter.persist();\n                            listener.urlChanged(urlListAdapter.getCheckedUrl());\n                            dialog.dismiss();\n                        }\n                    }\n                });\n            }\n        });\n\n        alertDialog.show();\n\n        // prevent keyboard from not showing\n        alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);\n        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);\n    }\n\n    interface OnUrlChangedListener {\n        void urlChanged(String url);\n    }\n}\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/drawable/ic_add_circle_accent_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF4081\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z\"/>\n</vector>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/drawable/ic_add_circle_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z\"/>\n</vector>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/drawable/ic_add_circle_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@drawable/ic_add_circle_black_24dp\" android:state_activated=\"false\" />\n    <item android:drawable=\"@drawable/ic_add_circle_accent_24dp\" />\n</selector>"
  },
  {
    "path": "sonic-android/sample/src/main/res/drawable/ic_remove_circle_accent_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF4081\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13L7,13v-2h10v2z\"/>\n</vector>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/drawable/sonic_button_round_mask.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<shape\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <solid android:color=\"#049DFF\" />\n    <corners android:radius=\"3dip\" />\n</shape>"
  },
  {
    "path": "sonic-android/sample/src/main/res/layout/activity_browser.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.widget.FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.tencent.sonic.demo.BrowserActivity\">\n\n    <WebView\n        android:id=\"@+id/webview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/btn_refresh\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"16dp\"\n        app:srcCompat=\"@android:drawable/ic_menu_rotate\" />\n</android.widget.FrameLayout>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.tencent.sonic.demo.MainActivity\">\n\n    <android.widget.RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        xmlns:tools=\"http://schemas.android.com/tools\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/iv_slogan\"\n            android:layout_margin=\"40dp\"\n            android:layout_marginTop=\"50dp\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:scaleType=\"centerInside\"\n            android:src=\"@drawable/slogan\" />\n\n        <LinearLayout\n            android:id=\"@+id/content\"\n            android:layout_below=\"@id/iv_slogan\"\n            android:layout_above=\"@+id/tv_vas_team\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <Button\n                android:id=\"@+id/btn_default_mode\"\n                style=\"@style/SonicButton\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0.02\"\n                android:text=\"@string/default_no_sonic\" />\n\n            <Button\n                android:id=\"@+id/btn_sonic\"\n                style=\"@style/SonicButton\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0.02\"\n                android:text=\"@string/sonic\" />\n\n            <Button\n                android:id=\"@+id/btn_sonic_preload\"\n                style=\"@style/SonicButton\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0.02\"\n                android:text=\"@string/sonic_preload\"\n                />\n\n            <Button\n                android:id=\"@+id/btn_sonic_with_offline\"\n                style=\"@style/SonicButton\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0.02\"\n                android:text=\"@string/sonic_offline\"\n                />\n\n            <Button\n                android:id=\"@+id/btn_reset\"\n                style=\"@style/SonicButton\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0.02\"\n                android:text=\"@string/reset_clear\"\n                />\n        </LinearLayout>\n\n        <TextView\n            android:id=\"@+id/tv_vas_team\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@string/tencent_vas_team\"\n            android:layout_margin=\"30dp\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_alignParentBottom=\"true\"/>\n    </android.widget.RelativeLayout>\n\n    <android.support.design.widget.FloatingActionButton\n        android:id=\"@+id/btn_fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"16dp\"\n        app:srcCompat=\"@android:drawable/ic_dialog_info\" />\n</android.support.design.widget.CoordinatorLayout>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/layout/dialog_url.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:animateLayoutChanges=\"true\"\n    android:orientation=\"vertical\">\n\n    <Button\n        android:id=\"@+id/btn_edit\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"right\"\n        android:background=\"@null\"\n        android:text=\"@string/edit\"\n        android:textColor=\"@color/colorAccent\" />\n\n    <ListView\n        android:id=\"@+id/listView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:choiceMode=\"singleChoice\" />\n\n    <LinearLayout\n        android:id=\"@+id/add_item\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"horizontal\"\n        android:padding=\"10dp\"\n        android:visibility=\"gone\">\n\n        <EditText\n            android:id=\"@+id/text_new_url\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:text=\"@string/http_prefix\" />\n\n        <ImageButton\n            android:id=\"@+id/btn_add_item\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@null\"\n            android:src=\"@drawable/ic_add_circle_selector\" />\n    </LinearLayout>\n\n</LinearLayout>"
  },
  {
    "path": "sonic-android/sample/src/main/res/layout/list_item_url.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:animateLayoutChanges=\"true\"\n    android:descendantFocusability=\"blocksDescendants\"\n    android:orientation=\"horizontal\"\n    android:padding=\"10dp\">\n\n    <RadioButton\n        android:id=\"@+id/radio\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:clickable=\"false\"\n        android:focusable=\"false\"\n        android:focusableInTouchMode=\"false\"\n        android:gravity=\"center_vertical\" />\n\n    <TextView\n        android:id=\"@+id/text_url\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_weight=\"1\"\n        android:focusable=\"false\"\n        android:focusableInTouchMode=\"false\"\n        android:gravity=\"center_vertical\" />\n\n    <ImageButton\n        android:id=\"@+id/btn_delete\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"@null\"\n        android:src=\"@drawable/ic_remove_circle_accent_24dp\"\n        android:visibility=\"invisible\" />\n</LinearLayout>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n    <color name=\"button_background\">#049DFF</color>\n    <color name=\"button_text\">#FFFFFF</color>\n    <color name=\"colorDisabled\">#808080</color>\n</resources>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">sonic</string>\n    <string name=\"default_no_sonic\">Load Without Sonic</string>\n    <string name=\"sonic\">Load With Sonic</string>\n    <string name=\"sonic_preload\">DO Sonic Preload</string>\n    <string name=\"sonic_offline\">Load Sonic With Offline Cache</string>\n    <string name=\"sonic_no_eTag\">Load Sonic With No ETag</string>\n    <string name=\"reset_clear\">Clean Up Cache</string>\n    <string name=\"tencent_vas_team\">腾讯增值技术团队出品</string>\n    <string name=\"set_custom_url\">设置自定义URL</string>\n    <string name=\"close\">关闭</string>\n    <string name=\"http_prefix\">http://</string>\n    <string name=\"finish\">完成</string>\n    <string name=\"illegal_url\">不合法的URL</string>\n    <string name=\"edit\">编辑</string>\n</resources>\n"
  },
  {
    "path": "sonic-android/sample/src/main/res/values/styles.xml",
    "content": "<resources xmlns:android=\"http://schemas.android.com/tools\">\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <style name=\"SonicButton\" parent=\"Widget.AppCompat.Button\">\n        <item name=\"android:textColor\">@color/button_text</item>\n        <item name=\"android:layout_margin\">12dp</item>\n        <item name=\"android:background\">@drawable/sonic_button_round_mask</item>\n    </style>\n\n\n</resources>\n"
  },
  {
    "path": "sonic-android/sdk/.gitignore",
    "content": ".gradle\n/build\n# Ignore Gradle GUI config\ngradle-app.setting\n\n# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)\n!gradle-wrapper.jar\n\n# Cache of project\n.gradletasknamecache\n\n.DS_Store\nnode_modules\n\n# Built application files\n*.apk\n*.ap_\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\n\n# Gradle files\n.gradle/\n*.iml\n/*/*.iml\n.idea\n/*/.idea/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\ngradle.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n/*/.idea\n\n/buildSdk\n\n\n"
  },
  {
    "path": "sonic-android/sdk/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'\napply plugin: 'maven'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n\n    defaultConfig {\n        minSdkVersion 9\n        targetSdkVersion 25\n        versionCode 3\n        versionName \"3.1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n\n    testCompile 'junit:junit:4.12'\n\n\n    // Required for instrumented tests\n    androidTestCompile 'com.android.support:support-annotations:24.0.0'\n    androidTestCompile 'com.android.support.test:runner:0.5'\n\n    compile 'com.android.support:support-annotations:25.2.0'\n    androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.9.1'\n}\n\n\n// sdk info\nversion = \"3.1.0\" // sdk version num\ngroup = \"com.tencent.sonic\" // maven group id for the artifact\ndef SITE_URL = \"https://github.com/Tencent/VasSonic\" // web site url\ndef GIT_URL = \"https://github.com/Tencent/VasSonic.git\" // git url\n\n// maven task\n\ninstall {\n    repositories.mavenInstaller {\n        // This generates POM.xml with proper parameters\n        pom {\n            project {\n                // default configs\n                packaging 'jar'\n                description 'a lightweight and high-performance hybrid framework'\n                name 'VasSonic Hybrid Framework'\n                url SITE_URL\n\n                // set up licenses\n                licenses {\n                    license {\n                        name 'BSD 3-Clause License'\n                        url 'https://github.com/Tencent/VasSonic/blob/master/LICENSE'\n                    }\n                }\n\n                // developers\n                developers {\n                    developer {\n                        id 'Tencent VAS'\n                        name 'Tencent VAS'\n                    }\n                }\n\n                // scm\n                scm {\n                    connection GIT_URL\n                    developerConnection GIT_URL\n                    url SITE_URL\n                }\n            }\n        }\n    }\n}\n\ntask sourcesJar(type: Jar) {\n    from android.sourceSets.main.java.srcDirs\n    classifier = 'sources'\n}\n\ntask javadoc(type: Javadoc) {\n    source = android.sourceSets.main.java.srcDirs\n    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n}\n\nafterEvaluate {\n    javadoc.classpath += files(android.libraryVariants.collect { variant ->\n        variant.javaCompile.classpath.files\n    })\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from javadoc.destinationDir\n}\n\nartifacts {\n    archives sourcesJar\n    archives javadocJar\n}\n\n\nProperties properties = new Properties()\nproperties.load(project.rootProject.file('local.properties').newDataInputStream())\nbintray {\n    user = properties.getProperty(\"bintray.user\")\n    key = properties.getProperty(\"bintray.apikey\")\n    configurations = ['archives']\n    pkg {\n        repo = \"sonic\"\n        name = \"sonic-sdk\"\n        websiteUrl = SITE_URL\n        vcsUrl = GIT_URL\n        licenses = [\"BSD 3-Clause\"]\n        publish = true\n    }\n}"
  },
  {
    "path": "sonic-android/sdk/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/lovekidchen/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/BaseSonicTest.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport android.support.test.InstrumentationRegistry;\nimport android.util.Log;\nimport android.webkit.WebResourceResponse;\n\nimport org.json.JSONObject;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Rule;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport okhttp3.mockwebserver.MockResponse;\nimport okhttp3.mockwebserver.MockWebServer;\n\nimport static org.junit.Assert.assertEquals;\n\n\n@RunWith(JUnit4.class)\npublic class BaseSonicTest implements Handler.Callback {\n    private static final String TAG = \"SonicSdk_BaseSonicTest\";\n\n    protected SonicSession sonicSession;\n    protected SonicSessionClientImplTest sonicSessionClient;\n    protected final Handler mainHandler = new Handler(Looper.getMainLooper(), this);\n    protected String url;\n\n    final AtomicBoolean destroyLock = new AtomicBoolean(false);\n    final AtomicBoolean finishLock = new AtomicBoolean(false);\n\n    @Rule\n    public final MockWebServer server = new MockWebServer();\n\n    protected void initSonicSession()  {\n        // init sonic engine if necessary, or maybe u can do this when application created\n        // step 1: Initialize sonic engine if necessary, or maybe u can do this when application created\n\n        sonicSessionClient = null;\n\n        // step 2: Create SonicSession\n        url = server.url(\"/\").toString();\n        sonicSession = SonicEngine.getInstance().createSession(url,  new SonicSessionConfig.Builder().build());\n        if (null != sonicSession) {\n            sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImplTest());\n        } else {\n            // this only happen when a same sonic session is already running,\n            // u can comment following codes to feedback as a default mode.\n            throw new UnknownError(\"create session fail!\");\n        }\n\n    }\n\n    @Before\n    public void setUp() throws Exception {\n        Log.d(TAG, \"setUp() clear all sonic cache.\");\n        if (!SonicEngine.isGetInstanceAllowed()) {\n            SonicEngine.createInstance(new SonicRuntimeImplTest(InstrumentationRegistry.getContext()), new SonicConfig.Builder().build());\n        }\n        SonicEngine.getInstance().cleanCache();\n    }\n\n    @After\n    public void tearDown() throws Exception {\n        desroySonicSession();\n    }\n\n    protected void desroySonicSession() throws InterruptedException {\n        if (sonicSession != null) {\n            mainHandler.post(new Runnable() {\n                @Override\n                public void run() {\n                    sonicSession.destroy();\n                }\n            });\n\n            if (!destroyLock.get()) {\n                synchronized (destroyLock) {\n                    destroyLock.wait();\n                }\n            }\n            sonicSession = null;\n        }\n        destroyLock.set(false);\n        finishLock.set(false);\n    }\n\n    protected MockResponse mockFirstLoadResponse() {\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        Map<String, String> headers = new HashMap<>();\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG, etag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, templateTag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, \"true\");\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"true\");\n\n        MockResponse response = new MockResponse();\n        Set<Map.Entry<String, String >> entrySet = headers.entrySet();\n        for (Map.Entry<String, String> entry : entrySet) {\n            response.addHeader(entry.getKey(), entry.getValue());\n        }\n        response.setBody(SonicTestData.htmlString);\n        return response;\n    }\n\n    protected MockResponse mock304Response() {\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        Map<String, String> headers = new HashMap<>();\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG, etag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, templateTag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, \"true\");\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"false\");\n\n        MockResponse response = new MockResponse();\n        Set<Map.Entry<String, String >> entrySet = headers.entrySet();\n        for (Map.Entry<String, String> entry : entrySet) {\n            response.addHeader(entry.getKey(), entry.getValue());\n        }\n        response.setBody(\"\");\n        response.setResponseCode(304);\n        return response;\n    }\n\n    protected MockResponse mockTemplateChangedResponse() {\n        String newHtml = SonicTestData.htmlString.replace(\"maxAge: 2592000\", \"maxAge: 3592000\");\n        String newTemplateHtml = SonicTestData.templateString.replace(\"maxAge: 2592000\", \"maxAge: 3592000\");\n\n        final String etag = SonicUtils.getSHA1(newHtml);\n        final String templateTag = SonicUtils.getSHA1(newTemplateHtml);\n\n        Map<String, String> headers = new HashMap<>();\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG, etag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, templateTag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, \"true\");\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"true\");\n\n        MockResponse response = new MockResponse();\n        Set<Map.Entry<String, String >> entrySet = headers.entrySet();\n        for (Map.Entry<String, String> entry : entrySet) {\n            response.addHeader(entry.getKey(), entry.getValue());\n        }\n        response.setBody(newHtml);\n        return response;\n    }\n\n    protected MockResponse mockDataUpdatedResponse() {\n        String newHtml = SonicTestData.htmlString.replace(\"img-1.png?max_age=2592000\", \"img-2.png?max_age=2592000\");\n        String newDataString = SonicTestData.dataString.replace(\"img-1.png?max_age=2592000\", \"img-2.png?max_age=2592000\");\n\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n        final String newHtmlSha1 = SonicUtils.getSHA1(newHtml);\n\n        JSONObject testServerRspJson = null;\n        try {\n            testServerRspJson = new JSONObject(newDataString);\n            testServerRspJson.put(\"template-tag\", templateTag);\n            testServerRspJson.put(\"html-sha1\", newHtmlSha1);\n        } catch (Exception e) {\n\n        }\n\n        Map<String, String> headers = new HashMap<>();\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG, newHtmlSha1);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, templateTag);\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, \"true\");\n        headers.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"false\");\n\n        MockResponse response = new MockResponse();\n        Set<Map.Entry<String, String >> entrySet = headers.entrySet();\n        for (Map.Entry<String, String> entry : entrySet) {\n            response.addHeader(entry.getKey(), entry.getValue());\n        }\n        response.setBody(testServerRspJson.toString());\n\n        return response;\n\n    }\n\n    protected void mockLoadUrl() {\n        mainHandler.post(new Runnable() {\n            @Override\n            public void run() {\n                sonicSessionClient.clientReady();\n            }\n        });\n    }\n\n    protected void mockInterceptRequest(String html) throws IOException {\n        WebResourceResponse resourceResponse = (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);\n        if (resourceResponse != null) {\n            BufferedInputStream bufferedInputStream = new BufferedInputStream(resourceResponse.getData());\n            byte[] buffer = new byte[1024];\n            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n            String data = null;\n            int n = 0;\n            while (-1 != (n = bufferedInputStream.read(buffer))) {\n                outputStream.write(buffer, 0, n);\n            }\n\n            if (n == -1) {\n                data = outputStream.toString(\"UTF-8\");\n            }\n            assertEquals(data, html);\n            bufferedInputStream.close();\n        }\n    }\n\n\n    @Override\n    public boolean handleMessage(Message msg) {\n        return false;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/ExampleInstrumentedTest.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n\n    @Test\n    public void useAppContext() throws Exception {\n\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.tencent.sonic.sdk.test\", appContext.getPackageName());\n\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/QuickSonicSessionTest.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.text.TextUtils;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.JUnit4;\n\nimport java.nio.charset.Charset;\n\nimport okhttp3.mockwebserver.MockResponse;\nimport okhttp3.mockwebserver.RecordedRequest;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\n@RunWith(JUnit4.class)\npublic class QuickSonicSessionTest extends BaseSonicTest{\n\n    @Test\n    public void handleFlow_NotModified() throws Exception {\n        handleFlow_FirstLoad();\n        desroySonicSession();\n\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        server.enqueue(mock304Response());\n        initSonicSession();\n\n        sonicSession.addSessionCallback(new SonicSessionCallback.SimpleCallbackImpl() {\n            @Override\n            public void onSessionLoadLocalCache(String cacheHtml) {\n                assertTrue(!TextUtils.isEmpty(cacheHtml));\n                assertEquals(cacheHtml, SonicTestData.htmlString);\n            }\n\n            @Override\n            public void onSessionHitCache() {\n                if (finishLock.compareAndSet(false, true)) {\n                    synchronized (finishLock) {\n                        finishLock.notify();\n                    }\n                }\n            }\n\n            @Override\n            public void onSessionDestroy() {\n                if (destroyLock.compareAndSet(false, true)) {\n                    synchronized (destroyLock) {\n                        destroyLock.notify();\n                    }\n                }\n            }\n        });\n\n        mockLoadUrl();\n\n        if (!finishLock.get()) {\n            synchronized (finishLock) {\n                finishLock.wait();\n            }\n        }\n\n        RecordedRequest request = server.takeRequest();\n        assertEquals(\"true\", request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_ACCEPT_DIFF));\n        assertEquals(etag, request.getHeader(SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH));\n    }\n\n\n    @Test\n    public void handleFlow_DataUpdate() throws Exception {\n        handleFlow_FirstLoad();\n        desroySonicSession();\n\n        final MockResponse dataUpdatedResponse = mockDataUpdatedResponse();\n        server.enqueue(dataUpdatedResponse);\n\n        final String newTag = dataUpdatedResponse.getHeaders().get(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG);\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        initSonicSession();\n\n        sonicSessionClient.getDiffData(new SonicDiffDataCallback() {\n            @Override\n            public void callback(String resultData) {\n                try {\n                    JSONObject callbackJson = new JSONObject(resultData);\n                    assertTrue(callbackJson.optInt(SonicSession.WEB_RESPONSE_SRC_CODE) == SonicSession.SONIC_RESULT_CODE_DATA_UPDATE);\n                } catch (Exception e) {\n                    e.printStackTrace();\n                    assertFalse(e != null);\n                }\n            }\n        });\n\n        sonicSession.addSessionCallback(new SonicSessionCallback.SimpleCallbackImpl() {\n            @Override\n            public void onSessionLoadLocalCache(String cacheHtml) {\n                assertTrue(!TextUtils.isEmpty(cacheHtml));\n                assertEquals(cacheHtml, SonicTestData.htmlString);\n            }\n\n            public void onSessionDataUpdated(String serverRsp) {\n                assertEquals(serverRsp, dataUpdatedResponse.getBody().clone().readString(Charset.forName(\"UTF-8\")));\n            }\n\n            public void onSessionSaveCache(String htmlString, String templateString, String dataString) {\n                assertEquals(SonicUtils.getSHA1(htmlString), newTag);\n\n                try {\n                    JSONObject serverRsp = new JSONObject(dataUpdatedResponse.getBody().clone().readString(Charset.forName(\"UTF-8\")));\n                    assertEquals(dataString, serverRsp.optString(\"data\"));\n                } catch (Exception e) {\n                    assertFalse(e != null);\n                }\n\n                if (finishLock.compareAndSet(false, true)) {\n                    synchronized (finishLock) {\n                        finishLock.notify();\n                    }\n                }\n\n            }\n\n            @Override\n            public void onSessionDestroy() {\n                if (destroyLock.compareAndSet(false, true)) {\n                    synchronized (destroyLock) {\n                        destroyLock.notify();\n                    }\n                }\n            }\n        });\n\n        mockLoadUrl();\n\n        if (!finishLock.get()) {\n            synchronized (finishLock) {\n                finishLock.wait();\n            }\n        }\n\n        RecordedRequest request = server.takeRequest();\n        assertEquals(\"true\", request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_ACCEPT_DIFF));\n        assertEquals(etag, request.getHeader(SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH));\n        assertEquals(templateTag, request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG));\n    }\n\n    @Test\n    public void handleFlow_TemplateChange() throws Exception {\n        handleFlow_FirstLoad();\n        desroySonicSession();\n\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        MockResponse templateChangedResponse = mockTemplateChangedResponse();\n        final String newTag = templateChangedResponse.getHeaders().get(SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG);\n        final String newTemplateTag = templateChangedResponse.getHeaders().get(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n\n        server.enqueue(templateChangedResponse);\n\n        initSonicSession();\n\n        sonicSessionClient.getDiffData(new SonicDiffDataCallback() {\n            @Override\n            public void callback(String resultData) {\n                try {\n                    JSONObject callbackJson = new JSONObject(resultData);\n                    assertTrue(callbackJson.optInt(SonicSession.WEB_RESPONSE_SRC_CODE) == SonicSession.SONIC_RESULT_CODE_TEMPLATE_CHANGE);\n                } catch (Exception e) {\n                    assertFalse(e != null);\n                }\n            }\n        });\n\n        sonicSession.addSessionCallback(new SonicSessionCallback.SimpleCallbackImpl() {\n            @Override\n            public void onSessionLoadLocalCache(String cacheHtml) {\n                assertTrue(!TextUtils.isEmpty(cacheHtml));\n                assertEquals(cacheHtml, SonicTestData.htmlString);\n            }\n\n            public void onSessionTemplateChanged(String newHtml) {\n                assertEquals(SonicUtils.getSHA1(newHtml), newTag);\n            }\n\n            public void onSessionSaveCache(String htmlString, String templateString, String dataString) {\n                assertEquals(SonicUtils.getSHA1(htmlString), newTag);\n                assertEquals(SonicUtils.getSHA1(templateString), newTemplateTag);\n\n                if (finishLock.compareAndSet(false, true)) {\n                    synchronized (finishLock) {\n                        finishLock.notify();\n                    }\n                }\n\n            }\n\n            @Override\n            public void onSessionDestroy() {\n                if (destroyLock.compareAndSet(false, true)) {\n                    synchronized (destroyLock) {\n                        destroyLock.notify();\n                    }\n                }\n            }\n        });\n\n        mockLoadUrl();\n\n        if (!finishLock.get()) {\n            synchronized (finishLock) {\n                finishLock.wait();\n            }\n        }\n\n        RecordedRequest request = server.takeRequest();\n        assertEquals(\"true\", request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_ACCEPT_DIFF));\n        assertEquals(etag, request.getHeader(SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH));\n        assertEquals(templateTag, request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG));\n    }\n\n    @Test\n    public void handleFlow_HttpError() throws Exception {\n    }\n\n    @Test\n    public void handleFlow_ServiceUnavailable() throws Exception {\n    }\n\n    @Test\n    public void handleFlow_FirstLoad() throws Exception {\n        initSonicSession();\n\n        final String etag = SonicUtils.getSHA1(SonicTestData.htmlString);\n        final String templateTag = SonicUtils.getSHA1(SonicTestData.templateString);\n\n        server.enqueue(mockFirstLoadResponse());\n\n        sonicSessionClient.getDiffData(new SonicDiffDataCallback() {\n            @Override\n            public void callback(final String resultData) {\n                try {\n                    JSONObject callbackJson = new JSONObject(resultData);\n                    assertTrue(callbackJson.optInt(SonicSession.WEB_RESPONSE_SRC_CODE) == SonicSession.SONIC_RESULT_CODE_FIRST_LOAD);\n                } catch (Exception e) {\n                    assertFalse(e != null);\n                }\n            }\n        });\n\n        sonicSession.addSessionCallback(new SonicSessionCallback.SimpleCallbackImpl() {\n            @Override\n            public void onSessionLoadLocalCache(String cacheHtml) {\n                assertTrue(TextUtils.isEmpty(cacheHtml));\n            }\n\n            public void onSessionSaveCache(String htmlString, String templateString, String dataString) {\n                assertEquals(SonicTestData.htmlString, htmlString);\n                assertEquals(SonicTestData.templateString, templateString);\n\n                JSONObject serverRspJson = null;\n                JSONObject testServerRspJson = null;\n                try {\n                    serverRspJson = new JSONObject(dataString);\n                    testServerRspJson = new JSONObject(SonicTestData.dataString);\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                }\n\n                String htmlSha1 = serverRspJson.optString(\"html-sha1\");\n                String templateTag1 = serverRspJson.optString(\"template-tag\");\n                assertEquals(etag, htmlSha1);\n                assertEquals(templateTag, templateTag1);\n                assertEquals(testServerRspJson.optString(\"data\").toString(), serverRspJson.optJSONObject(\"data\").toString());\n\n                if (finishLock.compareAndSet(false, true)) {\n                    synchronized (finishLock) {\n                        finishLock.notify();\n                    }\n                }\n            }\n\n            @Override\n            public void onSessionDestroy() {\n                if (destroyLock.compareAndSet(false, true)) {\n                    synchronized (destroyLock) {\n                        destroyLock.notify();\n                    }\n                }\n            }\n        });\n\n        mockLoadUrl();\n\n        mockInterceptRequest(SonicTestData.htmlString);\n\n        if (!finishLock.get()) {\n            synchronized (finishLock) {\n                finishLock.wait();\n            }\n        }\n\n        RecordedRequest request = server.takeRequest();\n        assertEquals(\"true\", request.getHeader(\"accept-diff\"));\n        assertTrue(TextUtils.isEmpty(request.getHeader(SonicSessionConnection.HTTP_HEAD_FILED_IF_NOT_MATCH)));\n        assertTrue(TextUtils.isEmpty(request.getHeader(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG)));\n    }\n\n}"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/SonicRuntimeImplTest.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n\nimport android.content.Context;\nimport android.os.Build;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.webkit.CookieManager;\nimport android.webkit.WebResourceResponse;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.util.List;\nimport java.util.Map;\n\nimport static org.junit.Assert.assertEquals;\n\n/**\n * the sonic host application must implement SonicRuntime to do right things.\n */\n\npublic class SonicRuntimeImplTest extends SonicRuntime {\n\n    public SonicRuntimeImplTest(Context context) {\n        super(context);\n    }\n\n    /**\n     * 获取用户UA信息\n     * @return\n     */\n    @Override\n    public String getUserAgent() {\n        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\";\n    }\n\n    /**\n     * 获取用户ID信息\n     * @return\n     */\n    @Override\n    public String getCurrentUserAccount() {\n        return \"sonic-junit-test\";\n    }\n\n    @Override\n    public String getCookie(String url) {\n        CookieManager cookieManager = CookieManager.getInstance();\n        return cookieManager.getCookie(url);\n    }\n\n    @Override\n    public void log(String tag, int level, String message) {\n        switch (level) {\n            case Log.ERROR:\n                Log.e(tag, message);\n                break;\n            case Log.INFO:\n                Log.i(tag, message);\n                break;\n            default:\n                Log.d(tag, message);\n        }\n    }\n\n    @Override\n    public Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map<String, String> headers) {\n        WebResourceResponse resourceResponse =  new WebResourceResponse(mimeType, encoding, data);\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            resourceResponse.setResponseHeaders(headers);\n        }\n        return resourceResponse;\n    }\n\n    @Override\n    public void showToast(CharSequence text, int duration) {\n\n    }\n\n    @Override\n    public void notifyError(SonicSessionClient client, String url, int errorCode) {\n        assertEquals(0, errorCode);\n    }\n\n    @Override\n    public boolean isSonicUrl(String url) {\n        return true;\n    }\n\n    @Override\n    public boolean setCookie(String url, List<String> cookies) {\n        if (!TextUtils.isEmpty(url) && cookies != null && cookies.size() > 0) {\n            CookieManager cookieManager = CookieManager.getInstance();\n            for (String cookie : cookies) {\n                cookieManager.setCookie(url, cookie);\n            }\n            return true;\n        }\n        return false;\n    }\n\n    @Override\n    public boolean isNetworkValid() {\n        return true;\n    }\n\n    @Override\n    public void postTaskToThread(Runnable task, long delayMillis) {\n        Thread thread = new Thread(task, \"SonicThread\");\n        thread.start();\n    }\n\n    @Override\n    public File getSonicCacheDir() {\n        return super.getSonicCacheDir();\n    }\n\n    @Override\n    public String getHostDirectAddress(String url) {\n        return null;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/SonicSessionClientImplTest.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Bundle;\n\nimport java.util.HashMap;\n\npublic class SonicSessionClientImplTest extends SonicSessionClient{\n\n    @Override\n    public void loadUrl(String url, Bundle extraData) {\n\n    }\n\n    @Override\n    public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {\n\n    }\n\n\n    @Override\n    public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap<String, String> headers) {\n\n    }\n\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/androidTest/java/com/tencent/sonic/sdk/SonicTestData.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\npublic interface SonicTestData {\n    String htmlString = \"<!DOCTYPE html>\\n\" +\n            \"<html lang=\\\"en\\\">\\n\" +\n            \"<head>\\n\" +\n            \"    <meta charset=\\\"UTF-8\\\">\\n\" +\n            \"    <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n\" +\n            \"    <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"ie=edge\\\">\\n\" +\n            \"    <script type=\\\"application/javascript\\\">\\n\" +\n            \"        var _pageTime = {};\\n\" +\n            \"        _pageTime.startTime = new Date;\\n\" +\n            \"    </script>\\n\" +\n            \"    <title>SONIC</title>\\n\" +\n            \"    <style>\\n\" +\n            \"        body {\\n\" +\n            \"            margin: 0;\\n\" +\n            \"            padding: 0;\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #777;\\n\" +\n            \"            margin-top: 20px;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper {\\n\" +\n            \"            padding: 0 12px;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper h1 {\\n\" +\n            \"            font-size: 18px;\\n\" +\n            \"            font-weight: 400;\\n\" +\n            \"            color: #000;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper h2 {\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #000;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper p {\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #777;\\n\" +\n            \"            line-height: 1.6em;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper img {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper table {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper table img {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic_des {display:none;}\\n\" +\n            \"    </style>\\n\" +\n            \"</head>\\n\" +\n            \"<body>\\n\" +\n            \"<div class=\\\"sonic-wrapper\\\">\\n\" +\n            \"    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\\n\" +\n            \"    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\\n\" +\n            \"    <span id=\\\"data1Content\\\">\\n\" +\n            \"    <!--sonicdiff-data1-->\\n\" +\n            \"    <p>示例：</p>\\n\" +\n            \"    <img src=\\\"//mc.vip.qq.com/img/img-1.png?max_age=2592000\\\" alt=\\\"\\\">\\n\" +\n            \"    <!--sonicdiff-data1-end-->\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des0\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>非Sonic模式 点击到页面打开耗时:<span id=\\\"pageTime0\\\"></span></h2>\\n\" +\n            \"        <p>普通直出的方式</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des1\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>首次访问 点击到页面打开耗时:<span id=\\\"pageTime1\\\"></span></h2>\\n\" +\n            \"        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des2\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>模版更新 点击到页面打开耗时:<span id=\\\"pageTime2\\\"></span></h2>\\n\" +\n            \"        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des3\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>数据更新 点击到页面打开耗时:<span id=\\\"pageTime3\\\"></span></h2>\\n\" +\n            \"        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des4\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>完全缓存 点击到页面打开耗时:<span id=\\\"pageTime4\\\"></span></h2>\\n\" +\n            \"        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"        <h2>页面打开速度效果对比</h2>\\n\" +\n            \"    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\\n\" +\n            \"\\n\" +\n            \"    <table>\\n\" +\n            \"        <tr>\\n\" +\n            \"            <td>原有直出页面：</td>\\n\" +\n            \"            <td>Sonic改造页面：</td>\\n\" +\n            \"        </tr>\\n\" +\n            \"        <tr>\\n\" +\n            \"            <td><img src=\\\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\\\" alt=\\\"\\\"></td>\\n\" +\n            \"            <td><img src=\\\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\\\" alt=\\\"\\\"></td>\\n\" +\n            \"        </tr>\\n\" +\n            \"    </table>\\n\" +\n            \"        <h2>Sonic实现原理简介</h2>\\n\" +\n            \"    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\\n\" +\n            \"</div>\\n\" +\n            \"<script>\\n\" +\n            \"    _pageTime.jsendtTime = new Date();\\n\" +\n            \"</script>\\n\" +\n            \"<script src=\\\"//open.mobile.qq.com/sdk/qqapi.js?_bid=152\\\"></script>\\n\" +\n            \"<script src=\\\"//imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\\\" id=\\\"seajsnode\\\"></script>\\n\" +\n            \"<script>\\n\" +\n            \"    seajs.config({\\n\" +\n            \"        base: location.protocol+'//imgcache.gtimg.cn/club/platform/examples/',\\n\" +\n            \"        localcache:{\\n\" +\n            \"            //浏览器缓存时间\\n\" +\n            \"            maxAge: 2592000,\\n\" +\n            \"            openLocalStorageCache: 0\\n\" +\n            \"        },\\n\" +\n            \"        maxFile : {\\n\" +\n            \"\\n\" +\n            \"        },\\n\" +\n            \"        debug:1,\\n\" +\n            \"        //别名\\n\" +\n            \"        alias:{\\n\" +\n            \"            'zepto': 'lib/zepto/zepto'\\n\" +\n            \"        },\\n\" +\n            \"        paths:{\\n\" +\n            \"            'lib' : location.protocol+'//imgcache.gtimg.cn/club/platform/lib'\\n\" +\n            \"        },\\n\" +\n            \"        manifest:{\\n\" +\n            \"            \\\"lib/zepto/zepto\\\": \\\"1.1.3\\\",\\n\" +\n            \"            \\\"lib/sonic/sonic\\\": \\\"3-1\\\"\\n\" +\n            \"        }\\n\" +\n            \"    });\\n\" +\n            \"\\n\" +\n            \"    seajs.use([\\\"zepto\\\", \\\"lib/sonic/sonic\\\"],function($, sonic){\\n\" +\n            \"        /**\\n\" +\n            \"         * 后置函数 sonic或普通模式 执行页面初始化等操作\\n\" +\n            \"         */\\n\" +\n            \"        function afterInit(sonicStatus){\\n\" +\n            \"            $('.sonic_des').css('display', 'none');\\n\" +\n            \"            $('#des'+sonicStatus).css('display', 'block');\\n\" +\n            \"            //耗时分析(上报)\\n\" +\n            \"            var performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\\n\" +\n            \"            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\\n\" +\n            \"            $(\\\"#pageTime\\\"+sonicStatus).text(pageTime+'ms');\\n\" +\n            \"        }\\n\" +\n            \"                /**\\n\" +\n            \"         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\\n\" +\n            \"         * @param sonicStatus\\n\" +\n            \"         * @param reportSonicStatus\\n\" +\n            \"         * @param sonicUpdateData\\n\" +\n            \"         */\\n\" +\n            \"        window.sonicStartTime = new Date;\\n\" +\n            \"        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\\n\" +\n            \"        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\\n\" +\n            \"            if(sonicStatus == 1){\\n\" +\n            \"                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\\n\" +\n            \"            }else if(sonicStatus == 2){\\n\" +\n            \"\\n\" +\n            \"            }else if(sonicStatus == 3){\\n\" +\n            \"                //局部刷新的时候需要更新页面的数据块和一些JS操作\\n\" +\n            \"                var html = '';\\n\" +\n            \"                var id = '';\\n\" +\n            \"                var elementObj = '';\\n\" +\n            \"                for(var key in sonicUpdateData){\\n\" +\n            \"                    id = key.substring(1,key.length-1);\\n\" +\n            \"                    html = sonicUpdateData[key];\\n\" +\n            \"                    elementObj = document.getElementById(id+'Content');\\n\" +\n            \"                    elementObj.innerHTML = html;\\n\" +\n            \"                }\\n\" +\n            \"\\n\" +\n            \"            }else if(sonicStatus == 4){\\n\" +\n            \"\\n\" +\n            \"            }\\n\" +\n            \"            afterInit(reportSonicStatus);\\n\" +\n            \"        });\\n\" +\n            \"            });\\n\" +\n            \"\\n\" +\n            \"</script>\\n\" +\n            \"</body>\\n\" +\n            \"</html>\";\n\n    String templateString = \"<!DOCTYPE html>\\n\" +\n            \"<html lang=\\\"en\\\">\\n\" +\n            \"<head>\\n\" +\n            \"    <meta charset=\\\"UTF-8\\\">\\n\" +\n            \"    <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n\" +\n            \"    <meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"ie=edge\\\">\\n\" +\n            \"    <script type=\\\"application/javascript\\\">\\n\" +\n            \"        var _pageTime = {};\\n\" +\n            \"        _pageTime.startTime = new Date;\\n\" +\n            \"    </script>\\n\" +\n            \"    {title}\\n\" +\n            \"    <style>\\n\" +\n            \"        body {\\n\" +\n            \"            margin: 0;\\n\" +\n            \"            padding: 0;\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #777;\\n\" +\n            \"            margin-top: 20px;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper {\\n\" +\n            \"            padding: 0 12px;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper h1 {\\n\" +\n            \"            font-size: 18px;\\n\" +\n            \"            font-weight: 400;\\n\" +\n            \"            color: #000;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper h2 {\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #000;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper p {\\n\" +\n            \"            font-size: 14px;\\n\" +\n            \"            color: #777;\\n\" +\n            \"            line-height: 1.6em;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper img {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper table {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic-wrapper table img {\\n\" +\n            \"            width: 100%;\\n\" +\n            \"        }\\n\" +\n            \"        .sonic_des {display:none;}\\n\" +\n            \"    </style>\\n\" +\n            \"</head>\\n\" +\n            \"<body>\\n\" +\n            \"<div class=\\\"sonic-wrapper\\\">\\n\" +\n            \"    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\\n\" +\n            \"    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\\n\" +\n            \"    <span id=\\\"data1Content\\\">\\n\" +\n            \"    {data1}\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des0\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>非Sonic模式 点击到页面打开耗时:<span id=\\\"pageTime0\\\"></span></h2>\\n\" +\n            \"        <p>普通直出的方式</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des1\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>首次访问 点击到页面打开耗时:<span id=\\\"pageTime1\\\"></span></h2>\\n\" +\n            \"        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des2\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>模版更新 点击到页面打开耗时:<span id=\\\"pageTime2\\\"></span></h2>\\n\" +\n            \"        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des3\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>数据更新 点击到页面打开耗时:<span id=\\\"pageTime3\\\"></span></h2>\\n\" +\n            \"        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"    <span id=\\\"des4\\\" class=\\\"sonic_des\\\">\\n\" +\n            \"        <h2>完全缓存 点击到页面打开耗时:<span id=\\\"pageTime4\\\"></span></h2>\\n\" +\n            \"        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\\n\" +\n            \"    </span>\\n\" +\n            \"        <h2>页面打开速度效果对比</h2>\\n\" +\n            \"    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\\n\" +\n            \"\\n\" +\n            \"    <table>\\n\" +\n            \"        <tr>\\n\" +\n            \"            <td>原有直出页面：</td>\\n\" +\n            \"            <td>Sonic改造页面：</td>\\n\" +\n            \"        </tr>\\n\" +\n            \"        <tr>\\n\" +\n            \"            <td><img src=\\\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\\\" alt=\\\"\\\"></td>\\n\" +\n            \"            <td><img src=\\\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\\\" alt=\\\"\\\"></td>\\n\" +\n            \"        </tr>\\n\" +\n            \"    </table>\\n\" +\n            \"        <h2>Sonic实现原理简介</h2>\\n\" +\n            \"    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\\n\" +\n            \"</div>\\n\" +\n            \"<script>\\n\" +\n            \"    _pageTime.jsendtTime = new Date();\\n\" +\n            \"</script>\\n\" +\n            \"<script src=\\\"//open.mobile.qq.com/sdk/qqapi.js?_bid=152\\\"></script>\\n\" +\n            \"<script src=\\\"//imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\\\" id=\\\"seajsnode\\\"></script>\\n\" +\n            \"<script>\\n\" +\n            \"    seajs.config({\\n\" +\n            \"        base: location.protocol+'//imgcache.gtimg.cn/club/platform/examples/',\\n\" +\n            \"        localcache:{\\n\" +\n            \"            //浏览器缓存时间\\n\" +\n            \"            maxAge: 2592000,\\n\" +\n            \"            openLocalStorageCache: 0\\n\" +\n            \"        },\\n\" +\n            \"        maxFile : {\\n\" +\n            \"\\n\" +\n            \"        },\\n\" +\n            \"        debug:1,\\n\" +\n            \"        //别名\\n\" +\n            \"        alias:{\\n\" +\n            \"            'zepto': 'lib/zepto/zepto'\\n\" +\n            \"        },\\n\" +\n            \"        paths:{\\n\" +\n            \"            'lib' : location.protocol+'//imgcache.gtimg.cn/club/platform/lib'\\n\" +\n            \"        },\\n\" +\n            \"        manifest:{\\n\" +\n            \"            \\\"lib/zepto/zepto\\\": \\\"1.1.3\\\",\\n\" +\n            \"            \\\"lib/sonic/sonic\\\": \\\"3-1\\\"\\n\" +\n            \"        }\\n\" +\n            \"    });\\n\" +\n            \"\\n\" +\n            \"    seajs.use([\\\"zepto\\\", \\\"lib/sonic/sonic\\\"],function($, sonic){\\n\" +\n            \"        /**\\n\" +\n            \"         * 后置函数 sonic或普通模式 执行页面初始化等操作\\n\" +\n            \"         */\\n\" +\n            \"        function afterInit(sonicStatus){\\n\" +\n            \"            $('.sonic_des').css('display', 'none');\\n\" +\n            \"            $('#des'+sonicStatus).css('display', 'block');\\n\" +\n            \"            //耗时分析(上报)\\n\" +\n            \"            var performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\\n\" +\n            \"            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\\n\" +\n            \"            $(\\\"#pageTime\\\"+sonicStatus).text(pageTime+'ms');\\n\" +\n            \"        }\\n\" +\n            \"                /**\\n\" +\n            \"         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\\n\" +\n            \"         * @param sonicStatus\\n\" +\n            \"         * @param reportSonicStatus\\n\" +\n            \"         * @param sonicUpdateData\\n\" +\n            \"         */\\n\" +\n            \"        window.sonicStartTime = new Date;\\n\" +\n            \"        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\\n\" +\n            \"        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\\n\" +\n            \"            if(sonicStatus == 1){\\n\" +\n            \"                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\\n\" +\n            \"            }else if(sonicStatus == 2){\\n\" +\n            \"\\n\" +\n            \"            }else if(sonicStatus == 3){\\n\" +\n            \"                //局部刷新的时候需要更新页面的数据块和一些JS操作\\n\" +\n            \"                var html = '';\\n\" +\n            \"                var id = '';\\n\" +\n            \"                var elementObj = '';\\n\" +\n            \"                for(var key in sonicUpdateData){\\n\" +\n            \"                    id = key.substring(1,key.length-1);\\n\" +\n            \"                    html = sonicUpdateData[key];\\n\" +\n            \"                    elementObj = document.getElementById(id+'Content');\\n\" +\n            \"                    elementObj.innerHTML = html;\\n\" +\n            \"                }\\n\" +\n            \"\\n\" +\n            \"            }else if(sonicStatus == 4){\\n\" +\n            \"\\n\" +\n            \"            }\\n\" +\n            \"            afterInit(reportSonicStatus);\\n\" +\n            \"        });\\n\" +\n            \"            });\\n\" +\n            \"\\n\" +\n            \"</script>\\n\" +\n            \"</body>\\n\" +\n            \"</html>\";\n\n    String dataString = \"{\\\"data\\\":{\\\"{data1}\\\":\\\"<!--sonicdiff-data1-->\\\\n    <p>示例：<\\\\/p>\\\\n    <img src=\\\\\\\"\\\\/\\\\/mc.vip.qq.com\\\\/img\\\\/img-1.png?max_age=2592000\\\\\\\" alt=\\\\\\\"\\\\\\\">\\\\n    <!--sonicdiff-data1-end-->\\\",\\\"{title}\\\":\\\"<title>SONIC<\\\\/title>\\\"},\\\"html-sha1\\\":\\\"\\\",\\\"template-tag\\\":\\\"\\\"}\";\n\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/AndroidManifest.xml",
    "content": "<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.tencent.sonic.sdk\">\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n</manifest>\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/QuickSonicSession.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport org.json.JSONObject;\n\nimport java.io.File;\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n/**\n *\n * A subclass of SonicSession.\n * QuickSonicSession mainly uses {@link SonicSessionClient#loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)}\n * to load data. Sometime, it will use {@link SonicSessionClient#loadUrl(String, Bundle)} instead. By using\n * {@link SonicSessionClient#loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)}, WebView will\n * quickly load web pages without the network affecting.\n *\n * <p>\n *  ATTENTION:\n *  Standard WebView don't have head information (such as csp) when it calls\n *  {@link SonicSessionClient#loadDataWithBaseUrlAndHeader(String, String, String, String, String, HashMap)} method.\n *  So this session mode may cause a security risk. However, you can put the csp contents into the html to avoid this risk caused by the lack of csp.\n *\n * <p>\n * See also {@link StandardSonicSession}\n */\n\npublic class QuickSonicSession extends SonicSession implements Handler.Callback {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"QuickSonicSession\";\n\n    /**\n     * The beginning of message\n     */\n    private static final int CLIENT_CORE_MSG_BEGIN = COMMON_MSG_END;\n\n    /**\n     * Message type : this message is sent after verify local data.\n     * This message may be removed before other messages being sent,such as <code>CLIENT_CORE_MSG_DATA_UPDATE</code>\n     * message.\n     */\n    private static final int CLIENT_CORE_MSG_PRE_LOAD = CLIENT_CORE_MSG_BEGIN + 1;\n\n    /**\n     * Message type : this message is sent after http(s) response when local\n     * data does not exist.\n     */\n    private static final int CLIENT_CORE_MSG_FIRST_LOAD = CLIENT_CORE_MSG_BEGIN + 2;\n\n    /**\n     * Message type : this message is sent after http(s) response when the\n     * local template content is the same as the server template.\n     */\n    private static final int CLIENT_CORE_MSG_DATA_UPDATE = CLIENT_CORE_MSG_BEGIN + 3;\n\n    /**\n     * Message type : this message is sent after http(s) response when the\n     * local template content is not the same as the server template.\n     */\n    private static final int CLIENT_CORE_MSG_TEMPLATE_CHANGE = CLIENT_CORE_MSG_BEGIN + 4;\n\n    /**\n     * Message type : this message is sent when http(s) connect fail.\n     */\n    private static final int CLIENT_CORE_MSG_CONNECTION_ERROR = CLIENT_CORE_MSG_BEGIN + 5;\n\n    /**\n     * Message type : this message is sent when the \"cache-offline\" content\n     * of the header information is \"http\".This means sonic server unavailable.\n     */\n    private static final int CLIENT_CORE_MSG_SERVICE_UNAVAILABLE = CLIENT_CORE_MSG_BEGIN + 6;\n\n    /**\n     * The end of message. The message which is not in the message range would not be handle.\n     */\n    private static final int CLIENT_CORE_MSG_END = CLIENT_CORE_MSG_SERVICE_UNAVAILABLE + 1;\n\n    /**\n     * The pending message : before client ready, sonic will store the latest message to pendingClientCoreMessage.\n     * If this pendingClientCoreMessage not null, sonic will handle this message when client ready.\n     */\n    private Message pendingClientCoreMessage;\n\n    /**\n     * Preload message type : local data does not exist.\n     */\n    private static final int PRE_LOAD_NO_CACHE = 1;\n\n    /**\n     * Preload message type : local data exists.\n     */\n    private static final int PRE_LOAD_WITH_CACHE = 2;\n\n    /**\n     * First loaded message type : server data has not finished reading when send this message.\n     */\n    private static final int FIRST_LOAD_NO_DATA = 1;\n\n    /**\n     * First loaded message type : server data has finished reading when send this message.\n     */\n    private static final int FIRST_LOAD_WITH_DATA = 2;\n\n    /**\n     * Whether refresh page content when template change or not.\n     */\n    private static final int TEMPLATE_CHANGE_REFRESH = 1;\n\n    /**\n     * Whether client invokes loadUrl method or not.\n     */\n    private final AtomicBoolean wasLoadUrlInvoked = new AtomicBoolean(false);\n\n    /**\n     * Whether client invokes loadDataWithBaseUrlAndHeader method or not.\n     */\n    private final AtomicBoolean wasLoadDataInvoked = new AtomicBoolean(false);\n\n\n    QuickSonicSession(String id, String url, SonicSessionConfig config) {\n        super(id, url, config);\n    }\n\n    @Override\n    public boolean handleMessage(Message msg) {\n\n        // fix issue[https://github.com/Tencent/VasSonic/issues/89]\n        if (super.handleMessage(msg)) {\n            return true; // handled by super class\n        }\n\n        if (CLIENT_CORE_MSG_BEGIN < msg.what && msg.what < CLIENT_CORE_MSG_END && !clientIsReady.get()) {\n            pendingClientCoreMessage = Message.obtain(msg);\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleMessage: client not ready, core msg = \" + msg.what + \".\");\n            return true;\n        }\n\n        switch (msg.what) {\n            case CLIENT_CORE_MSG_PRE_LOAD:\n                handleClientCoreMessage_PreLoad(msg);\n                break;\n            case CLIENT_CORE_MSG_FIRST_LOAD:\n                handleClientCoreMessage_FirstLoad(msg);\n                break;\n            case CLIENT_CORE_MSG_CONNECTION_ERROR:\n                handleClientCoreMessage_ConnectionError(msg);\n                break;\n            case CLIENT_CORE_MSG_SERVICE_UNAVAILABLE:\n                handleClientCoreMessage_ServiceUnavailable(msg);\n                break;\n            case CLIENT_CORE_MSG_DATA_UPDATE:\n                handleClientCoreMessage_DataUpdate(msg);\n                break;\n            case CLIENT_CORE_MSG_TEMPLATE_CHANGE:\n                handleClientCoreMessage_TemplateChange(msg);\n                break;\n            case CLIENT_MSG_NOTIFY_RESULT:\n                setResult(msg.arg1, msg.arg2, true);\n                break;\n            case CLIENT_MSG_ON_WEB_READY: {\n                diffDataCallback = (SonicDiffDataCallback) msg.obj;\n                setResult(srcResultCode, finalResultCode, true);\n                break;\n            }\n\n            default: {\n                if (SonicUtils.shouldLog(Log.DEBUG)) {\n                    SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") can not  recognize refresh type: \" + msg.what);\n                }\n                return false;\n            }\n\n        }\n        return true;\n    }\n\n    /**\n     * Handle the connection error message. Client will invoke loadUrl method if this method is not\n     * invoked before, or do nothing.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_ConnectionError(Message msg) {\n        if (wasLoadUrlInvoked.compareAndSet(false, true)) {\n            if (SonicUtils.shouldLog(Log.INFO)) {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_ConnectionError: load src url.\");\n            }\n            sessionClient.loadUrl(srcUrl, null);\n        }\n    }\n\n    /**\n     * Handle the server unavailable message. Client will invoke loadUrl method if this method is not\n     * invoked before, or do nothing.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_ServiceUnavailable(Message msg) {\n        if (wasLoadUrlInvoked.compareAndSet(false, true)) {\n            if (SonicUtils.shouldLog(Log.INFO)) {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_ServiceUnavailable:load src url.\");\n            }\n            sessionClient.loadUrl(srcUrl, null);\n        }\n    }\n\n    /**\n     * Handle the preload message. If the type of this message is <code>PRE_LOAD_NO_CACHE</code>  and client did not\n     * initiate request for load url,client will invoke loadUrl method. If the type of this message is\n     * <code>PRE_LOAD_WITH_CACHE</code> and and client did not initiate request for loadUrl,client will load local data.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_PreLoad(Message msg) {\n        switch (msg.arg1) {\n            case PRE_LOAD_NO_CACHE: {\n                if (wasLoadUrlInvoked.compareAndSet(false, true)) {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleClientCoreMessage_PreLoad:PRE_LOAD_NO_CACHE load url.\");\n                    sessionClient.loadUrl(srcUrl, null);\n                } else {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleClientCoreMessage_PreLoad:wasLoadUrlInvoked = true.\");\n                }\n            }\n            break;\n            case PRE_LOAD_WITH_CACHE: {\n                if (wasLoadDataInvoked.compareAndSet(false, true)) {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleClientCoreMessage_PreLoad:PRE_LOAD_WITH_CACHE load data.\");\n                    String html = (String) msg.obj;\n                    sessionClient.loadDataWithBaseUrlAndHeader(srcUrl, html, \"text/html\",\n                            SonicUtils.DEFAULT_CHARSET, srcUrl, getCacheHeaders());\n                } else {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleClientCoreMessage_PreLoad:wasLoadDataInvoked = true.\");\n                }\n            }\n            break;\n        }\n    }\n\n    /**\n     * Handle first load message.If the type of this message is <code>FIRST_LOAD_NO_DATA</code> and client did not\n     * initiated request for load url,the quickSonicSession will do nothing but assign a value to sonic by invoke\n     * setResult method.\n     *\n     * If the type of this message is <code>FIRST_LOAD_WITH_DATA</code> and client did not initiated request for load url,\n     * client will load the html content that comes from server . In this case, the value of <code>finalResultCode</code>\n     * will be set as <code>SONIC_RESULT_CODE_HIT_CACHE</code>.If client has a request for load url before,the value of\n     * <code>finalResultCode</code> will be set as <code>SONIC_RESULT_CODE_FIRST_LOAD</code>.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_FirstLoad(Message msg) {\n        switch (msg.arg1) {\n            case FIRST_LOAD_NO_DATA: {\n                if (wasInterceptInvoked.get()) {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleClientCoreMessage_FirstLoad:FIRST_LOAD_NO_DATA.\");\n                    setResult(SONIC_RESULT_CODE_FIRST_LOAD, SONIC_RESULT_CODE_FIRST_LOAD, true);\n                } else {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleClientCoreMessage_FirstLoad:url was not invoked.\");\n                }\n            }\n            break;\n            case FIRST_LOAD_WITH_DATA: {\n                if (wasLoadUrlInvoked.compareAndSet(false, true)) {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleClientCoreMessage_FirstLoad:oh yeah, first load hit 304.\");\n                    sessionClient.loadDataWithBaseUrlAndHeader(srcUrl, (String) msg.obj, \"text/html\",\n                            getCharsetFromHeaders(), srcUrl, getHeaders());\n                    setResult(SONIC_RESULT_CODE_FIRST_LOAD, SONIC_RESULT_CODE_HIT_CACHE, false);\n                } else {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") FIRST_LOAD_WITH_DATA load url was invoked.\");\n                    setResult(SONIC_RESULT_CODE_FIRST_LOAD, SONIC_RESULT_CODE_FIRST_LOAD, true);\n                }\n            }\n            break;\n        }\n    }\n\n    /**\n     * Handle data update message. If client had loaded local data before, sonic will store the difference data between\n     * server and local data to <code>pendingDiffData</code>. The value of <code>finalResultCode</code> will be set as\n     * <code>SONIC_RESULT_CODE_DATA_UPDATE</code>.\n     *\n     * If client had not loaded local data before, client will load new html content which is from the combination of local\n     * template content and server data.The value of <code>finalResultCode</code> will be set as <code>SONIC_RESULT_CODE_HIT_CACHE</code>.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_DataUpdate(Message msg) {\n        String htmlString = (String) msg.obj;\n        String diffData = msg.getData().getString(DATA_UPDATE_BUNDLE_PARAMS_DIFF);\n        if (wasLoadDataInvoked.get()) {\n            pendingDiffData = diffData;\n            if (!TextUtils.isEmpty(diffData)) {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_DataUpdate:try to notify web callback.\");\n                setResult(SONIC_RESULT_CODE_DATA_UPDATE, SONIC_RESULT_CODE_DATA_UPDATE, true);\n            } else {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_DataUpdate:diffData is null, cache-offline = store , do not refresh.\");\n                setResult(SONIC_RESULT_CODE_DATA_UPDATE, SONIC_RESULT_CODE_HIT_CACHE, true);\n            }\n            return;\n        } else {\n            if (!TextUtils.isEmpty(htmlString)) {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_DataUpdate:oh yeah data update hit 304, now clear pending data ->\" + (null != pendingDiffData) + \".\");\n                pendingDiffData = null;\n                sessionClient.loadDataWithBaseUrlAndHeader(srcUrl, htmlString, \"text/html\", getCharsetFromHeaders(), srcUrl, getHeaders());\n                setResult(SONIC_RESULT_CODE_DATA_UPDATE, SONIC_RESULT_CODE_HIT_CACHE, false);\n                return;\n            }\n        }\n        SonicUtils.log(TAG, Log.ERROR, \"handleClientCoreMessage_DataUpdate error:call load url.\");\n        sessionClient.loadUrl(srcUrl, null);\n        setResult(SONIC_RESULT_CODE_DATA_UPDATE, SONIC_RESULT_CODE_FIRST_LOAD, false);\n    }\n\n    /**\n     * Handle template change message.If client had loaded local data before and the page need refresh,\n     * client will load data or loadUrl according to whether the message has latest data. And the\n     * <code>finalResultCode</code> will be set as <code>SONIC_RESULT_CODE_TEMPLATE_CHANGE</code>.\n     *\n     * If client had not loaded local data before, client will load the latest html content which comes\n     * from server and the <code>finalResultCode</code> will be set as <code>SONIC_RESULT_CODE_HIT_CACHE</code>.\n     *\n     * @param msg The message\n     */\n    private void handleClientCoreMessage_TemplateChange(Message msg) {\n        SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange wasLoadDataInvoked = \" + wasLoadDataInvoked.get() + \",msg arg1 = \" + msg.arg1);\n\n        if (wasLoadDataInvoked.get()) {\n            if (TEMPLATE_CHANGE_REFRESH == msg.arg1) {\n                String html = (String) msg.obj;\n                if (TextUtils.isEmpty(html)) {\n                    SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:load url with preload=2, webCallback is null? ->\" + (null != diffDataCallback));\n                    sessionClient.loadUrl(srcUrl, null);\n                } else {\n                    SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:load data.\");\n                    sessionClient.loadDataWithBaseUrlAndHeader(srcUrl, html, \"text/html\",\n                            getCharsetFromHeaders(), srcUrl, getHeaders());\n                }\n                setResult(SONIC_RESULT_CODE_TEMPLATE_CHANGE, SONIC_RESULT_CODE_TEMPLATE_CHANGE, false);\n            } else {\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:not refresh.\");\n                setResult(SONIC_RESULT_CODE_TEMPLATE_CHANGE, SONIC_RESULT_CODE_HIT_CACHE, true);\n            }\n        } else {\n            SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:oh yeah template change hit 304.\");\n            if (msg.obj instanceof String) {\n                String html = (String) msg.obj;\n                sessionClient.loadDataWithBaseUrlAndHeader(srcUrl, html, \"text/html\",\n                        getCharsetFromHeaders(), srcUrl, getHeaders());\n                setResult(SONIC_RESULT_CODE_TEMPLATE_CHANGE, SONIC_RESULT_CODE_HIT_CACHE, false);\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"handleClientCoreMessage_TemplateChange error:call load url.\");\n                sessionClient.loadUrl(srcUrl, null);\n                setResult(SONIC_RESULT_CODE_TEMPLATE_CHANGE, SONIC_RESULT_CODE_FIRST_LOAD, false);\n            }\n        }\n        diffDataCallback = null;\n        mainHandler.removeMessages(CLIENT_MSG_ON_WEB_READY);\n    }\n\n    /**\n     * Handle load local cache of html if exist.\n     * This handle is called before connection.\n     *\n     * @param cacheHtml local cache of html\n     */\n    @Override\n    protected void handleFlow_LoadLocalCache(String cacheHtml) {\n        Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_PRE_LOAD);\n        if (!TextUtils.isEmpty(cacheHtml)) {\n            msg.arg1 = PRE_LOAD_WITH_CACHE;\n            msg.obj = cacheHtml;\n        } else {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") runSonicFlow has no cache, do first load flow.\");\n            msg.arg1 = PRE_LOAD_NO_CACHE;\n        }\n        mainHandler.sendMessage(msg);\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionLoadLocalCache(cacheHtml);\n            }\n        }\n    }\n\n    public boolean onWebReady(SonicDiffDataCallback callback) {\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onWebReady: webCallback has set ? ->\" + (null != diffDataCallback));\n\n        if (null != diffDataCallback) {\n            this.diffDataCallback = null;\n            SonicUtils.log(TAG, Log.WARN, \"session(\" + sId + \") onWebReady: call more than once.\");\n        }\n\n        Message msg = Message.obtain();\n        msg.what = CLIENT_MSG_ON_WEB_READY;\n        msg.obj = callback;\n        mainHandler.sendMessage(msg);\n\n        return true;\n    }\n\n    public boolean onClientReady() {\n        if (clientIsReady.compareAndSet(false, true)) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClientReady: have pending client core message ? -> \" + (null != pendingClientCoreMessage) + \".\");\n            if (null != pendingClientCoreMessage) {\n                Message message = pendingClientCoreMessage;\n                pendingClientCoreMessage = null;\n                handleMessage(message);\n            } else if (STATE_NONE == sessionState.get()) {\n                start();\n            }\n            return true;\n        }\n        return false;\n    }\n\n    protected Object onRequestResource(String url) {\n        if (wasInterceptInvoked.get() || !isMatchCurrentUrl(url)) {\n            return null;\n        }\n\n        if (!wasInterceptInvoked.compareAndSet(false, true)) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \")  onClientRequestResource error:Intercept was already invoked, url = \" + url);\n            return null;\n        }\n\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \")  onClientRequestResource:url = \" + url);\n        }\n\n        long startTime = System.currentTimeMillis();\n        if (sessionState.get() == STATE_RUNNING) {\n            synchronized (sessionState) {\n                try {\n                    if (sessionState.get() == STATE_RUNNING) {\n                        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") now wait for pendingWebResourceStream!\");\n                        sessionState.wait(30 * 1000);\n                    }\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") wait for pendingWebResourceStream failed\" + e.getMessage());\n                }\n            }\n        } else {\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") is not in running state: \" + sessionState);\n            }\n        }\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") have pending stream? -> \" + (pendingWebResourceStream != null) + \", cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n\n        if (null != pendingWebResourceStream) {\n            Object webResourceResponse;\n            if (!isDestroyedOrWaitingForDestroy()) {\n                String mime = SonicUtils.getMime(srcUrl);\n                webResourceResponse = SonicEngine.getInstance().getRuntime().createWebResourceResponse(mime,\n                        getCharsetFromHeaders(), pendingWebResourceStream, getHeaders());\n            } else {\n                webResourceResponse = null;\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") onClientRequestResource error: session is destroyed!\");\n\n            }\n            pendingWebResourceStream = null;\n            return webResourceResponse;\n        }\n\n        return null;\n    }\n\n    protected void handleFlow_HttpError(int responseCode){\n        if (config.RELOAD_IN_BAD_NETWORK) {\n            mainHandler.removeMessages(CLIENT_CORE_MSG_PRE_LOAD);\n            Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_CONNECTION_ERROR);\n            msg.arg1 = responseCode;\n            mainHandler.sendMessage(msg);\n        }\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionHttpError(responseCode);\n            }\n        }\n    }\n\n    protected void handleFlow_ServiceUnavailable(){\n        mainHandler.removeMessages(CLIENT_CORE_MSG_PRE_LOAD);\n        Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_SERVICE_UNAVAILABLE);\n        mainHandler.sendMessage(msg);\n\n    }\n\t\n    /**\n     *\n     * In this case sonic will always read the new data from the server until the local page finish.\n     * If the server data is read finished, sonic will send a <code>CLIENT_CORE_MSG_TEMPLATE_CHANGE</code>\n     * message.\n     *\n     * If the server data is not read finished sonic will split the read and unread data into a\n     * bridgedStream{@link SonicSessionStream}. When the client initiates a resource interception,\n     * sonic will provide the bridgedStream to the kernel.\n     *\n     * <p>\n     * If need save and separate data, sonic will save the server data and separate the server data to template and data.\n     *  @param newHtml html content from server\n     *\n     */\n    protected void handleFlow_TemplateChange(String newHtml) {\n        try {\n            SonicUtils.log(TAG, Log.INFO, \"handleFlow_TemplateChange.\");\n            String htmlString = newHtml;\n            long startTime = System.currentTimeMillis();\n\n            // When serverRsp is empty\n            if (TextUtils.isEmpty(htmlString)) {\n                pendingWebResourceStream = server.getResponseStream(wasOnPageFinishInvoked);\n                if (pendingWebResourceStream == null) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_TemplateChange error:server.getResponseStream = null!\");\n                    return;\n                }\n\n                htmlString = server.getResponseData(clientIsReload.get());\n            }\n\n            String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n\n            if (!clientIsReload.get()) {\n                // send CLIENT_CORE_MSG_TEMPLATE_CHANGE message\n                mainHandler.removeMessages(CLIENT_CORE_MSG_PRE_LOAD);\n                Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_TEMPLATE_CHANGE);\n                msg.obj = htmlString;\n                if (!OFFLINE_MODE_STORE.equals(cacheOffline)) {\n                    msg.arg1 = TEMPLATE_CHANGE_REFRESH;\n                }\n                mainHandler.sendMessage(msg);\n            } else {\n                Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n                msg.arg1 = SONIC_RESULT_CODE_TEMPLATE_CHANGE;\n                msg.arg2 = SONIC_RESULT_CODE_TEMPLATE_CHANGE;\n                mainHandler.sendMessage(msg);\n            }\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionTemplateChanged(htmlString);\n                }\n            }\n\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") read byte stream cost \" + (System.currentTimeMillis() - startTime) + \" ms, wasInterceptInvoked: \" + wasInterceptInvoked.get());\n            }\n\n            //save and separate data\n            if (SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n                switchState(STATE_RUNNING, STATE_READY, true);\n                if (!TextUtils.isEmpty(htmlString)) {\n                    postTaskToSaveSonicCache(htmlString);\n                }\n            } else if (OFFLINE_MODE_FALSE.equals(cacheOffline)) {\n                SonicUtils.removeSessionCache(id);\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:offline mode is 'false', so clean cache.\");\n            } else {\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_TemplateChange:offline->\" + cacheOffline + \" , so do not need cache to file.\");\n            }\n\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") handleFlow_TemplateChange error:\" + e.getMessage());\n        }\n    }\n\n    /**\n     *\n     * In this case sonic will always read the new data from the server until the client\n     * initiates a resource interception.\n     *\n     * If the server data is read finished, sonic will send <code>CLIENT_CORE_MSG_FIRST_LOAD</code>\n     * message with the new html content from server.\n     *\n     * If the server data is not read finished sonic will split the read and unread data into\n     * a bridgedStream{@link SonicSessionStream}.When client initiates a resource interception,\n     * sonic will provide the bridgedStream to the kernel.\n     *\n     * <p>\n     * If need save and separate data, sonic will save the server data and separate the server data\n     * to template and data.\n     *\n     */\n    protected void handleFlow_FirstLoad() {\n        pendingWebResourceStream = server.getResponseStream(wasInterceptInvoked);\n        if (null == pendingWebResourceStream) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_FirstLoad error:server.getResponseStream is null!\");\n            return;\n        }\n\n        String htmlString = server.getResponseData(false);\n\n\n        boolean hasCompletionData = !TextUtils.isEmpty(htmlString);\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_FirstLoad:hasCompletionData=\" + hasCompletionData + \".\");\n\n        mainHandler.removeMessages(CLIENT_CORE_MSG_PRE_LOAD);\n        Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_FIRST_LOAD);\n        msg.obj = htmlString;\n        msg.arg1 = hasCompletionData ? FIRST_LOAD_WITH_DATA : FIRST_LOAD_NO_DATA;\n        mainHandler.sendMessage(msg);\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionFirstLoad(htmlString);\n            }\n        }\n\n        String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n        if (SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n            if (hasCompletionData && !wasLoadUrlInvoked.get() && !wasInterceptInvoked.get()) { // Otherwise will save cache in com.tencent.sonic.sdk.SonicSession.onServerClosed\n                switchState(STATE_RUNNING, STATE_READY, true);\n                postTaskToSaveSonicCache(htmlString);\n            }\n        } else {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_FirstLoad:offline->\" + cacheOffline + \" , so do not need cache to file.\");\n        }\n    }\n\n    /**\n     *\n     * In this case sonic obtains the difference data between the server and the local\n     * data first,then sonic will build the template and server data into html,\n     * then send a <code>CLIENT_CORE_MSG_DATA_UPDATE</code> message.\n     *\n     * @param serverRsp Server response data\n     */\n    protected void handleFlow_DataUpdate(String serverRsp) {\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: start.\");\n\n        try {\n            String htmlString = null;\n\n            if (TextUtils.isEmpty(serverRsp)) {\n                serverRsp = server.getResponseData(true);\n            } else {\n                htmlString = server.getResponseData(false);\n            }\n\n            if (TextUtils.isEmpty(serverRsp)) {\n                SonicUtils.log(TAG, Log.ERROR, \"handleFlow_DataUpdate:getResponseData error.\");\n                return;\n            }\n\n\n            final String eTag = server.getResponseHeaderField(getCustomHeadFieldEtagKey());\n            final String templateTag = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n\n            String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n\n            long startTime = System.currentTimeMillis();\n            JSONObject serverRspJson = new JSONObject(serverRsp);\n            final JSONObject serverDataJson = serverRspJson.optJSONObject(\"data\");\n            String htmlSha1 = serverRspJson.optString(\"html-sha1\");\n\n            JSONObject diffDataJson = SonicUtils.getDiffData(id, serverDataJson);\n\n            Bundle diffDataBundle = new Bundle();\n            if (null != diffDataJson) {\n                diffDataBundle.putString(DATA_UPDATE_BUNDLE_PARAMS_DIFF, diffDataJson.toString());\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"handleFlow_DataUpdate:getDiffData error.\");\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_MERGE_DIFF_DATA_FAIL);\n            }\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"handleFlow_DataUpdate:getDiffData cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n\n            boolean hasSentDataUpdateMessage = false;\n            if (wasLoadDataInvoked.get()) {\n                if (SonicUtils.shouldLog(Log.INFO)) {\n                    SonicUtils.log(TAG, Log.INFO, \"handleFlow_DataUpdate:loadData was invoked, quick notify web data update.\");\n                }\n                Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_DATA_UPDATE);\n                if (!OFFLINE_MODE_STORE.equals(cacheOffline)) {\n                    msg.setData(diffDataBundle);\n                }\n                mainHandler.sendMessage(msg);\n                hasSentDataUpdateMessage = true;\n            }\n\n            startTime = System.currentTimeMillis();\n            if (TextUtils.isEmpty(htmlString)) {\n                htmlString = SonicUtils.buildHtml(id, serverDataJson, htmlSha1, serverRsp.length());\n            }\n\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"handleFlow_DataUpdate:buildHtml cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n\n            if (TextUtils.isEmpty(htmlString)) {\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_BUILD_HTML_ERROR);\n            }\n\n            if (!hasSentDataUpdateMessage) {\n                mainHandler.removeMessages(CLIENT_CORE_MSG_PRE_LOAD);\n                Message msg = mainHandler.obtainMessage(CLIENT_CORE_MSG_DATA_UPDATE);\n                msg.obj = htmlString;\n                mainHandler.sendMessage(msg);\n            }\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionDataUpdated(serverRsp);\n                }\n            }\n\n            if (null == diffDataJson || null == htmlString || !SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: clean session cache.\");\n                SonicUtils.removeSessionCache(id);\n                return;\n            }\n\n            switchState(STATE_RUNNING, STATE_READY, true);\n\n            Thread.yield();\n\n            startTime = System.currentTimeMillis();\n            Map<String, List<String>> headers = server.getResponseHeaderFields();\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionSaveCache(htmlString, null, serverDataJson.toString());\n                }\n            }\n            if (SonicUtils.saveSessionFiles(id, htmlString, null, serverDataJson.toString(), headers)) {\n                long htmlSize = new File(SonicFileUtils.getSonicHtmlPath(id)).length();\n                SonicUtils.saveSonicData(id, eTag, templateTag, htmlSha1, htmlSize, headers);\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: finish save session cache, cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_DataUpdate: save session files fail.\");\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_WRITE_FILE_FAIL);\n            }\n\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_DataUpdate error:\" + e.getMessage());\n        }\n\n    }\n\n    @Override\n    protected void clearSessionData() {\n        if (null != pendingClientCoreMessage) {\n            pendingClientCoreMessage = null;\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicCacheInterceptor.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.io.File;\n\n/**\n * <code>SonicCacheInterceptor</code> provide local data.\n * if a {@link SonicSessionConfig} does not set a sonicCacheInterceptor\n * sonic will use {@link SonicSessionConnection.SessionConnectionDefaultImpl} as default.\n *\n */\npublic abstract class SonicCacheInterceptor {\n\n    public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicCacheInterceptor\";\n\n    private final SonicCacheInterceptor nextInterceptor;\n\n    public SonicCacheInterceptor(SonicCacheInterceptor next) {\n        nextInterceptor = next;\n    }\n\n    public SonicCacheInterceptor next() {\n        return nextInterceptor;\n    }\n\n    public abstract String getCacheData(SonicSession session);\n\n    static String getSonicCacheData(SonicSession session) {\n        SonicCacheInterceptor interceptor = session.config.cacheInterceptor;\n        if (null == interceptor) {\n            return SonicCacheInterceptorDefaultImpl.getCacheData(session);\n        }\n\n        String htmlString = null;\n        while (null != interceptor) {\n            htmlString = interceptor.getCacheData(session);\n            if (null != htmlString) {\n                break;\n            }\n            interceptor = interceptor.next();\n        }\n        return htmlString;\n    }\n\n    /**\n     * <code>SonicCacheInterceptorDefaultImpl</code> provide a default implement for SonicCacheInterceptor.\n     */\n    private static class SonicCacheInterceptorDefaultImpl {\n\n        public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"DefaultSonicCacheInterceptor\";\n\n        public static String getCacheData(SonicSession session) {\n            if (session == null) {\n                SonicUtils.log(TAG, Log.INFO, \"getCache is null\");\n                return null;\n            }\n\n            SonicDataHelper.SessionData sessionData = SonicDataHelper.getSessionData(session.id);\n            boolean verifyError;\n            String htmlString = \"\";\n            // verify local data\n            if (TextUtils.isEmpty(sessionData.eTag) || TextUtils.isEmpty(sessionData.htmlSha1)) {\n                verifyError = true;\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + session.sId + \") runSonicFlow : session data is empty.\");\n            } else {\n                SonicDataHelper.updateSonicCacheHitCount(session.id);\n                File htmlCacheFile = new File(SonicFileUtils.getSonicHtmlPath(session.id));\n                htmlString = SonicFileUtils.readFile(htmlCacheFile);\n                verifyError = TextUtils.isEmpty(htmlString);\n                if (verifyError) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") runSonicFlow error:cache data is null.\");\n                } else {\n                    if (SonicEngine.getInstance().getConfig().VERIFY_CACHE_FILE_WITH_SHA1) {\n                        if (!SonicFileUtils.verifyData(htmlString, sessionData.htmlSha1)) {\n                            verifyError = true;\n                            htmlString = \"\";\n                            SonicEngine.getInstance().getRuntime().notifyError(session.sessionClient, session.srcUrl, SonicConstants.ERROR_CODE_DATA_VERIFY_FAIL);\n                            SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") runSonicFlow error:verify html cache with sha1 fail.\");\n                        } else {\n                            SonicUtils.log(TAG, Log.INFO, \"session(\" + session.sId + \") runSonicFlow verify html cache with sha1 success.\");\n                        }\n                    } else {\n                        if (sessionData.htmlSize != htmlCacheFile.length()) {\n                            verifyError = true;\n                            htmlString = \"\";\n                            SonicEngine.getInstance().getRuntime().notifyError(session.sessionClient, session.srcUrl, SonicConstants.ERROR_CODE_DATA_VERIFY_FAIL);\n                            SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") runSonicFlow error:verify html cache with size fail.\");\n                        }\n                    }\n                }\n            }\n            // if the local data is faulty, delete it\n            if (verifyError) {\n                long startTime = System.currentTimeMillis();\n                SonicUtils.removeSessionCache(session.id);\n                sessionData.reset();\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + session.sId + \") runSonicFlow:verify error so remove session cache, cost \" + +(System.currentTimeMillis() - startTime) + \"ms.\");\n            }\n            return htmlString;\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicConfig.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n/**\n * Sonic global config\n */\npublic class SonicConfig {\n\n    /**\n     * The max number of preload session , default is 5\n     */\n    int MAX_PRELOAD_SESSION_COUNT = 5;\n\n    /**\n     * When sonic server unavailable, sonic will not execute its flow and will execute\n     * webview normal loading process. This time control sonic how log will not execute its flow.\n     */\n    long SONIC_UNAVAILABLE_TIME = 6 * 60 * 60 * 1000;\n\n    /**\n     * The max size of sonic cache, default is 30M.\n     */\n    long SONIC_CACHE_MAX_SIZE = 30 * 1024 * 1024;\n\n    /**\n     * The max size of sonic resource cache, default is 60M.\n     */\n    long SONIC_RESOURCE_CACHE_MAX_SIZE = 60 * 1024 * 1024;\n\n    /**\n     * The time interval between check sonic cache, default is 24 hours.\n     */\n    long SONIC_CACHE_CHECK_TIME_INTERVAL = 24 * 60 * 60 * 1000L;\n\n    /**\n     * The max number of tasks which is downloading in the same time.\n     */\n    public int SONIC_MAX_NUM_OF_DOWNLOADING_TASK = 3;\n\n    /**\n     * The max age of sonic cache before expired.\n     */\n    int SONIC_CACHE_MAX_AGE = 5 * 60 * 1000;\n\n    /**\n     * Whether verify file by compare SHA1. If this value is false, sonic will verify file by file's size.\n     * Verify the file size is less time consuming than checking SHA1.\n     */\n    public boolean VERIFY_CACHE_FILE_WITH_SHA1 = true;\n\n    /**\n     * Whether auto call init db when create sonicEngine or not, default is true.\n     */\n    boolean AUTO_INIT_DB_WHEN_CREATE = true;\n\n    /**\n     * There will be a deadlock when ShouldInterceptRequest and getCookie are running at the same thread.\n     * This bug was found on Android ( < 5.0) system. @see <a href=\"https://github.com/Tencent/VasSonic/issues/90\">Issue 90</a> <br>\n     * So Sonic will call getCookie before sending Sonic request If GET_COOKIE_WHEN_SESSION_CREATE is true.<br>\n     * The value of this property should be true unless your app uses <a href=\"https://x5.tencent.com/tbs\">X5 kernel</a>.\n     */\n    boolean GET_COOKIE_WHEN_SESSION_CREATE = true;\n\n    private SonicConfig() {\n\n    }\n\n    /**\n     * Builder for SonicConfig\n     */\n    public static class Builder {\n\n        private final SonicConfig target;\n\n        public Builder() {\n            target = new SonicConfig();\n        }\n\n        public Builder setMaxPreloadSessionCount(int maxPreloadSessionCount) {\n            target.MAX_PRELOAD_SESSION_COUNT = maxPreloadSessionCount;\n            return this;\n        }\n\n        public Builder setUnavailableTime(long unavailableTime) {\n            target.SONIC_UNAVAILABLE_TIME = unavailableTime;\n            return this;\n        }\n\n        public Builder setCacheVerifyWithSha1(boolean enable) {\n            target.VERIFY_CACHE_FILE_WITH_SHA1 = enable;\n            return this;\n        }\n\n        public Builder setCacheMaxSize(long maxSize) {\n            target.SONIC_CACHE_MAX_SIZE = maxSize;\n            return this;\n        }\n\n        public Builder setResourceCacheMaxSize(long maxSize) {\n            target.SONIC_RESOURCE_CACHE_MAX_SIZE = maxSize;\n            return this;\n        }\n\n        public Builder setCacheCheckTimeInterval(long time) {\n            target.SONIC_CACHE_CHECK_TIME_INTERVAL = time;\n            return this;\n        }\n\n        public Builder setMaxNumOfDownloadingTasks(int num) {\n            target.SONIC_MAX_NUM_OF_DOWNLOADING_TASK = num;\n            return this;\n        }\n\n        public Builder setAutoInitDBWhenCreate(boolean autoInitDBWhenCreate) {\n            target.AUTO_INIT_DB_WHEN_CREATE = autoInitDBWhenCreate;\n            return this;\n        }\n\n        public Builder setGetCookieWhenSessionCreate(boolean value) {\n            target.GET_COOKIE_WHEN_SESSION_CREATE = value;\n            return this;\n        }\n\n        public Builder setSonicCacheMaxAge(int maxAge) {\n            target.SONIC_CACHE_MAX_AGE = maxAge;\n            return this;\n        }\n\n        public SonicConfig build() {\n            return target;\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicConstants.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n/**\n * Sonic constants\n */\npublic class SonicConstants {\n\n    /**\n     * SonicSDK log prefix\n     */\n    public final static String SONIC_SDK_LOG_PREFIX = \"SonicSdk_\";\n\n    /**\n     * SonicSDK version\n     */\n    public final static String SONIC_VERSION_NUM = \"2.0.0\";\n\n    /**\n     * Sonic parameter prefix\n     */\n    public final static String SONIC_PARAMETER_NAME_PREFIX = \"sonic_\";\n\n    /**\n     * This parameter in url will be as part of session id，and it is separated by SONIC_REMAIN_PARAMETER_SPLIT_CHAR.\n     */\n    public final static String SONIC_REMAIN_PARAMETER_NAMES= \"sonic_remain_params\";\n\n\n    public final static String SONIC_REMAIN_PARAMETER_SPLIT_CHAR = \";\";\n\n    /**\n     * SonicSession mode : StandardSonicSession\n     */\n    public static final int SESSION_MODE_DEFAULT = 0;\n\n    /**\n     * SonicSession mode : QuickSonicSession\n     */\n    public static final int SESSION_MODE_QUICK = 1;\n\n    /**\n     * Unknown\n     */\n    public static final int ERROR_CODE_UNKNOWN = -1;\n\n    /**\n     * Success\n     */\n    public static final int ERROR_CODE_SUCCESS = 0;\n\n    /**\n     * Http(s) connection error : IO Exception\n     */\n    public static final int ERROR_CODE_CONNECT_IOE = -901;\n\n    /**\n     * Http(s) connection error : time out\n     */\n    public static final int ERROR_CODE_CONNECT_TOE = -902;\n\n    /**\n     * Http(s) connection error : nullPointer in native\n     */\n    public static final int ERROR_CODE_CONNECT_NPE = -903;\n\n\n    /**\n     * Verify local file failed\n     */\n    public static final int ERROR_CODE_DATA_VERIFY_FAIL = -1001;\n\n    /**\n     * Failed to create sonic directory\n     */\n    public static final int ERROR_CODE_MAKE_DIR_ERROR = -1003;\n\n    /**\n     * File save failed\n     */\n    public static final int ERROR_CODE_WRITE_FILE_FAIL = -1004;\n\n    /**\n     * Separate html to template and data failed\n     */\n    public static final int ERROR_CODE_SPLIT_HTML_FAIL = -1005;\n\n    /**\n     * Obtain difference data between server and local data failed\n     */\n    public static final int ERROR_CODE_MERGE_DIFF_DATA_FAIL = -1006;\n\n    /**\n     * Server data exception\n     */\n    public static final int ERROR_CODE_SERVER_DATA_EXCEPTION = -1007;\n\n    /**\n     * Build template and data to html failed\n     */\n    public static final int ERROR_CODE_BUILD_HTML_ERROR = -1008;\n\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicDBHelper.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteOpenHelper;\nimport android.util.Log;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n/**\n * SonicDBHelper interacts with the database, such as managing database creation and\n * the version management.\n */\npublic class SonicDBHelper extends SQLiteOpenHelper {\n\n    /**\n     * log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicDBHelper\";\n\n    /**\n     * name of the database file\n     */\n    private static final String SONIC_DATABASE_NAME = \"sonic.db\";\n\n    /**\n     * the first version code of database\n     */\n    private static final int SONIC_DATABASE_FIRST_VERSION = 1;\n\n    /**\n     * current version code of the database (starting at <code>SONIC_DATABASE_FIRST_VERSION</code>)\n     */\n    private static final int SONIC_DATABASE_VERSION = 2;\n\n    private static SonicDBHelper sInstance = null;\n\n    private static AtomicBoolean isDBUpgrading = new AtomicBoolean(false);\n\n    private SonicDBHelper(Context context) {\n        super(context, SONIC_DATABASE_NAME, null, SONIC_DATABASE_VERSION);\n    }\n\n    static synchronized SonicDBHelper createInstance(Context context) {\n        if (null == sInstance) {\n            sInstance = new SonicDBHelper(context);\n        }\n        return sInstance;\n    }\n\n    public static synchronized SonicDBHelper getInstance() {\n        if (null == sInstance) {\n            throw new IllegalStateException(\"SonicDBHelper::createInstance() needs to be called before SonicDBHelper::getInstance()!\");\n        }\n        return sInstance;\n    }\n\n    /**\n     * Called when the database is created for the first time. This is where the\n     * creation of tables and the initial population of the tables should happen.\n     *\n     * @param db The database.\n     */\n    @Override\n    public void onCreate(SQLiteDatabase db) {\n        // create sessionData table\n        db.execSQL(SonicDataHelper.CREATE_TABLE_SQL);\n\n        // upgrade SP if need(session data save in SP on sdk 1.0)\n        onUpgrade(db, -1, SONIC_DATABASE_VERSION);\n\n        doUpgrade(db, SONIC_DATABASE_FIRST_VERSION, SONIC_DATABASE_VERSION);\n    }\n\n    @Override\n    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n        if (isDBUpgrading.compareAndSet(false, true)) {\n            long startTime = System.currentTimeMillis();\n            SonicUtils.log(TAG, Log.INFO, \"onUpgrade start, from \" + oldVersion + \" to \" + newVersion + \".\");\n            if (-1 == oldVersion) {\n                SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n                    @Override\n                    public void run() {\n                        SonicUtils.removeAllSessionCache();\n                        isDBUpgrading.set(false);\n                    }\n                }, 0L);\n            } else {\n                doUpgrade(db, oldVersion, newVersion);\n                isDBUpgrading.set(false);\n            }\n            SonicUtils.log(TAG, Log.INFO, \"onUpgrade finish, cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n        }\n    }\n\n    /**\n     * Called when the database needs to be upgraded.\n     *\n     * @param db The database.\n     * @param oldVersion The old database version.\n     * @param newVersion The new database version.\n     */\n    private void doUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n        switch (oldVersion) {\n            case 1: //2.0 version\n                upgradeToVersion_2(db);\n                break;\n            default:\n                break;\n        }\n    }\n\n    /**\n     * upgrade database from version 1 to version 2.\n     *\n     * @param db The database.\n     */\n    private void upgradeToVersion_2(SQLiteDatabase db) {\n        // create resourceData table\n        db.execSQL(SonicResourceDataHelper.CREATE_TABLE_SQL);\n    }\n\n    /**\n     * Indicates whether is upgrading or not. If return true, It will fail to create session.\n     * @return is Upgrading or not\n     */\n    public boolean isUpgrading() {\n        return isDBUpgrading.get();\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicDataHelper.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.ContentValues;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.support.annotation.NonNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n *\n * SonicDataHelper provides sonic data such as eTag, templateTag, etc.\n *\n */\nclass SonicDataHelper {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicDataHelper\";\n\n    /**\n     * table name of the SessionData\n     */\n    protected static final String Sonic_SESSION_TABLE_NAME = \"SessionData\";\n\n    /**\n     * SessionData's id\n     */\n    protected static final String SESSION_DATA_COLUMN_SESSION_ID = \"sessionID\";\n\n    /**\n     * The key of eTag\n     */\n    protected static final String SESSION_DATA_COLUMN_ETAG = \"eTag\";\n\n    /**\n     * The key of templateTag\n     */\n    protected static final String SESSION_DATA_COLUMN_TEMPLATE_EAG = \"templateTag\";\n\n    /**\n     * The key of html sha1\n     */\n    protected static final String SESSION_DATA_COLUMN_HTML_SHA1 = \"htmlSha1\";\n\n    /**\n     * The key of html size\n     */\n    protected static final String SESSION_DATA_COLUMN_HTML_SIZE = \"htmlSize\";\n\n    /**\n     * The key of template update time\n     */\n    protected static final String SESSION_DATA_COLUMN_TEMPLATE_UPDATE_TIME = \"templateUpdateTime\";\n\n    /**\n     * The key of Unavailable Time\n     */\n    protected static final String SESSION_DATA_COLUMN_UNAVAILABLE_TIME = \"UnavailableTime\";\n\n    /**\n     * The key of cache expired Time\n     */\n    protected static final String SESSION_DATA_COLUMN_CACHE_EXPIRED_TIME = \"cacheExpiredTime\";\n\n    /**\n     * The key of cache hit count\n     */\n    protected static final String SESSION_DATA_COLUMN_CACHE_HIT_COUNT = \"cacheHitCount\";\n\n    /**\n     * The create table sql\n     */\n    public static final String CREATE_TABLE_SQL = \"CREATE TABLE IF NOT EXISTS \" + Sonic_SESSION_TABLE_NAME + \" ( \" +\n            \"id  integer PRIMARY KEY autoincrement\" +\n            \" , \" + SESSION_DATA_COLUMN_SESSION_ID + \" text not null\" +\n            \" , \" + SESSION_DATA_COLUMN_ETAG + \" text not null\" +\n            \" , \" + SESSION_DATA_COLUMN_TEMPLATE_EAG + \" text\" +\n            \" , \" + SESSION_DATA_COLUMN_HTML_SHA1 + \" text not null\" +\n            \" , \" + SESSION_DATA_COLUMN_UNAVAILABLE_TIME + \" integer default 0\" +\n            \" , \" + SESSION_DATA_COLUMN_HTML_SIZE + \" integer default 0\" +\n            \" , \" + SESSION_DATA_COLUMN_TEMPLATE_UPDATE_TIME + \" integer default 0\" +\n            \" , \" + SESSION_DATA_COLUMN_CACHE_EXPIRED_TIME + \" integer default 0\" +\n            \" , \" + SESSION_DATA_COLUMN_CACHE_HIT_COUNT + \" integer default 0\" +\n            \" ); \";\n\n    /**\n     * Sonic data structure\n     */\n    static class SessionData {\n\n        String sessionId;\n\n        /**\n         * The eTag of html\n         */\n        String eTag;\n\n        /**\n         * Template tag\n         */\n        String templateTag;\n\n        /**\n         * The sha1 of html\n         */\n        String htmlSha1;\n\n        /**\n         * The size of html\n         */\n        long htmlSize;\n\n        /**\n         * The latest time of template update\n         */\n        long templateUpdateTime;\n\n        /**\n         * Indicates when local sonic cache is expired.\n         * If It is expired, the record of database and file on SDCard will be removed.\n         */\n        long expiredTime;\n\n        /**\n         * Indicates when sonic session is unavailable.\n         */\n        long unAvailableTime;\n\n        /**\n         * Indicates this cache  how many times to be used.\n         */\n        int cacheHitCount;\n\n        /**\n         * Reset data\n         */\n        public void reset() {\n            eTag = \"\";\n            templateTag = \"\";\n            htmlSha1 = \"\";\n            htmlSize = 0;\n            templateUpdateTime = 0;\n            expiredTime = 0;\n            cacheHitCount = 0;\n            unAvailableTime = 0;\n        }\n    }\n\n    /**\n     *\n     * @return all of the column in {@code Sonic_SESSION_TABLE_NAME}\n     */\n    static String[] getAllSessionDataColumn() {\n        return new String[] {SESSION_DATA_COLUMN_SESSION_ID, SESSION_DATA_COLUMN_ETAG,\n                SESSION_DATA_COLUMN_TEMPLATE_EAG, SESSION_DATA_COLUMN_HTML_SHA1,\n                SESSION_DATA_COLUMN_UNAVAILABLE_TIME, SESSION_DATA_COLUMN_HTML_SIZE,\n                SESSION_DATA_COLUMN_TEMPLATE_UPDATE_TIME, SESSION_DATA_COLUMN_CACHE_EXPIRED_TIME,\n                SESSION_DATA_COLUMN_CACHE_HIT_COUNT};\n    }\n    \n    /**\n     * Get sonic sessionData by unique session id\n     *\n     * @param sessionId a unique session id\n     * @return SessionData\n     */\n    @NonNull static SessionData getSessionData(String sessionId) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        SessionData sessionData = getSessionData(db, sessionId);\n        if (null == sessionData) {\n            sessionData = new SessionData();\n        }\n        return sessionData;\n    }\n\n    /**\n     * Get sonic sessionData by unique session id\n     *\n     * @param db The database.\n     * @param sessionId a unique session id\n     * @return SessionData\n     */\n    private static SessionData getSessionData(SQLiteDatabase db, String sessionId) {\n        Cursor cursor = db.query(Sonic_SESSION_TABLE_NAME,\n                getAllSessionDataColumn(),\n                SESSION_DATA_COLUMN_SESSION_ID + \"=?\",\n                new String[] {sessionId},\n                null, null, null);\n\n        SessionData sessionData = null;\n        if (cursor != null && cursor.moveToFirst()) {\n            sessionData = querySessionData(cursor);\n        }\n        if(cursor != null){\n            cursor.close();\n        }\n        return sessionData;\n    }\n\n    /**\n     * translate cursor to session data.\n     * @param cursor db cursor\n     */\n    private static SessionData querySessionData(Cursor cursor) {\n        SessionData sessionData = new SessionData();\n        sessionData.sessionId = cursor.getString(cursor.getColumnIndex(SESSION_DATA_COLUMN_SESSION_ID));\n        sessionData.eTag = cursor.getString(cursor.getColumnIndex(SESSION_DATA_COLUMN_ETAG));\n        sessionData.htmlSha1 = cursor.getString(cursor.getColumnIndex(SESSION_DATA_COLUMN_HTML_SHA1));\n        sessionData.htmlSize = cursor.getLong(cursor.getColumnIndex(SESSION_DATA_COLUMN_HTML_SIZE));\n        sessionData.templateTag = cursor.getString(cursor.getColumnIndex(SESSION_DATA_COLUMN_TEMPLATE_EAG));\n        sessionData.templateUpdateTime = cursor.getLong(cursor.getColumnIndex(SESSION_DATA_COLUMN_TEMPLATE_UPDATE_TIME));\n        sessionData.expiredTime = cursor.getLong(cursor.getColumnIndex(SESSION_DATA_COLUMN_CACHE_EXPIRED_TIME));\n        sessionData.unAvailableTime = cursor.getLong(cursor.getColumnIndex(SESSION_DATA_COLUMN_UNAVAILABLE_TIME));\n        sessionData.cacheHitCount = cursor.getInt(cursor.getColumnIndex(SESSION_DATA_COLUMN_CACHE_HIT_COUNT));\n        return sessionData;\n    }\n\n    /**\n     *\n     * @return all of the session data order by HitCount decrease.\n     */\n    static List<SessionData> getAllSessionByHitCount() {\n        List<SessionData> sessionDatas = new ArrayList<SessionData>();\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        Cursor cursor = db.query(Sonic_SESSION_TABLE_NAME,\n                getAllSessionDataColumn(),\n                null,null,null, null, SESSION_DATA_COLUMN_CACHE_HIT_COUNT + \" ASC\");\n        while(cursor != null && cursor.moveToNext()) {\n            sessionDatas.add(querySessionData(cursor));\n        }\n\n        return sessionDatas;\n    }\n\n    /**\n     * Save or update sonic sessionData with a unique session id\n     *\n     * @param sessionId   a unique session id\n     * @param sessionData SessionData\n     */\n    static void saveSessionData(String sessionId, SessionData sessionData) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        saveSessionData(db, sessionId, sessionData);\n    }\n\n    /**\n     * Save or update sonic sessionData with a unique session id\n     *\n     * @param db The database.\n     * @param sessionId   a unique session id\n     * @param sessionData SessionData\n     */\n    private static void saveSessionData(SQLiteDatabase db, String sessionId, SessionData sessionData) {\n        sessionData.sessionId = sessionId;\n        SessionData storedSessionData = getSessionData(db, sessionId);\n        if (storedSessionData != null) {\n            sessionData.cacheHitCount = storedSessionData.cacheHitCount;\n            updateSessionData(db, sessionId, sessionData);\n        } else {\n            insertSessionData(db, sessionId, sessionData);\n        }\n    }\n\n    private static void insertSessionData(SQLiteDatabase db, String sessionId, SessionData sessionData) {\n        ContentValues contentValues = getContentValues(sessionId, sessionData);\n        db.insert(Sonic_SESSION_TABLE_NAME, null, contentValues);\n    }\n\n    private static void updateSessionData(SQLiteDatabase db, String sessionId, SessionData sessionData) {\n        ContentValues contentValues = getContentValues(sessionId, sessionData);\n        db.update(Sonic_SESSION_TABLE_NAME, contentValues, SESSION_DATA_COLUMN_SESSION_ID + \"=?\",\n                new String[] {sessionId});\n    }\n\n    @NonNull\n    private static ContentValues getContentValues(String sessionId, SessionData sessionData) {\n        ContentValues contentValues = new ContentValues();\n        contentValues.put(SESSION_DATA_COLUMN_SESSION_ID, sessionId);\n        contentValues.put(SESSION_DATA_COLUMN_ETAG, sessionData.eTag);\n        contentValues.put(SESSION_DATA_COLUMN_HTML_SHA1, sessionData.htmlSha1);\n        contentValues.put(SESSION_DATA_COLUMN_HTML_SIZE, sessionData.htmlSize);\n        contentValues.put(SESSION_DATA_COLUMN_TEMPLATE_EAG, sessionData.templateTag);\n        contentValues.put(SESSION_DATA_COLUMN_TEMPLATE_UPDATE_TIME, sessionData.templateUpdateTime);\n        contentValues.put(SESSION_DATA_COLUMN_CACHE_EXPIRED_TIME, sessionData.expiredTime);\n        contentValues.put(SESSION_DATA_COLUMN_UNAVAILABLE_TIME, sessionData.unAvailableTime);\n        contentValues.put(SESSION_DATA_COLUMN_CACHE_HIT_COUNT, sessionData.cacheHitCount);\n        return contentValues;\n    }\n\n\n    /**\n     * Remove a unique session data\n     *\n     * @param sessionId A unique session id\n     */\n    static void removeSessionData(String sessionId) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        db.delete(Sonic_SESSION_TABLE_NAME, SESSION_DATA_COLUMN_SESSION_ID + \"=?\",\n                new String[] {sessionId});\n    }\n\n    /**\n     * Set sonic unavailable time, sonic will not execute its logic before this time.\n     *\n     * @param sessionId       A unique session id.\n     * @param unavailableTime Unavailable time.\n     * @return The result of save unavailable time\n     */\n    static boolean setSonicUnavailableTime(String sessionId, long unavailableTime) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        SessionData sessionData = getSessionData(db, sessionId);\n        if (sessionData != null) {\n            sessionData.unAvailableTime = unavailableTime;\n            updateSessionData(db, sessionId, sessionData);\n            return true;\n        } else {\n            sessionData = new SessionData();\n            sessionData.sessionId = sessionId;\n            sessionData.eTag = \"Unknown\";\n            sessionData.htmlSha1 = \"Unknown\";\n            sessionData.unAvailableTime = unavailableTime;\n            insertSessionData(db, sessionId, sessionData);\n            return true;\n        }\n    }\n\n    /**\n     * Get the sonic unavailable time\n     *\n     * @param sessionId A unique session id\n     * @return The sonic unavailable time\n     */\n    static long getLastSonicUnavailableTime(String sessionId) {\n        SessionData sessionData = getSessionData(sessionId);\n        return sessionData.unAvailableTime;\n    }\n\n    /**\n     * It will increase HitCount when local session cache is used.\n     * @param sessionId session id\n     */\n    static void updateSonicCacheHitCount(String sessionId) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        updateSonicCacheHitCount(db, sessionId);\n    }\n\n    /**\n     * It will increase HitCount when local session cache is used.\n     *\n     * @param sessionId session id\n     * @param db The database.\n     */\n    private static void updateSonicCacheHitCount(SQLiteDatabase db, String sessionId) {\n        SessionData sessionData = getSessionData(db, sessionId);\n        if (sessionData != null) {\n            sessionData.cacheHitCount += 1;\n            updateSessionData(db, sessionId, sessionData);\n        }\n    }\n\n    /**\n     * Remove all sonic data\n     */\n    static synchronized void clear() {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        db.delete(Sonic_SESSION_TABLE_NAME, null, null);\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicDiffDataCallback.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n/**\n * This interface is used to call the difference data between local and server data\n * to the client.\n *\n */\npublic interface SonicDiffDataCallback {\n    /**\n     * Called when sonic processes the local data and the server data.\n     * When the page requests the latest data, sonic will send the latest\n     * data to page by this method.\n     *\n     * @param resultData The result to page.\n     */\n    void callback(String resultData);\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicEngine.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Bundle;\nimport android.support.annotation.NonNull;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.util.Collection;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n *\n * Interacts with the overall SonicSessions running in the system.\n * Instances of this class can be used to query or fetch the information, such as SonicSession SonicRuntime.\n */\npublic class SonicEngine {\n\n    /**\n     * Log filter\n     */\n    private final static String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicEngine\";\n\n    /**\n     * SonicRuntime\n     */\n    private final SonicRuntime runtime;\n\n    /**\n     * Global config\n     */\n    private final SonicConfig config;\n\n    /**\n     * Single instance\n     */\n    private static SonicEngine sInstance;\n\n    /**\n     * Map containing preload session with capacity limits.\n     */\n    private final ConcurrentHashMap<String, SonicSession> preloadSessionPool = new ConcurrentHashMap<String, SonicSession>(5);\n\n    /**\n     * Map containing weak reference of running sessions.\n     */\n    private final ConcurrentHashMap<String, SonicSession> runningSessionHashMap = new ConcurrentHashMap<String, SonicSession>(5);\n\n\n    private SonicEngine(SonicRuntime runtime, SonicConfig config) {\n        this.runtime = runtime;\n        this.config = config;\n    }\n\n    /**\n     * Returns a SonicEngine instance\n     * <p>\n     * Make sure {@link #createInstance(SonicRuntime, SonicConfig)} has been called.\n     *\n     * @return SonicEngine instance\n     * @throws IllegalStateException if {@link #createInstance(SonicRuntime, SonicConfig)} hasn't been called\n     */\n    public static synchronized SonicEngine getInstance() {\n        if (null == sInstance) {\n            throw new IllegalStateException(\"SonicEngine::createInstance() needs to be called before SonicEngine::getInstance()\");\n        }\n        return sInstance;\n    }\n\n    /**\n     * Check if {@link #getInstance()} is ready or not.\n     * <p><b>Note: {@link #createInstance(SonicRuntime, SonicConfig)} must be called if {@code false} is returned.</b></p>\n     * @return\n     *      Return <code>true</code> if {@link #sInstance} is not null, <code>false</code> otherwise\n     */\n    public static synchronized boolean isGetInstanceAllowed() {\n        return null != sInstance;\n    }\n\n    /**\n     * Create SonicEngine instance. Meanwhile it will initialize engine and SonicRuntime.\n     * @param runtime SonicRuntime\n     * @param config SonicConfig\n     * @return SonicEngine object\n     */\n    public static synchronized SonicEngine createInstance(@NonNull SonicRuntime runtime, @NonNull SonicConfig config) {\n        if (null == sInstance) {\n            sInstance = new SonicEngine(runtime, config);\n            if (config.AUTO_INIT_DB_WHEN_CREATE) {\n                sInstance.initSonicDB();\n            }\n        }\n\n        return sInstance;\n    }\n\n    /**\n     * Init sonic DB which will upgrade to new version of database.\n     */\n    public void initSonicDB() {\n        SonicDBHelper.createInstance(getRuntime().getContext()).getWritableDatabase(); // init and update db\n    }\n\n    /**\n     * @return SonicRuntime object\n     */\n    public SonicRuntime getRuntime() {\n        return runtime;\n    }\n\n    /**\n     * @return SonicConfig object\n     */\n    public SonicConfig getConfig() {\n        return config;\n    }\n\n\n    /**\n     * Whether Sonic Service is available or not\n     * @return return true if Sonic Service is available , false else others.\n     */\n    public boolean isSonicAvailable() {\n        return !SonicDBHelper.getInstance().isUpgrading();\n    }\n\n    /**\n     * Create session ID\n     *\n     * @param url    session url\n     * @param isAccountRelated\n     *   Session Id will contain {@link com.tencent.sonic.sdk.SonicRuntime#getCurrentUserAccount()}  if {@code isAccountRelated } is true.\n     * @return String Object of session ID\n     */\n    public static String makeSessionId(String url, boolean isAccountRelated) {\n        return getInstance().getRuntime().makeSessionId(url, isAccountRelated);\n    }\n\n    /**\n     * This method will preCreate sonic session .\n     * And maps the specified session id to the specified value in this table {@link #preloadSessionPool} if there is no same sonic session.\n     * At the same time, if the number of {@link #preloadSessionPool} exceeds {@link SonicConfig#MAX_PRELOAD_SESSION_COUNT},\n     * preCreateSession will return false and not create any sonic session.\n     *\n     * <p><b>Note: this method is intended for preload scene.</b></p>\n     * @param url           url for preCreate sonic session\n     * @param sessionConfig SonicSession config\n     * @return\n     *  If this method preCreate sonic session and associated with {@code sessionId} in this table {@link #preloadSessionPool} successfully,\n     *  it will return true,\n     *  <code>false</code> otherwise.\n     */\n    public synchronized boolean preCreateSession(@NonNull String url, @NonNull SonicSessionConfig sessionConfig) {\n        if (isSonicAvailable()) {\n            String sessionId = makeSessionId(url, sessionConfig.IS_ACCOUNT_RELATED);\n            if (!TextUtils.isEmpty(sessionId)) {\n                SonicSession sonicSession = lookupSession(sessionConfig, sessionId, false);\n                if (null != sonicSession) {\n                    runtime.log(TAG, Log.ERROR, \"preCreateSession：sessionId(\" + sessionId + \") is already in preload pool.\");\n                    return false;\n                }\n                if (preloadSessionPool.size() < config.MAX_PRELOAD_SESSION_COUNT) {\n                    if (isSessionAvailable(sessionId) && runtime.isNetworkValid()) {\n                        sonicSession = internalCreateSession(sessionId, url, sessionConfig);\n                        if (null != sonicSession) {\n                            preloadSessionPool.put(sessionId, sonicSession);\n                            return true;\n                        }\n                    }\n                } else {\n                    runtime.log(TAG, Log.ERROR, \"create id(\" + sessionId + \") fail for preload size is bigger than \" + config.MAX_PRELOAD_SESSION_COUNT + \".\");\n                }\n            }\n        } else {\n            runtime.log(TAG, Log.ERROR, \"preCreateSession fail for sonic service is unavailable!\");\n        }\n        return false;\n    }\n\n    /**\n     *\n     * @param url           url for SonicSession Object\n     * @param sessionConfig SSonicSession config\n     * @return This method will create and return SonicSession Object when url is legal.\n     */\n    public synchronized SonicSession createSession(@NonNull String url, @NonNull SonicSessionConfig sessionConfig) {\n        if (isSonicAvailable()) {\n            String sessionId = makeSessionId(url, sessionConfig.IS_ACCOUNT_RELATED);\n            if (!TextUtils.isEmpty(sessionId)) {\n                SonicSession sonicSession = lookupSession(sessionConfig, sessionId, true);\n                if (null != sonicSession) {\n                    sonicSession.setIsPreload(url);\n                } else if (isSessionAvailable(sessionId)) { // 缓存中未存在\n                    sonicSession = internalCreateSession(sessionId, url, sessionConfig);\n                }\n                return sonicSession;\n            }\n        } else {\n            runtime.log(TAG, Log.ERROR, \"createSession fail for sonic service is unavailable!\");\n        }\n        return null;\n    }\n\n\n    /**\n     *\n     * @param sessionId possible sessionId\n     * @param pick      When {@code pick} is true and there is SonicSession in {@link #preloadSessionPool},\n     *                  it will remove from {@link #preloadSessionPool}\n     * @return\n     *          Return valid SonicSession Object from {@link #preloadSessionPool} if the specified sessionId is a key in {@link #preloadSessionPool}.\n     */\n    private SonicSession lookupSession(SonicSessionConfig config, String sessionId, boolean pick) {\n        if (!TextUtils.isEmpty(sessionId) && config != null) {\n            SonicSession sonicSession = preloadSessionPool.get(sessionId);\n            if (sonicSession != null) {\n                //判断session缓存是否过期,以及sessionConfig是否发生变化\n                if (!config.equals(sonicSession.config) ||\n                        sonicSession.config.PRELOAD_SESSION_EXPIRED_TIME > 0 && System.currentTimeMillis() - sonicSession.createdTime > sonicSession.config.PRELOAD_SESSION_EXPIRED_TIME) {\n                    if (runtime.shouldLog(Log.ERROR)) {\n                        runtime.log(TAG, Log.ERROR, \"lookupSession error:sessionId(\" + sessionId + \") is expired.\");\n                    }\n                    preloadSessionPool.remove(sessionId);\n                    sonicSession.destroy();\n                    return null;\n                }\n\n                if (pick) {\n                    preloadSessionPool.remove(sessionId);\n                }\n            }\n            return sonicSession;\n        }\n        return null;\n    }\n\n    /**\n     * Create sonic session internal\n     *\n     * @param sessionId session id\n     * @param url origin url\n     * @param sessionConfig session config\n     * @return Return new SonicSession if there was no mapping for the sessionId in {@link #runningSessionHashMap}\n     */\n    private SonicSession internalCreateSession(String sessionId, String url, SonicSessionConfig sessionConfig) {\n        if (!runningSessionHashMap.containsKey(sessionId)) {\n            SonicSession sonicSession;\n            if (sessionConfig.sessionMode == SonicConstants.SESSION_MODE_QUICK) {\n                sonicSession = new QuickSonicSession(sessionId, url, sessionConfig);\n            } else {\n                sonicSession = new StandardSonicSession(sessionId, url, sessionConfig);\n            }\n            sonicSession.addSessionStateChangedCallback(sessionCallback);\n\n            if (sessionConfig.AUTO_START_WHEN_CREATE) {\n                sonicSession.start();\n            }\n            return sonicSession;\n        }\n        if (runtime.shouldLog(Log.ERROR)) {\n            runtime.log(TAG, Log.ERROR, \"internalCreateSession error:sessionId(\" + sessionId + \") is running now.\");\n        }\n        return null;\n    }\n\n    /**\n     * If the server fails or specifies HTTP pattern, SonicSession won't use Sonic pattern Within {@link com.tencent.sonic.sdk.SonicConfig#SONIC_UNAVAILABLE_TIME} ms\n     * @param sessionId session id\n     * @return Test if the sessionId is available.\n     */\n    private boolean isSessionAvailable(String sessionId) {\n        long unavailableTime = SonicDataHelper.getLastSonicUnavailableTime(sessionId);\n        if (System.currentTimeMillis() > unavailableTime) {\n            return true;\n        }\n        if (runtime.shouldLog(Log.ERROR)) {\n            runtime.log(TAG, Log.ERROR, \"sessionId(\" + sessionId + \") is unavailable and unavailable time until \" + unavailableTime + \".\");\n        }\n        return false;\n    }\n\n    /**\n     * Removes all of the cache from {@link #preloadSessionPool} and deletes file caches from SDCard.\n     *\n     * @return\n     *      Returns {@code false} if {@link #runningSessionHashMap} is not empty.\n     *      Returns {@code true} if all of the local file cache has been deleted, <code>false</code> otherwise\n     */\n    public synchronized boolean cleanCache() {\n        if (!preloadSessionPool.isEmpty()) {\n            runtime.log(TAG, Log.INFO, \"cleanCache: remove all preload sessions, size=\" + preloadSessionPool.size() + \".\");\n            Collection<SonicSession> sonicSessions = preloadSessionPool.values();\n            for (SonicSession session : sonicSessions) {\n                session.destroy();\n            }\n            preloadSessionPool.clear();\n        }\n\n        if (!runningSessionHashMap.isEmpty()) {\n            runtime.log(TAG, Log.ERROR, \"cleanCache fail, running session map's size is \" + runningSessionHashMap.size() + \".\");\n            return false;\n        }\n\n        runtime.log(TAG, Log.INFO, \"cleanCache: remove all sessions cache.\");\n\n        return SonicUtils.removeAllSessionCache();\n    }\n\n    /**\n     * Removes the sessionId and its corresponding SonicSession from {@link #preloadSessionPool}.\n     *\n     * @param sessionId A unique session id\n     * @return Return {@code true} If there is no specified sessionId in {@link #runningSessionHashMap}, <code>false</code> otherwise.\n     */\n    public synchronized boolean removeSessionCache(@NonNull String sessionId) {\n        SonicSession sonicSession = preloadSessionPool.get(sessionId);\n        if (null != sonicSession) {\n            sonicSession.destroy();\n            preloadSessionPool.remove(sessionId);\n            runtime.log(TAG, Log.INFO, \"sessionId(\" + sessionId + \") removeSessionCache: remove preload session.\");\n        }\n\n        if (!runningSessionHashMap.containsKey(sessionId)) {\n            runtime.log(TAG, Log.INFO, \"sessionId(\" + sessionId + \") removeSessionCache success.\");\n            SonicUtils.removeSessionCache(sessionId);\n            return true;\n        }\n        runtime.log(TAG, Log.ERROR, \"sessionId(\" + sessionId + \") removeSessionCache fail: session is running.\");\n        return false;\n    }\n\n    /**\n     * It will Post a task to trim sonic cache\n     * if the last time of check sonic cache exceed {@link SonicConfig#SONIC_CACHE_CHECK_TIME_INTERVAL}.\n     */\n    public void trimSonicCache() {\n        SonicFileUtils.checkAndTrimCache();\n        SonicFileUtils.checkAndTrimResourceCache();\n    }\n\n    /**\n     * <p>A callback receives notifications from a SonicSession.\n     * Notifications indicate session related events, such as the running or the\n     * destroy of the SonicSession.\n     * It is intended to handle cache of SonicSession correctly to avoid concurrent modification.\n     * </p>\n     *\n     */\n    private final SonicSession.Callback sessionCallback = new SonicSession.Callback() {\n        @Override\n        public void onSessionStateChange(SonicSession session, int oldState, int newState, Bundle extraData) {\n            SonicUtils.log(TAG, Log.DEBUG, \"onSessionStateChange:session(\" + session.sId + \") from state \" + oldState + \" -> \" + newState);\n            switch (newState) {\n                case SonicSession.STATE_RUNNING:\n                    runningSessionHashMap.put(session.id, session);\n                    break;\n                case SonicSession.STATE_DESTROY:\n                    runningSessionHashMap.remove(session.id);\n                    break;\n            }\n        }\n    };\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicFileUtils.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.InputStreamReader;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n *\n * Interact with the overall file operations.\n */\npublic class SonicFileUtils {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicFileUtils\";\n\n    /**\n     *  Template  extensions\n     */\n    private static final String TEMPLATE_EXT = \".tpl\";\n\n    /**\n     * Data extensions\n     */\n    private static final String DATA_EXT = \".data\";\n\n    /**\n     * Html extensions\n     */\n    private static final String HTML_EXT = \".html\";\n\n    /**\n     * Response header extensions.\n     */\n    private static final String HEADER_EXT = \".header\";\n\n    /**\n     * The max percent threshold of cache.\n     * If the size of cache exceed max threshold, it will trim cache to{@link SonicFileUtils#THRESHOLD_OF_CACHE_MIN_PERCENT}\n     */\n    private static final double THRESHOLD_OF_CACHE_MAX_PERCENT = 0.8;\n\n    /**\n     * The min percent threshold of cache.\n     */\n    private static final double THRESHOLD_OF_CACHE_MIN_PERCENT = 0.25;\n\n    /**\n     *\n     * @return Returns the absolute path to the specific cache directory on\n     *  the filesystem (including File.separator at the end of path).\n     */\n    static String getSonicCacheDirPath() {\n        String dirPath = SonicEngine.getInstance().getRuntime().getSonicCacheDir().getAbsolutePath();\n        if (!dirPath.endsWith(File.separator)) {\n            dirPath += File.separator;\n        }\n        return dirPath;\n    }\n\n    /**\n     *\n     * @return Returns the absolute path to the resource cache directory on\n     *  the filesystem (including File.separator at the end of path).\n     */\n    static String getSonicResourceCachePath() {\n        String dirPath = SonicEngine.getInstance().getRuntime().getSonicResourceCacheDir().getAbsolutePath();\n        if (!dirPath.endsWith(File.separator)) {\n            dirPath += File.separator;\n        }\n        return dirPath;\n    }\n\n    /**\n     *\n     * @param sessionId session id\n     * @return The path of the directory holding sonic template cache files.\n     */\n    static String getSonicTemplatePath(String sessionId) {\n        return getSonicCacheDirPath() + sessionId + TEMPLATE_EXT;\n    }\n\n    /**\n     *\n     * @param sessionId session id\n     * @return The path of the directory holding sonic data cache files.\n     */\n    static String getSonicDataPath(String sessionId) {\n        return getSonicCacheDirPath() + sessionId + DATA_EXT;\n    }\n\n    /**\n     *\n     * @param sessionId session id\n     * @return he path of the directory holding sonic response http header cache files.\n     */\n    static String getSonicHeaderPath(String sessionId) {\n        return getSonicCacheDirPath() + sessionId + HEADER_EXT;\n    }\n\n    /**\n     *\n     * @param sessionId session id\n     * @return The path of the directory holding sonic html cache files.\n     */\n    static String getSonicHtmlPath(String sessionId) {\n        return getSonicCacheDirPath() + sessionId + HTML_EXT;\n    }\n\n    /**\n     *\n     * @param resourceName resource file name\n     * @return The path of the resource file.\n     */\n    public static String getSonicResourcePath(String resourceName) {\n        return getSonicResourceCachePath() + resourceName;\n    }\n\n    /**\n     *\n     * @param resourceName resource file name\n     * @return The path of the resource header file.\n     */\n    public static String getSonicResourceHeaderPath(String resourceName) {\n        return getSonicResourceCachePath() + resourceName + HEADER_EXT;\n    }\n\n    /**\n     *\n     * @param sessionId session id\n     * @return Return {@code true} if all of the cache files have been deleted, such as html template and the data cache files.\n     */\n    static boolean deleteSonicFiles(String sessionId) {\n        boolean deleteSuccess = true;\n        File htmlFile = new File(getSonicHtmlPath(sessionId));\n        if (htmlFile.exists()) {\n            deleteSuccess = htmlFile.delete();\n        }\n\n        File templateFile = new File(getSonicTemplatePath(sessionId));\n        if (templateFile.exists()) {\n            deleteSuccess &= templateFile.delete();\n        }\n\n        File dataFile = new File(getSonicDataPath(sessionId));\n        if (dataFile.exists()) {\n            deleteSuccess &= dataFile.delete();\n        }\n\n        File headerFile = new File(getSonicHeaderPath(sessionId));\n        if (headerFile.exists()){\n            deleteSuccess &= headerFile.delete();\n        }\n\n        return deleteSuccess;\n    }\n\n    /**\n     *\n     * @param resourceId resource file name\n     * @return Return {@code true} if all of the cache files have been deleted, such as resource file and resource header file.\n     */\n    static boolean deleteResourceFiles(String resourceId) {\n        boolean deleteSuccess = true;\n        File resourceFile = new File(getSonicResourcePath(resourceId));\n        if (resourceFile.exists()) {\n            deleteSuccess = resourceFile.delete();\n        }\n\n        File headerFile = new File(getSonicHeaderPath(resourceId));\n        if (headerFile.exists()){\n            deleteSuccess &= headerFile.delete();\n        }\n\n        return deleteSuccess;\n    }\n\n    /**\n     * This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.\n     *\n     * @param content    Data\n     * @param targetSha1 The specified hash value\n     * @return {@code true} if the given hash value\n     *          equivalent to computed hash value, {@code false} otherwise\n     */\n    static boolean verifyData(String content, String targetSha1) {\n        return !TextUtils.isEmpty(content) && !TextUtils.isEmpty(targetSha1) &&\n                targetSha1.equals(SonicUtils.getSHA1(content));\n    }\n\n    /**\n     * This method computes hash value by using specified SHA1 digest algorithm and compares hash value to the specified hash @{code targetSha1}.\n     *\n     * @param content   Data bytes\n     * @param targetSha1 The specified hash value\n     * @return {@code true} if the given hash value\n     *          equivalent to computed hash value, {@code false} otherwise\n     */\n    public static boolean verifyData(byte[] content, String targetSha1) {\n        return content != null && !TextUtils.isEmpty(targetSha1) &&\n                targetSha1.equals(SonicUtils.getSHA1(content));\n    }\n\n    /**\n     *\n     * @param file The file path of template\n     * @return Returns a string containing all of the content read from template file.\n     */\n    static String readFile(File file) {\n        if (file == null || !file.exists() || !file.canRead()) {\n            return null;\n        }\n\n        // read\n        BufferedInputStream bis = null;\n        InputStreamReader reader = null;\n        char[] buffer;\n        String rtn = null;\n        int n;\n        try {\n            bis = new BufferedInputStream(new FileInputStream(file));\n            reader = new InputStreamReader(bis);\n            int size = (int) file.length();\n            if (size > 1024 * 12) {\n                buffer = new char[1024 * 4];\n                StringBuilder result = new StringBuilder(1024 * 12);\n                while (-1 != (n = reader.read(buffer))) {\n                    result.append(buffer, 0, n);\n                }\n                rtn = result.toString();\n            } else {\n                buffer = new char[size];\n                n = reader.read(buffer);\n                rtn = new String(buffer, 0, n);\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"readFile error:(\" + file.getName() + \") \" + e.getMessage());\n        } finally {\n            if (bis != null) {\n                try {\n                    bis.close();\n                } catch (Exception e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"readFile close error:(\" + file.getName() + \") \" + e.getMessage());\n                }\n            }\n            if (reader != null) {\n                try {\n                    reader.close();\n                } catch (Exception e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"readFile close error:(\" + file.getName() + \") \" + e.getMessage());\n                }\n            }\n        }\n        return rtn;\n    }\n\n    /**\n     *\n     * @param file path of the file to read\n     * @return Returns the content bytes read from the file.\n     */\n    public static byte[] readFileToBytes(File file) {\n        if (file == null || !file.exists() || !file.canRead()) {\n            return null;\n        }\n\n        // read\n        BufferedInputStream bis = null;\n        ByteArrayOutputStream out = null;\n        byte[] rtn = null;\n        int n;\n        try {\n            bis = new BufferedInputStream(new FileInputStream(file));\n            int size = (int) file.length();\n            if (size > 1024 * 12) {\n                out = new ByteArrayOutputStream();\n                byte[] buffer = new byte[1024 * 4];\n                while ((n = bis.read(buffer)) != -1) {\n                    out.write(buffer, 0, n);\n                }\n                rtn = out.toByteArray();\n            } else {\n                rtn = new byte[size];\n                n = bis.read(rtn);\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"readFile error:(\" + file.getName() + \") \" + e.getMessage());\n        } finally {\n            if (bis != null) {\n                try {\n                    bis.close();\n                } catch (Exception e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"readFile close error:(\" + file.getName() + \") \" + e.getMessage());\n                }\n            }\n        }\n        return rtn;\n    }\n\n    /**\n     * Write string to the file represented by\n     * the specified <code>File</code> object.\n     *\n     * @param str      The string is to be saved\n     * @param filePath path to write\n     * @return Returns {@code true} if string is saved successfully.\n     */\n    static boolean writeFile(String str, String filePath) {\n        return writeFile(str.getBytes(), filePath);\n    }\n\n    /**\n     * Write bytes to the specific file.\n     *\n     * @param content   The data is to be saved\n     * @param filePath  path to write\n     * @return Returns {@code true} if string is saved successfully.\n     */\n    static boolean writeFile(byte[] content, String filePath) {\n        File file = new File(filePath);\n        FileOutputStream fos = null;\n        try {\n            if (!file.exists() && !file.createNewFile()) {\n                return false;\n            }\n            fos = new FileOutputStream(file);\n            fos.write(content);\n            fos.flush();\n            return true;\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"writeFile error:(\" + filePath + \") \" + e.getMessage());\n        } finally {\n            if (null != fos) {\n                try {\n                    fos.close();\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"writeFile close error:(\" + filePath + \") \" + e.getMessage());\n                }\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Deletes all of the files or directory denoted by this file path\n     *\n     * @param file The file to be deleted\n     */\n    static boolean deleteAllChildFiles(File file) {\n        boolean deleteSuccess = true;\n        if (null != file && file.exists()) {\n            if (file.isFile()) {\n                deleteSuccess = file.delete();\n            } else if (file.isDirectory()) {\n                File[] childFiles = file.listFiles();\n                if (null != childFiles) {\n                    for (File childFile : childFiles) {\n                        deleteSuccess &= deleteAllChildFiles(childFile);\n                    }\n                }\n            }\n        }\n        return deleteSuccess;\n    }\n\n    /**\n     * Check whether the sonic cache has been exceed the limit {@link SonicConfig#SONIC_CACHE_MAX_SIZE}.\n     * If the size of sonic cache exceeds, then it will remove the elder cache\n     * until the size is less than threshold {@link SonicFileUtils#THRESHOLD_OF_CACHE_MIN_PERCENT}.\n     */\n    static void checkAndTrimCache() {\n        HashMap<String, List<String>> currentCacheFileMap = new HashMap<String, List<String>>();\n        long startTime = System.currentTimeMillis();\n        long cacheFileSize = calcCacheSize(getSonicCacheDirPath(), currentCacheFileMap);\n\n        final long MAX_CACHE_SIZE = SonicEngine.getInstance().getConfig().SONIC_CACHE_MAX_SIZE;\n\n        if (cacheFileSize > (MAX_CACHE_SIZE * THRESHOLD_OF_CACHE_MAX_PERCENT)) {\n            SonicUtils.log(TAG, Log.INFO, \"now try clear cache, current cache size: \" + (cacheFileSize / 1024 / 1024) + \"m\");\n\n            List<SonicDataHelper.SessionData> allSessions = SonicDataHelper.getAllSessionByHitCount();\n\n            long fileSize ;\n            SonicDataHelper.SessionData sessionData;\n            for (int i = 0; i < allSessions.size(); i++) {\n                sessionData = allSessions.get(i);\n                List<String> files = currentCacheFileMap.get(sessionData.sessionId);\n\n                if (files != null && files.size() > 0) {\n                    for (String filePath : files) {\n                        File file = new File(filePath);\n                        if (file.isFile() && file.exists()) {\n                            String fileName = file.getName();\n                            fileSize = file.length();\n                            if (file.delete()) {\n                                cacheFileSize -= fileSize;\n                                SonicDataHelper.removeSessionData(fileName);\n                                SonicUtils.log(TAG, Log.INFO, \"delete \" + file.getAbsolutePath());\n                            }\n                        }\n                    }\n                }\n\n                if (cacheFileSize <= MAX_CACHE_SIZE * THRESHOLD_OF_CACHE_MIN_PERCENT) {\n                    break;\n                }\n            }\n\n            SonicUtils.log(TAG, Log.INFO, \"checkAndTrimCache: finish , cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n        }\n    }\n\n    /**\n     * Check whether the resource cache has been exceed the limit {@link SonicConfig#SONIC_RESOURCE_CACHE_MAX_SIZE}.\n     * If the size of sonic cache exceeds, then it will remove the elder cache\n     * until the size is less than threshold {@link SonicFileUtils#THRESHOLD_OF_CACHE_MIN_PERCENT}.\n     */\n    static void checkAndTrimResourceCache() {\n        HashMap<String, List<String>> currentCacheFileMap = new HashMap<String, List<String>>();\n        long startTime = System.currentTimeMillis();\n        long cacheFileSize = calcCacheSize(getSonicResourceCachePath(), currentCacheFileMap);\n\n        final long MAX_CACHE_SIZE = SonicEngine.getInstance().getConfig().SONIC_RESOURCE_CACHE_MAX_SIZE;\n\n        if (cacheFileSize > (MAX_CACHE_SIZE * THRESHOLD_OF_CACHE_MAX_PERCENT)) {\n            SonicUtils.log(TAG, Log.INFO, \"now try clear cache, current cache size: \" + (cacheFileSize / 1024 / 1024) + \"m\");\n\n            List<SonicResourceDataHelper.ResourceData> allSessions = SonicResourceDataHelper.getAllResourceData();\n\n            long fileSize ;\n            SonicResourceDataHelper.ResourceData sessionData;\n            for (int i = 0; i < allSessions.size(); i++) {\n                sessionData = allSessions.get(i);\n                List<String> files = currentCacheFileMap.get(sessionData.resourceId);\n\n                if (files != null && files.size() > 0) {\n                    for (String filePath : files) {\n                        File file = new File(filePath);\n                        if (file.isFile() && file.exists()) {\n                            String fileName = file.getName();\n                            fileSize = file.length();\n                            if (file.delete()) {\n                                cacheFileSize -= fileSize;\n                                SonicResourceDataHelper.removeResourceData(fileName);\n                                SonicUtils.log(TAG, Log.INFO, \"delete \" + file.getAbsolutePath());\n                            }\n                        }\n                    }\n                }\n\n                if (cacheFileSize <= MAX_CACHE_SIZE * THRESHOLD_OF_CACHE_MIN_PERCENT) {\n                    break;\n                }\n            }\n\n            SonicUtils.log(TAG, Log.INFO, \"checkAndTrimCache: finish , cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n        }\n    }\n\n    private static long calcCacheSize(String cacheDirPath, Map<String, List<String>> currentCacheFileMap) {\n        File cacheRootDir = new File(cacheDirPath);\n        if (cacheRootDir.exists() && cacheRootDir.isDirectory()) {\n            File[] childFiles = cacheRootDir.listFiles();\n            if (childFiles != null && childFiles.length > 0) {\n                long cacheFileSize = 0L;\n                String fileName;\n                File file ;\n                List<String> files;\n                for (File childFile : childFiles) {\n                    file = childFile;\n                    cacheFileSize += file.length();\n                    fileName = file.getName();\n\n                    files = currentCacheFileMap.get(fileName);\n                    if (files == null) {\n                        files = new ArrayList<String>();\n                    }\n\n                    files.add(file.getAbsolutePath());\n                    currentCacheFileMap.put(fileName, files);\n                }\n\n                return cacheFileSize;\n            }\n        }\n        return 0;\n    }\n\n    /**\n     *\n     * @param headers response headers\n     * @return the string which represent the last response header split by \"\\r\\n\n     */\n    static String convertHeadersToString(Map<String, List<String>> headers) {\n        if (headers != null && headers.size() > 0) {\n            StringBuilder headerString = new StringBuilder();\n            Set<Map.Entry<String, List<String>>> entries =  headers.entrySet();\n            for (Map.Entry<String, List<String>> entry : entries) {\n                String key = entry.getKey();\n                if (!TextUtils.isEmpty(key)) {\n                    List<String> values = entry.getValue();\n                    for (String value : values) {\n                        if (!TextUtils.isEmpty(value)) {\n                            headerString.append(key).append(\" : \");\n                            headerString.append(value).append(\"\\r\\n\");\n                        }\n                    }\n                }\n            }\n            return headerString.toString();\n        }\n\n        return \"\";\n    }\n\n    /**\n     * Get headers from local cache file\n     *\n     * @param headerPath header file path\n     * @return The last http response headers from local cache.\n     */\n    public static Map<String, List<String>> getHeaderFromLocalCache(String headerPath) {\n        Map<String, List<String>> headers = new HashMap<String, List<String>>();\n        File headerFile = new File(headerPath);\n        if (headerFile.exists()) {\n            String headerString = readFile(headerFile);\n            if (!TextUtils.isEmpty(headerString)) {\n                String[] headerArray = headerString.split(\"\\r\\n\");\n                if (headerArray.length > 0) {\n                    List<String> tmpHeaderList;\n                    for (String header : headerArray) {\n                        String[] keyValues = header.split(\" : \");\n                        if (keyValues.length == 2) {\n                            String key = keyValues[0].trim();\n                            tmpHeaderList = headers.get(key.toLowerCase());\n                            if (null == tmpHeaderList) {\n                                tmpHeaderList = new ArrayList<String>(1);\n                                headers.put(key.toLowerCase(), tmpHeaderList);\n                            }\n                            tmpHeaderList.add(keyValues[1].trim());\n                        }\n                    }\n                }\n            }\n        }\n\n        return headers;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicResourceDataHelper.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.ContentValues;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.support.annotation.NonNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * SonicResourceDataHelper manages the resource database.\n */\npublic class SonicResourceDataHelper {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicResourceDataHelper\";\n\n    /**\n     * table name of resource data.\n     */\n    private static final String Sonic_RESOURCE_TABLE_NAME = \"ResourceData\";\n\n    /**\n     * resource data's id.\n     */\n    private static final String RESOURCE_DATA_COLUMN_RESOURCE_ID = \"resourceID\";\n\n    /**\n     * key of resource sha1.\n     */\n    private static final String RESOURCE_DATA_COLUMN_RESOURCE_SHA1 = \"resourceSha1\";\n\n    /**\n     * key of resource size.\n     */\n    private static final String RESOURCE_DATA_COLUMN_RESOURCE_SIZE = \"resourceSize\";\n\n    /**\n     * key of last update time.\n     */\n    private static final String RESOURCE_DATA_COLUMN_LAST_UPDATE_TIME = \"resourceUpdateTime\";\n\n    /**\n     * key of cache expired time.\n     */\n    private static final String RESOURCE_DATA_COLUMN_CACHE_EXPIRED_TIME = \"cacheExpiredTime\";\n\n    /**\n     * The create table sql\n     */\n    public static final String CREATE_TABLE_SQL = \"CREATE TABLE IF NOT EXISTS \" + Sonic_RESOURCE_TABLE_NAME + \" ( \" +\n            \"id  integer PRIMARY KEY autoincrement\" +\n            \" , \" + RESOURCE_DATA_COLUMN_RESOURCE_ID + \" text not null\" +\n            \" , \" + RESOURCE_DATA_COLUMN_RESOURCE_SHA1 + \" text not null\" +\n            \" , \" + RESOURCE_DATA_COLUMN_RESOURCE_SIZE + \" integer default 0\" +\n            \" , \" + RESOURCE_DATA_COLUMN_LAST_UPDATE_TIME + \" integer default 0\" +\n            \" , \" + RESOURCE_DATA_COLUMN_CACHE_EXPIRED_TIME + \" integer default 0\" +\n            \" ); \";\n\n    /**\n     * resource data structure\n     */\n    public static class ResourceData {\n\n        String resourceId;\n\n        /**\n         * The sha1 of resource\n         */\n        public String resourceSha1;\n\n        /**\n         * The size of resource\n         */\n        public long resourceSize;\n\n        /**\n         * The latest time of resource update\n         */\n        long lastUpdateTime;\n\n        /**\n         * Indicates when local resource cache is expired.\n         * If It is expired, the record of database and file on SDCard will be removed.\n         */\n        public long expiredTime;\n\n        /**\n         * Reset data\n         */\n        public void reset() {\n            resourceSha1 = \"\";\n            resourceSize = 0;\n            lastUpdateTime = 0;\n            expiredTime = 0;\n        }\n    }\n    \n    /**\n     * Get sonic ResourceData by unique resource id\n     *\n     * @param resourceId a unique resource id\n     * @return ResourceData\n     */\n    @NonNull\n    public static ResourceData getResourceData(String resourceId) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        ResourceData resourceData = getResourceData(db, resourceId);\n        if (null == resourceData) {\n            resourceData = new ResourceData();\n        }\n        return resourceData;\n    }\n\n    /**\n     * Get sonic resourceData by unique resource id\n     *\n     * @param db The database.\n     * @param resourceId a unique resource id\n     * @return ResourceData\n     */\n    private static ResourceData getResourceData(SQLiteDatabase db, String resourceId) {\n        Cursor cursor = db.query(Sonic_RESOURCE_TABLE_NAME,\n                getAllResourceDataColumn(),\n                RESOURCE_DATA_COLUMN_RESOURCE_ID + \"=?\",\n                new String[] {resourceId},\n                null, null, null);\n\n        ResourceData resourceData = null;\n        if (cursor != null && cursor.moveToFirst()) {\n            resourceData = queryResourceData(cursor);\n        }\n        if(cursor != null){\n            cursor.close();\n        }\n        return resourceData;\n    }\n\n    /**\n     *\n     * @return all of the column in {@code Sonic_RESOURCE_TABLE_NAME}\n     */\n    public static String[] getAllResourceDataColumn() {\n        return new String[]{\n                RESOURCE_DATA_COLUMN_RESOURCE_ID,\n                RESOURCE_DATA_COLUMN_RESOURCE_SHA1,\n                RESOURCE_DATA_COLUMN_RESOURCE_SIZE,\n                RESOURCE_DATA_COLUMN_LAST_UPDATE_TIME,\n                RESOURCE_DATA_COLUMN_CACHE_EXPIRED_TIME\n        };\n    }\n\n    /**\n     * translate cursor to resource data.\n     * @param cursor db cursor\n     */\n    private static ResourceData queryResourceData(Cursor cursor) {\n        ResourceData resourceData = new ResourceData();\n        resourceData.resourceId = cursor.getString(cursor.getColumnIndex(RESOURCE_DATA_COLUMN_RESOURCE_ID));\n        resourceData.resourceSha1 = cursor.getString(cursor.getColumnIndex(RESOURCE_DATA_COLUMN_RESOURCE_SHA1));\n        resourceData.resourceSize = cursor.getLong(cursor.getColumnIndex(RESOURCE_DATA_COLUMN_RESOURCE_SIZE));\n        resourceData.lastUpdateTime = cursor.getLong(cursor.getColumnIndex(RESOURCE_DATA_COLUMN_LAST_UPDATE_TIME));\n        resourceData.expiredTime = cursor.getLong(cursor.getColumnIndex(RESOURCE_DATA_COLUMN_CACHE_EXPIRED_TIME));\n        return resourceData;\n    }\n\n    /**\n     * Save or update sonic resourceData with a unique resource id\n     *\n     * @param resourceId   a unique resource id\n     * @param resourceData ResourceData\n     */\n    static void saveResourceData(String resourceId, ResourceData resourceData) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        saveResourceData(db, resourceId, resourceData);\n    }\n\n    /**\n     * Save or update sonic resourceData with a unique resource id\n     *\n     * @param db The database.\n     * @param resourceId   a unique resource id\n     * @param resourceData ResourceData\n     */\n    private static void saveResourceData(SQLiteDatabase db, String resourceId, ResourceData resourceData) {\n        resourceData.resourceId = resourceId;\n        ResourceData storedResourceData = getResourceData(db, resourceId);\n        if (storedResourceData != null) {\n            updateResourceData(db, resourceId, resourceData);\n        } else {\n            insertResourceData(db, resourceId, resourceData);\n        }\n    }\n\n    private static void insertResourceData(SQLiteDatabase db, String resourceId, ResourceData resourceData) {\n        ContentValues contentValues = getContentValues(resourceId, resourceData);\n        db.insert(Sonic_RESOURCE_TABLE_NAME, null, contentValues);\n    }\n\n    private static void updateResourceData(SQLiteDatabase db, String resourceId, ResourceData resourceData) {\n        ContentValues contentValues = getContentValues(resourceId, resourceData);\n        db.update(Sonic_RESOURCE_TABLE_NAME, contentValues, RESOURCE_DATA_COLUMN_RESOURCE_ID + \"=?\",\n                new String[] {resourceId});\n    }\n\n    static List<ResourceData> getAllResourceData() {\n        List<ResourceData> resourceDataList = new ArrayList<ResourceData>();\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        Cursor cursor = db.query(Sonic_RESOURCE_TABLE_NAME, getAllResourceDataColumn(),\n                null,null,null, null, \"\");\n        while(cursor != null && cursor.moveToNext()) {\n            resourceDataList.add(queryResourceData(cursor));\n        }\n        return resourceDataList;\n    }\n\n    @NonNull\n    private static ContentValues getContentValues(String resourceId, ResourceData resourceData) {\n        ContentValues contentValues = new ContentValues();\n        contentValues.put(RESOURCE_DATA_COLUMN_RESOURCE_ID, resourceId);\n        contentValues.put(RESOURCE_DATA_COLUMN_RESOURCE_SHA1, resourceData.resourceSha1);\n        contentValues.put(RESOURCE_DATA_COLUMN_RESOURCE_SIZE, resourceData.resourceSize);\n        contentValues.put(RESOURCE_DATA_COLUMN_LAST_UPDATE_TIME, resourceData.lastUpdateTime);\n        contentValues.put(RESOURCE_DATA_COLUMN_CACHE_EXPIRED_TIME, resourceData.expiredTime);\n        return contentValues;\n    }\n\n\n    /**\n     * Remove a unique resource data\n     *\n     * @param resourceId A unique resource id\n     */\n    static void removeResourceData(String resourceId) {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        db.delete(Sonic_RESOURCE_TABLE_NAME, RESOURCE_DATA_COLUMN_RESOURCE_ID + \"=?\",\n                new String[] {resourceId});\n    }\n\n    /**\n     * Remove all sonic data\n     */\n    static synchronized void clear() {\n        SQLiteDatabase db = SonicDBHelper.getInstance().getWritableDatabase();\n        db.delete(Sonic_RESOURCE_TABLE_NAME, null, null);\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicRuntime.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.net.Uri;\nimport android.os.Environment;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.os.Looper;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.util.Collections;\nimport java.util.LinkedHashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.TreeSet;\n\n\n/**\n * <code>SonicRuntime</code> is a class which interacts with the overall running information in the system,\n * including Context, UA, ID (which is the unique identification for the saved data) and other information.\n */\npublic abstract class SonicRuntime {\n\n    /**\n     * Log filter\n     */\n    private final static String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicRuntime\";\n\n    /**\n     * A context for this runtime, it's expected to be ApplicationContext\n     */\n    protected final Context context;\n\n    /**\n     * This handle thread use to save sonic cache.\n     */\n    protected volatile static HandlerThread fileHandlerThread;\n\n    public SonicRuntime(Context context) {\n        if (null == context) {\n            throw new NullPointerException(\"SonicRuntime context con not be null!\");\n        }\n        this.context = context;\n    }\n\n    public Context getContext() {\n        return context;\n    }\n\n\n    /**\n     * Make a unique session id for the url, it can be account related.\n     * @param url Url which need to make session id\n     * @param isAccountRelated Is account related or not\n     * @return A unique session id\n     */\n    public String makeSessionId(String url, boolean isAccountRelated) {\n        if (isSonicUrl(url)) {\n            StringBuilder sessionIdBuilder = new StringBuilder();\n            try {\n                Uri uri = Uri.parse(url);\n                sessionIdBuilder.append(uri.getAuthority()).append(uri.getPath());\n                if (uri.isHierarchical()) {\n                    String sonicRemainParams = uri.getQueryParameter(SonicConstants.SONIC_REMAIN_PARAMETER_NAMES);\n                    TreeSet<String> remainParamTreeSet = new TreeSet<String>();\n                    if (!TextUtils.isEmpty(sonicRemainParams)) {\n                        Collections.addAll(remainParamTreeSet, sonicRemainParams.split(SonicConstants.SONIC_REMAIN_PARAMETER_SPLIT_CHAR));\n                    }\n\n                    TreeSet<String> parameterNamesTreeSet = new TreeSet<String>(getQueryParameterNames(uri));\n                    if (!remainParamTreeSet.isEmpty()) {\n                        parameterNamesTreeSet.remove(SonicConstants.SONIC_REMAIN_PARAMETER_NAMES);\n                    }\n\n                    for (String parameterName : parameterNamesTreeSet) {\n                        if (!TextUtils.isEmpty(parameterName) && (parameterName.startsWith(SonicConstants.SONIC_PARAMETER_NAME_PREFIX) || remainParamTreeSet.contains(parameterName))) {\n                            sessionIdBuilder.append(parameterName).append(uri.getQueryParameter(parameterName));\n                        }\n                    }\n                }\n            } catch (Throwable e) {\n                log(TAG, Log.ERROR, \"makeSessionId error:\" + e.getMessage() + \", url=\" + url);\n                sessionIdBuilder.setLength(0);\n                sessionIdBuilder.append(url);\n            }\n            String sessionId;\n            if (isAccountRelated) {\n                sessionId = getCurrentUserAccount() + \"_\" + SonicUtils.getMD5(sessionIdBuilder.toString());\n            } else {\n                sessionId = SonicUtils.getMD5(sessionIdBuilder.toString());\n            }\n            return sessionId;\n        }\n        return null;\n    }\n\n    /**\n     * Returns a set of the unique names of all query parameters. Iterating\n     * over the set will return the names in order of their first occurrence.\n     *\n     * @throws UnsupportedOperationException if this isn't a hierarchical URI\n     *\n     * @param uri The uri\n     * @return A set of decoded names\n     */\n    public Set<String> getQueryParameterNames(Uri uri) {\n        if (uri == null) {\n            return Collections.emptySet();\n        }\n\n        if (uri.isOpaque()) {\n            throw new UnsupportedOperationException(\"This isn't a hierarchical URI.\");\n        }\n\n        String query = uri.getEncodedQuery();\n        if (query == null) {\n            return Collections.emptySet();\n        }\n\n        Set<String> names = new LinkedHashSet<String>();\n        int start = 0;\n        do {\n            int next = query.indexOf('&', start);\n            int end = (next == -1) ? query.length() : next;\n\n            int separator = query.indexOf('=', start);\n            if (separator > end || separator == -1) {\n                separator = end;\n            }\n\n            String name = query.substring(start, separator);\n            names.add(Uri.decode(name));\n\n            // Move start to end of name.\n            start = end + 1;\n        } while (start < query.length());\n\n        return Collections.unmodifiableSet(names);\n    }\n\n    /**\n     * Logger function\n     *\n     * @param level Level of this log，such like Log.DEBUG.\n     * @return Should log or not\n     */\n    public boolean shouldLog(int level) {\n        return true;\n    }\n\n    public abstract void log(String tag, int level, String message);\n\n    /**\n     * Get cookies of the input url, this method will be called before sonic session make a\n     * session connection to request data.\n     *\n     * @param url The url which need to get cookies\n     * @return The cookies for current input url\n     */\n    public abstract String getCookie(String url);\n\n    /**\n     * Set cookies to webview after session connection response with cookies in it's headers.\n     *\n     * @param url The url which need to set cookies\n     * @param cookies The cookies for current input url\n     * @return Set cookie success or not\n     */\n    public abstract boolean setCookie(String url, List<String> cookies);\n\n    /**\n     * Get user agent of current runtime, this method will be called before sonic session make a\n     * session connection to request data.(sonic sdk info such like \"sonic-sdk-version/2.0.0\" will\n     * be added to this user agent.)\n     * @return The user agent\n     */\n    public abstract String getUserAgent();\n\n    /**\n     * The sonic cache root dir which sonic cache such like .html/.template/.data will be storage.\n     * it's expected to be a dir in /data dir for security.\n     *\n     * @return The root cache dir.\n     */\n    public File getSonicCacheDir() {\n        String path = context.getFilesDir() + \"/Sonic/\";\n        File file = new File(path.trim());\n        if (!file.exists() && !file.mkdir()) {\n            log(TAG, Log.ERROR, \"getSonicCacheDir error:make dir(\" + file.getAbsolutePath() + \") fail!\");\n            notifyError(null, path, SonicConstants.ERROR_CODE_MAKE_DIR_ERROR);\n        }\n        return file;\n    }\n\n    /**\n     * The resource cache root dir which resource cache will be storage.\n     * it's expected to be a dir in /sdcard dir for security.\n     *\n     * @return The root cache dir.\n     */\n    public File getSonicResourceCacheDir() {\n        File file = new File(Environment.getExternalStorageDirectory(), \"/SonicResource/\");\n        if (!file.exists() && !file.mkdir()) {\n            log(TAG, Log.ERROR, \"getSonicResourceCacheDir error:make dir(\" + file.getAbsolutePath() + \") fail!\");\n            notifyError(null, file.getAbsolutePath(), SonicConstants.ERROR_CODE_MAKE_DIR_ERROR);\n        }\n        return file;\n    }\n\n    /**\n     * get SharedPreferences of sonic.\n     *\n     * @return the sp\n     */\n    public SharedPreferences getSonicSharedPreferences() {\n        return context.getSharedPreferences(\"sonic\", Context.MODE_PRIVATE);\n    }\n\n    /**\n     * Get the current user account, this method will be called when makeSessionId's params is\n     * account related.\n     *\n     * @return Current user account\n     */\n    public abstract String getCurrentUserAccount();\n\n    /**\n     * This method is used to judge the input url is support sonic or not, when this method return\n     * true, it means it's allow to create a sonic session for this url.\n     * e.g. In mobile QQ, it will judge url params contain sonic=1 or not, if contains it will return\n     * true, others return false.\n     *\n     * @param url The url which need to judge\n     * @return Return is sonic url or not\n     */\n    public abstract boolean isSonicUrl(String url);\n\n    /**\n     * We add this method to decoupling webview since some application may use x5 webview or others.\n     *\n     * e.g. If u use a system webview, just call new android.webkit.WebResourceResponse\n     *\n     * Constructs a resource response with the given MIME type, encoding, and\n     * input stream. Callers must implement\n     * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input\n     * stream.\n     *\n     * @param mimeType The resource response's MIME type, for example text/html\n     * @param encoding The resource response's encoding\n     * @param data     The input stream that provides the resource response's data. Must not be a\n     *                 StringBufferInputStream.\n     * @param headers  The headers\n     *\n     * @return The response to kernel\n     */\n    public abstract Object createWebResourceResponse(String mimeType, String encoding, InputStream data, Map<String, String> headers);\n\n    /**\n     * This method is used to judge is network valid or not\n     *\n     * @return Network valid or not\n     */\n    public abstract boolean isNetworkValid();\n\n    /**\n     * Get the direct address of a url(host)，format as[ip:port]，the default http port is 80 and\n     * 443 for https.\n     *\n     * @param url The input url which need to get direct address\n     * @return Return a valid direct address or null.\n     */\n    public String getHostDirectAddress(String url) {\n        return null;\n    }\n\n    /**\n     * Show toast\n     *\n     * @param text     Content\n     * @param duration See Toast.LENGTH_SHORT/Toast.LENGTH_LONG\n     */\n    public abstract void showToast(CharSequence text, int duration);\n\n    /**\n     * Post a task to the thread(a io thread is better) which used to separate template and data.\n     *\n     * @param task A runnable task\n     * @param delayMillis The delay (in milliseconds) until the Runnable\n     *        will be executed.\n     */\n    public abstract void postTaskToThread(Runnable task, long delayMillis);\n\n    /**\n     * Post a task to session thread(a high priority thread is better)\n     *\n     * @param task A runnable task\n     */\n    public void postTaskToSessionThread(Runnable task) {\n        SonicSessionThreadPool.postTask(task);\n    }\n\n    /**\n     * Post a task in main thread\n     *\n     * @param task A runnable task\n     * @param delayMillis Delay millis\n     */\n    public void postTaskToMainThread(Runnable task, long delayMillis) {\n        new Handler(Looper.getMainLooper()).postDelayed(task, delayMillis);\n    }\n\n    /**\n     * Return the looper of HandleThread which use to save sonic cache.\n     *\n     * @return The looper of HandleThread which use to save sonic cache.\n     */\n    public Looper getFileThreadLooper() {\n        if (fileHandlerThread == null) {\n            fileHandlerThread = new HandlerThread(\"SonicSdk_FileThread\");\n            fileHandlerThread.start();\n        }\n\n        return fileHandlerThread.getLooper();\n    }\n\n    /**\n     * Notify error for host application to do report or statics\n     *\n     * @param client    The error client\n     * @param url      The error url\n     * @param errorCode Error code\n     */\n    public abstract void notifyError(SonicSessionClient client, String url, int errorCode);\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicServer.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Intent;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport org.json.JSONObject;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport static com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_HTTP;\nimport static com.tencent.sonic.sdk.SonicSession.OFFLINE_MODE_TRUE;\nimport static com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE;\nimport static com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_HTML_SHA1;\nimport static com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE;\nimport static com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG;\n\n/**\n * Instances of this class can be used to read server response from SonicSessionConnection.\n * If this request support Local Sonic Server, it will separate html into template and data file.\n */\npublic class SonicServer implements SonicSessionStream.Callback {\n    public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicServer\";\n\n    /**\n     * A session connection implement.\n     */\n    protected final SonicSessionConnection connectionImpl;\n\n    protected String serverRsp;\n\n    protected String templateString;\n\n    protected String dataString;\n\n    protected int responseCode;\n\n    final protected SonicSession session;\n\n    final protected Intent requestIntent;\n\n    /**\n     *  Cached response headers which contains response headers from server and custom response headers from\n     *  {@code com.tencent.sonic.sdk.SonicSessionConfig}\n     */\n    protected Map<String, List<String>> cachedResponseHeaders;\n    private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n\n    public SonicServer(SonicSession session, Intent requestIntent) {\n        this.session = session;\n        this.requestIntent = requestIntent;\n        connectionImpl = SonicSessionConnectionInterceptor.getSonicSessionConnection(session, requestIntent);\n    }\n\n    /**\n     *\n     * Opens a communications link to the resource referenced by Sonic session.\n     * If this request support Local Sonic Server, it will separate html into template and data file.\n     *\n     * @return Returns the response code of connection\n     */\n    protected int connect() {\n        long startTime = System.currentTimeMillis();\n\n        int resultCode = connectionImpl.connect();\n        session.statistics.connectionConnectTime = System.currentTimeMillis();\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + session.id + \") server connect cost = \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n        }\n\n        if (SonicConstants.ERROR_CODE_SUCCESS != resultCode) {\n            return resultCode; // error case\n        }\n\n        startTime = System.currentTimeMillis();\n        responseCode = connectionImpl.getResponseCode(); // update response code\n        session.statistics.connectionRespondTime = System.currentTimeMillis();\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + session.id + \") server response cost = \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n        }\n\n        if (HttpURLConnection.HTTP_NOT_MODIFIED == responseCode) { // nothing needs to do\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n\n        if (HttpURLConnection.HTTP_OK != responseCode) { // error case\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n\n        // fix issue for Weak ETag case [https://github.com/Tencent/VasSonic/issues/128]\n        String eTag = getResponseHeaderField(getCustomHeadFieldEtagKey());\n        if (!TextUtils.isEmpty(eTag) && eTag.toLowerCase().startsWith(\"w/\")) {\n            eTag = eTag.toLowerCase().replace(\"w/\", \"\");\n            eTag = eTag.replace(\"\\\"\", \"\");\n            addResponseHeaderFields(getCustomHeadFieldEtagKey(), eTag);\n        }\n\n        String requestETag = requestIntent.getStringExtra(getCustomHeadFieldEtagKey());\n        String responseETag = getResponseHeaderField(getCustomHeadFieldEtagKey());\n        if (!TextUtils.isEmpty(requestETag) && requestETag.equals(responseETag)) {\n            responseCode = HttpURLConnection.HTTP_NOT_MODIFIED; // fix 304 case\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n\n        if (isSonicResponse() || !session.config.SUPPORT_LOCAL_SERVER) {\n            return SonicConstants.ERROR_CODE_SUCCESS; // real sonic response or not support local server\n        }\n\n        String cacheOffline = getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n        if (OFFLINE_MODE_HTTP.equalsIgnoreCase(cacheOffline)) {\n            // When cache-offline is \"http\": which means sonic server is in bad condition, need feed back to run standard http request.\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n\n        if (TextUtils.isEmpty(cacheOffline)) {\n            addResponseHeaderFields(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, OFFLINE_MODE_TRUE);\n        }\n\n        if (isFirstLoadRequest()) { // first load case\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n\n        // When eTag is empty\n        if (TextUtils.isEmpty(eTag)) {\n            readServerResponse(null);\n            if (!TextUtils.isEmpty(serverRsp)) {\n                eTag = SonicUtils.getSHA1(serverRsp);\n                addResponseHeaderFields(getCustomHeadFieldEtagKey(), eTag);\n                addResponseHeaderFields(CUSTOM_HEAD_FILED_HTML_SHA1, eTag);\n            } else {\n                return SonicConstants.ERROR_CODE_CONNECT_IOE;\n            }\n\n            if (requestETag.equals(eTag)) { // 304 case\n                responseCode = HttpURLConnection.HTTP_NOT_MODIFIED;\n                return SonicConstants.ERROR_CODE_SUCCESS;\n            }\n        }\n\n        // When templateTag is empty\n        String templateTag = getResponseHeaderField(CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n        if (TextUtils.isEmpty(templateTag)) {\n            if (TextUtils.isEmpty(serverRsp)) {\n                readServerResponse(null);\n            }\n            if (!TextUtils.isEmpty(serverRsp)) {\n                separateTemplateAndData();\n                templateTag = getResponseHeaderField(CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n            } else {\n                return SonicConstants.ERROR_CODE_CONNECT_IOE;\n            }\n        }\n\n        //check If it changes template or update data.\n        String requestTemplateTag = requestIntent.getStringExtra(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n        if (requestTemplateTag.equals(templateTag)) {\n            addResponseHeaderFields(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"false\");\n        } else {\n            addResponseHeaderFields(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE, \"true\");\n        }\n\n        return SonicConstants.ERROR_CODE_SUCCESS;\n    }\n\n    private boolean isSonicResponse() {\n        Map<String, List<String>> headersFromServer = connectionImpl.getResponseHeaderFields();\n        if (null != headersFromServer && !headersFromServer.isEmpty()) {\n            Set<Map.Entry<String, List<String>>> entrySet = headersFromServer.entrySet();\n            String KeyInLowercase;\n            for (Map.Entry<String, List<String>> entry : entrySet) {\n                if (!TextUtils.isEmpty(entry.getKey())) {\n                    KeyInLowercase = entry.getKey().toLowerCase();\n                    if (KeyInLowercase.equals(CUSTOM_HEAD_FILED_CACHE_OFFLINE) ||\n                            KeyInLowercase.equals(CUSTOM_HEAD_FILED_TEMPLATE_CHANGE) ||\n                            KeyInLowercase.equals(CUSTOM_HEAD_FILED_TEMPLATE_TAG)) {\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    private boolean isFirstLoadRequest() {\n        return TextUtils.isEmpty(requestIntent.getStringExtra(getCustomHeadFieldEtagKey())) ||\n                TextUtils.isEmpty(requestIntent.getStringExtra(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG));\n    }\n\n    public int getResponseCode() {\n        return responseCode;\n    }\n\n    /**\n     * Disconnect the communications link to the resource referenced by Sonic session\n     */\n    public void disconnect() {\n        // We need to close connectionImpl.getResponseStream() manually.\n        // ConnectionImpl.disconnect() doesn't close the stream because doing so would require all stream\n        // access to be synchronized. It's expected that the thread using the\n        // connection will close its streams directly. If it doesn't, the worst\n        // case is that the GzipSource's Inflater won't be released until it's\n        // finalized. (This logs a warning on Android.)\n        try {\n            BufferedInputStream bufferedInputStream = connectionImpl.getResponseStream();\n            if (bufferedInputStream != null) {\n                bufferedInputStream.close();\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") server disconnect error:\" + e.getMessage() + \".\");\n        }\n\n        connectionImpl.disconnect();\n    }\n\n\n    /**\n     *  return response headers which contains response headers from server and custom response headers from\n     *  {@code com.tencent.sonic.sdk.SonicSessionConfig}\n     *  note: server response headers have high priority than custom headers!\n     *  @return a Map of header fields\n     */\n    public  Map<String, List<String>> getResponseHeaderFields() {\n        if (null == cachedResponseHeaders) {\n            // new cachedResponseHeaders\n            cachedResponseHeaders = new ConcurrentHashMap<String, List<String>>();\n            // fill custom headers\n            List<String> tmpHeaderList;\n            if (session.config.customResponseHeaders != null && session.config.customResponseHeaders.size() > 0) {\n                for (Map.Entry<String, String> entry : session.config.customResponseHeaders.entrySet()) {\n                    String key = entry.getKey();\n                    if (!TextUtils.isEmpty(key)) {\n                        tmpHeaderList = cachedResponseHeaders.get(key.toLowerCase());\n                        if (null == tmpHeaderList) {\n                            tmpHeaderList = new ArrayList<String>(1);\n                            cachedResponseHeaders.put(key.toLowerCase(), tmpHeaderList);\n                        }\n                        tmpHeaderList.add(entry.getValue());\n                    }\n                }\n            }\n\n            // fill real response headers\n            Map<String, List<String>> headersFromServer = connectionImpl.getResponseHeaderFields();\n            if (null != headersFromServer && !headersFromServer.isEmpty()) {\n                Set<Map.Entry<String, List<String>>> entrySet = headersFromServer.entrySet();\n                for (Map.Entry<String, List<String>> entry : entrySet) {\n                    String key = entry.getKey();\n                    if (!TextUtils.isEmpty(key)) {\n                        cachedResponseHeaders.put(key.toLowerCase(), entry.getValue());\n                    }\n                }\n            }\n\n        }\n\n        return cachedResponseHeaders;\n    }\n\n    /**\n     *\n     * @param key  the name of a header field.\n     * @return Returns the value of the named header field from SonicSessionConnection.\n     */\n    public String getResponseHeaderField(String key) {\n        Map<String, List<String>> responseHeaderFields = getResponseHeaderFields();\n        if (null != responseHeaderFields && 0 != responseHeaderFields.size()) {\n            List<String> responseHeaderValues = responseHeaderFields.get(key.toLowerCase());\n            if (null != responseHeaderValues && 0 != responseHeaderValues.size()) {\n                StringBuilder stringBuilder = new StringBuilder(responseHeaderValues.get(0));\n                for (int index = 1, size = responseHeaderValues.size(); index < size; ++index) {\n                    stringBuilder.append(',');\n                    stringBuilder.append(responseHeaderValues.get(index));\n                }\n                return stringBuilder.toString();\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Read all of data from {@link SonicSessionConnection#getResponseStream()} into byte array output stream {@code outputStream} until\n     * {@code breakCondition} is true when {@code breakCondition} is not null.\n     * Then return a {@code SonicSessionStream} obtains input bytes\n     * from  {@code outputStream} and a {@code netStream} when there is unread data from network.\n     *\n     * @param breakConditions This method won't read any data from {@link SonicSessionConnection#getResponseStream()} if {@code breakCondition} is true.\n     * @return Returns a {@code SonicSessionStream} obtains input bytes\n     * from  {@code outputStream} and a {@code netStream} when there is unread data from network.\n     */\n    public synchronized InputStream getResponseStream(AtomicBoolean breakConditions) {\n        if (readServerResponse(breakConditions)) {\n            BufferedInputStream netStream = !TextUtils.isEmpty(serverRsp) ? null : connectionImpl.getResponseStream();\n            return new SonicSessionStream(this, outputStream, netStream);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Put key and value into http header.\n     * @param key the name of a header field.\n     * @param args the value which need to put into http header.\n     */\n    private void addResponseHeaderFields(String key, String... args) {\n        ArrayList<String> field = new ArrayList<>(args.length);\n        Collections.addAll(field, args);\n        getResponseHeaderFields().put(key.toLowerCase(), field);\n    }\n\n    /**\n     *  Return current cached server response data.\n     *  If @{code readUntilEnd} is true and current cached response data is empty, read all of data from {@link SonicSessionConnection#getResponseStream()} into byte array output stream {@code outputStream}.\n     *  And then this method convert outputStream into response string {@code serverRsp}. <br>\n     * <p><b>Note: This method blocks until the end of the input stream has been reached or {@code breakCondition} has been reset to true.</b></p>\n     *\n     * @param readUntilEnd This method won't read any data from {@link SonicSessionConnection#getResponseStream()} if {@code readUntilEnd} is false.\n     *\n     * @return\n     *      Returns {@code serverRsp} current cached server response data.\n     */\n    public synchronized String getResponseData(boolean readUntilEnd) {\n        if (readUntilEnd && TextUtils.isEmpty(serverRsp)) {\n            readServerResponse(null);\n        }\n        return serverRsp;\n    }\n\n    /**\n     * If the serverRsp is not empty, It will separate serverRsp into template and data file and return template as string.\n     * @return The template.\n     */\n    public synchronized String getTemplate() {\n        if (TextUtils.isEmpty(templateString) && !TextUtils.isEmpty(serverRsp)) {\n            separateTemplateAndData();\n        }\n        return templateString;\n    }\n\n    /**\n     * If the serverRsp is not empty, It will separate serverRsp into template and data file and return data as JSONObject String.\n     * @return the JSONObject String which represent data.\n     */\n    public synchronized String getUpdatedData() {\n        if (TextUtils.isEmpty(dataString) && !TextUtils.isEmpty(serverRsp)) {\n            separateTemplateAndData();\n        }\n        return dataString;\n    }\n\n    /**\n     * Read all of data from {@link SonicSessionConnection#getResponseStream()} into byte array output stream {@code outputStream} until\n     * {@code breakCondition} is true if {@code breakCondition} is not null.\n     *  And then this method convert outputStream into response string {@code serverRsp} at the end of response stream.\n     *\n     * @param breakCondition This method won't read any data from {@link SonicSessionConnection#getResponseStream()} if {@code breakCondition} is true.\n     * @return True when read any of data from {@link SonicSessionConnection#getResponseStream()} and write into {@code outputStream}\n     */\n    private boolean readServerResponse(AtomicBoolean breakCondition) {\n        if (TextUtils.isEmpty(serverRsp)) {\n            BufferedInputStream bufferedInputStream = connectionImpl.getResponseStream();\n            if (null == bufferedInputStream) {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") readServerResponse error: bufferedInputStream is null!\");\n                return false;\n            }\n\n            try {\n                byte[] buffer = new byte[session.config.READ_BUF_SIZE];\n\n                int n = 0;\n                while (((breakCondition == null) || !breakCondition.get()) && -1 != (n = bufferedInputStream.read(buffer))) {\n                    outputStream.write(buffer, 0, n);\n                }\n\n                if (n == -1) {\n                    serverRsp = outputStream.toString(session.getCharsetFromHeaders());\n                }\n            } catch (Exception e) {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") readServerResponse error:\" + e.getMessage() + \".\");\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected void separateTemplateAndData() {\n        if (!TextUtils.isEmpty(serverRsp)) {\n            StringBuilder templateStringBuilder = new StringBuilder();\n            StringBuilder dataStringBuilder = new StringBuilder();\n            String data = null;\n            if (SonicUtils.separateTemplateAndData(session.id, serverRsp, templateStringBuilder, dataStringBuilder)) {\n                templateString = templateStringBuilder.toString();\n                data = dataStringBuilder.toString();\n            }\n\n            String eTag = getResponseHeaderField(getCustomHeadFieldEtagKey());\n            String templateTag = getResponseHeaderField(CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n            String newHtmlSha1 = null;\n            if (TextUtils.isEmpty(eTag)) { // When eTag is empty, fill eTag with Sha1\n                newHtmlSha1 = eTag = SonicUtils.getSHA1(serverRsp);\n                addResponseHeaderFields(getCustomHeadFieldEtagKey(), eTag);\n                addResponseHeaderFields(CUSTOM_HEAD_FILED_HTML_SHA1, newHtmlSha1);\n            }\n\n            if (TextUtils.isEmpty(templateString)) { // The same with htmlString\n                templateString = serverRsp;\n                addResponseHeaderFields(CUSTOM_HEAD_FILED_TEMPLATE_TAG, eTag);\n            } else if (TextUtils.isEmpty(templateTag)){ // When eTag is empty, fill templateTag with Sha1 of templateString\n                addResponseHeaderFields(CUSTOM_HEAD_FILED_TEMPLATE_TAG, SonicUtils.getSHA1(templateString));\n            }\n\n            if (!TextUtils.isEmpty(data)) {\n                try {\n                    JSONObject object = new JSONObject();\n                    object.put(\"data\", new JSONObject(data));\n                    if (TextUtils.isEmpty(newHtmlSha1)) {\n                        newHtmlSha1 = SonicUtils.getSHA1(serverRsp);\n                        addResponseHeaderFields(CUSTOM_HEAD_FILED_HTML_SHA1, newHtmlSha1);\n                    }\n                    object.put(\"html-sha1\", getResponseHeaderField(CUSTOM_HEAD_FILED_HTML_SHA1));\n                    object.put(\"template-tag\", getResponseHeaderField(CUSTOM_HEAD_FILED_TEMPLATE_TAG));\n                    dataString = object.toString();\n                } catch (Exception e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \") parse server response data error:\" + e.getMessage() + \".\");\n                }\n            }\n        }\n    }\n\n    public String getCustomHeadFieldEtagKey() {\n        return connectionImpl != null ? connectionImpl.getCustomHeadFieldEtagKey() : SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG;\n    }\n\n    @Override\n    public void onClose(boolean readComplete, ByteArrayOutputStream outputStream) {\n        if (TextUtils.isEmpty(serverRsp) && readComplete && outputStream != null) {\n            try {\n                serverRsp = outputStream.toString(session.getCharsetFromHeaders());\n                outputStream.close();\n            } catch (Throwable e) {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + session.sId + \"), onClose error:\" + e.getMessage() + \".\");\n            }\n        }\n        session.onServerClosed(this, readComplete);\n    }\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSession.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport android.support.annotation.Nullable;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.widget.Toast;\n\nimport com.tencent.sonic.sdk.download.SonicDownloadCache;\nimport com.tencent.sonic.sdk.download.SonicDownloadEngine;\n\nimport org.json.JSONObject;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.lang.ref.WeakReference;\nimport java.net.HttpURLConnection;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Random;\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * In Sonic, <code>SonicSession</code>s are used to manage the entire process,include\n * obtain the latest data from the server, provide local and latest\n * data to kernel, separate html to template and data, build template\n * and data to html and so on. Each url involves one session at a time,\n * that session will be destroyed when the page is destroyed.\n *\n */\n\npublic abstract class SonicSession implements Handler.Callback {\n\n    /**\n     * Log filter\n     */\n    public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicSession\";\n\n    /**\n     * The result keyword to page : the value is <code>srcResultCode</code>\n     */\n    public static final String WEB_RESPONSE_SRC_CODE = \"srcCode\";\n\n    /**\n     * The result keyword to page : the value is <code>finalResultCode</code>\n     */\n    public static final String WEB_RESPONSE_CODE = \"code\";\n\n\n    public static final String WEB_RESPONSE_EXTRA = \"extra\";\n\n\n    /**\n     * The all data keyword to page\n     */\n    public static final String WEB_RESPONSE_DATA = \"result\";\n\n\n    public static final String DATA_UPDATE_BUNDLE_PARAMS_DIFF = \"_diff_data_\";\n\n\n    public static final String WEB_RESPONSE_LOCAL_REFRESH_TIME = \"local_refresh_time\";\n\n\n    /**\n     * Name of chrome file thread\n     */\n    public static final String CHROME_FILE_THREAD = \"Chrome_FileThread\";\n\n    /**\n     * Session state : original.\n     * <p>\n     * This state means session has not start.\n     */\n    public static final int STATE_NONE = 0;\n\n    /**\n     * Session state : running.\n     * <p>\n     * This state means session has begun to request data from\n     * the server and is processing the data.\n     *\n     */\n    public static final int STATE_RUNNING = 1;\n\n    /**\n     * Session state : ready.\n     * <p>\n     * This state means session data is available when the page\n     * initiates a resource interception. In other stats the\n     * client(kernel) will wait.\n     *\n     */\n    public static final int STATE_READY = 2;\n\n    /**\n     * Session state : destroyed.\n     * <p>\n     * This state means the session is destroyed.\n     */\n    public static final int STATE_DESTROY = 3;\n\n    /**\n     * The value of \"cache-offline\" in http(s) response headers.\n     * <p>\n     * This value means sonic server unavailable, the terminal\n     * does not take sonic logic for the next period of time,the\n     * value of time is defined in {@link SonicConfig#SONIC_UNAVAILABLE_TIME}\n     *\n     */\n    public static final String OFFLINE_MODE_HTTP = \"http\";\n\n    /**\n     * The value of \"cache-offline\" in http(s) response headers.\n     * <p>\n     * This value means sonic will save the latest data, but not refresh\n     * page.For example, when sonic mode is data update, sonic will not\n     * provide the difference data between local and server to page to refresh\n     * the content.\n     *\n     */\n    public static final String OFFLINE_MODE_STORE = \"store\";\n\n    /**\n     * The value of \"cache-offline\" in http(s) response headers.\n     * <p>\n     * This value means sonic will save the latest data and refresh page content.\n     *\n     */\n    public static final String OFFLINE_MODE_TRUE = \"true\";\n\n    /**\n     * The value of \"cache-offline\" in http(s) response headers.\n     * <p>\n     * This value means sonic will refresh page content but not save date, sonic\n     * will remove the local data also.\n     *\n     */\n    public static final String OFFLINE_MODE_FALSE = \"false\";\n\n    /**\n     * Sonic mode : unknown.\n     */\n    public static final int SONIC_RESULT_CODE_UNKNOWN = -1;\n\n    /**\n     * Sonic mode : first load.\n     */\n    public static final int SONIC_RESULT_CODE_FIRST_LOAD = 1000;\n\n    /**\n     * Sonic mode : template change.\n     */\n    public static final int SONIC_RESULT_CODE_TEMPLATE_CHANGE = 2000;\n\n    /**\n     * Sonic mode : data update.\n     */\n    public static final int SONIC_RESULT_CODE_DATA_UPDATE = 200;\n\n    /**\n     * Sonic mode : 304.\n     */\n    public static final int SONIC_RESULT_CODE_HIT_CACHE = 304;\n\n    /**\n     * Sonic original mode.\n     * <p>\n     *  For example, when local data does not exist, the value is\n     *  <code>SONIC_RESULT_CODE_FIRST_LOAD</code>\n     *\n     */\n    protected int srcResultCode = SONIC_RESULT_CODE_UNKNOWN;\n\n    /**\n     * Sonic final mode.\n     * <p>\n     *  For example, when local data does not exist, the <code>srcResultCode</code>\n     *  value is <code>SONIC_RESULT_CODE_FIRST_LOAD</code>. If the server data is read\n     *  finished, sonic will provide the latest data to kernel when the kernel\n     *  initiates a resource interception.This effect is the same as loading local data,\n     *  so the sonic mode will be set as <code>SONIC_RESULT_CODE_HIT_CACHE</code>\n     *\n     */\n    protected int finalResultCode = SONIC_RESULT_CODE_UNKNOWN;\n\n\n    protected static final int COMMON_MSG_BEGIN = 0;\n\n    /**\n     * The message to record sonic mode.\n     */\n    protected static final int CLIENT_MSG_NOTIFY_RESULT = COMMON_MSG_BEGIN + 1;\n\n    /**\n     * The message of page ready, its means page want to get the latest session data.\n     */\n    protected static final int CLIENT_MSG_ON_WEB_READY = COMMON_MSG_BEGIN + 2;\n\n    /**\n     * The message of forced to destroy the session.\n     */\n    protected static final int SESSION_MSG_FORCE_DESTROY = COMMON_MSG_BEGIN + 3;\n\n\n    protected static final int COMMON_MSG_END = COMMON_MSG_BEGIN + 4;\n\n\n    protected static final int FILE_THREAD_MSG_BEGIN = 0;\n\n    /**\n     * The message of saving sonic cache while server close.\n     */\n    protected static final int FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE = FILE_THREAD_MSG_BEGIN + 1;\n\n    /**\n     * The message of saving sonic cache while session finish.\n     */\n    protected static final int FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED = FILE_THREAD_MSG_BEGIN + 2;\n\n    /**\n     * Resource Intercept State : none\n     */\n    protected static final int RESOURCE_INTERCEPT_STATE_NONE = 0;\n\n    /**\n     * Resource Intercept State : intercepting in file thread\n     */\n    protected static final int RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD = 1;\n\n    /**\n     * Resource Intercept State : intercepting in other thread(may be IOThread or other else)\n     */\n    protected static final int RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD = 2;\n\n    /**\n     * Session state, include <code>STATE_NONE</code>, <code>STATE_RUNNING</code>,\n     * <code>STATE_READY</code> and <code>STATE_DESTROY</code>.\n     */\n    protected final AtomicInteger sessionState = new AtomicInteger(STATE_NONE);\n\n    /**\n     * Whether the client initiates a resource interception.\n     */\n    protected final AtomicBoolean wasInterceptInvoked = new AtomicBoolean(false);\n\n    /**\n     * Whether the client is ready.\n     */\n    protected final AtomicBoolean clientIsReady = new AtomicBoolean(false);\n\n    /**\n     * Whether notify the result to page.\n     */\n    private final AtomicBoolean wasNotified = new AtomicBoolean(false);\n\n    /**\n     * Whether it is waiting for the file to be saved. If it is true, the session can not\n     * be destroyed.\n     */\n    protected final AtomicBoolean isWaitingForSaveFile = new AtomicBoolean(false);\n\n    /**\n     * Whether the session is waiting for destroy.\n     */\n    protected final AtomicBoolean isWaitingForDestroy = new AtomicBoolean(false);\n\n    /**\n     * Whether the session is waiting for data. If it is true, the session can not\n     * be destroyed.\n     */\n    protected final AtomicBoolean isWaitingForSessionThread = new AtomicBoolean(false);\n\n\n    /**\n     * Whether the local html is loaded, it is used only the template changes.\n     */\n    protected final AtomicBoolean wasOnPageFinishInvoked = new AtomicBoolean(false);\n\n\n\n    /**\n     * Resource intercept state, include <code>RESOURCE_INTERCEPT_STATE_NONE</code>,\n     * <code>RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD</code>,\n     * <code>RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD</code>\n     * More about it at {https://codereview.chromium.org/1350553005/#ps20001}\n     */\n    protected final AtomicInteger resourceInterceptState = new AtomicInteger(RESOURCE_INTERCEPT_STATE_NONE);\n\n    /**\n     * Indicate current session is reload or not.\n     */\n    protected final AtomicBoolean clientIsReload = new AtomicBoolean(false);\n\n    /**\n     * Session statics var\n     */\n    protected SonicSessionStatistics statistics = new SonicSessionStatistics();\n\n    /**\n     * Sonic server\n     */\n    protected volatile SonicServer server;\n\n    /**\n     * Sonic sub resource downloader\n     */\n    protected volatile SonicDownloadEngine resourceDownloaderEngine;\n\n    /**\n     * The response for client interception.\n     */\n    protected volatile InputStream pendingWebResourceStream;\n\n    /**\n     * The difference data between local and server data.\n     */\n    protected String pendingDiffData = \"\";\n\n    /**\n     * Log id\n     */\n    protected static long sNextSessionLogId = new Random().nextInt(263167);\n\n    final public SonicSessionConfig config;\n\n    public final String id;\n\n    /**\n     * Whether current session is preload.\n     */\n    protected boolean isPreload;\n\n    /**\n     * The time of current session created.\n     */\n    public long createdTime;\n\n\n    /**\n     * The integer id of current session\n     */\n    public final long sId;\n\n    /**\n     * The original url\n     */\n    public String srcUrl;\n\n    protected volatile SonicSessionClient sessionClient;\n\n    protected final Handler mainHandler = new Handler(Looper.getMainLooper(), this);\n\n    protected final CopyOnWriteArrayList<WeakReference<Callback>> stateChangedCallbackList = new CopyOnWriteArrayList<WeakReference<Callback>>();\n\n    protected SonicDiffDataCallback diffDataCallback;\n\n    protected final Handler fileHandler;\n    protected List<String> preloadLinks;\n\n    protected final CopyOnWriteArrayList<WeakReference<SonicSessionCallback>> sessionCallbackList = new CopyOnWriteArrayList<WeakReference<SonicSessionCallback>>();\n\n    /**\n     * This intent saves all of the initialization param.\n     */\n    protected final Intent intent = new Intent();\n\n    /**\n     * The interface is used to inform the listeners that the state of the\n     * session has changed.\n     */\n    public interface Callback {\n\n        /**\n         * When the session's state changes, this method will be invoked.\n         *\n         * @param session   Current session.\n         * @param oldState  The old state.\n         * @param newState  The next state.\n         * @param extraData Extra data.\n         */\n        void onSessionStateChange(SonicSession session, int oldState, int newState, Bundle extraData);\n    }\n\n    /**\n     * Subclasses must implement this to receive messages.\n     */\n    @Override\n    public boolean handleMessage(Message msg) {\n\n        if (SESSION_MSG_FORCE_DESTROY == msg.what) {\n            destroy(true);\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleMessage:force destroy.\");\n            return true;\n        }\n\n        if (isDestroyedOrWaitingForDestroy()) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleMessage error: is destroyed or waiting for destroy.\");\n            return true;\n        }\n\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") handleMessage: msg what = \" + msg.what + \".\");\n        }\n\n        return false;\n    }\n\n    private void saveSonicCacheOnServerClose(SonicServer sonicServer) {\n        // if the session has been destroyed or refresh, exit directly\n        if(isDestroyedOrWaitingForDestroy()) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") doSaveSonicCache: save session files fail.\" +\n                    \" Current session is destroy (\" + isDestroyedOrWaitingForDestroy()  + \") or refresh ( \" + (sonicServer != server) + \")\");\n            return;\n        }\n\n        String htmlString = sonicServer.getResponseData(false);\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") onClose:htmlString size:\"\n                    + (!TextUtils.isEmpty(htmlString) ? htmlString.length() : 0));\n        }\n\n        if (!TextUtils.isEmpty(htmlString)) {\n            long startTime = System.currentTimeMillis();\n            doSaveSonicCache(sonicServer, htmlString);\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClose:separate And save ache finish, cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n        }\n\n        // Current session can be destroyed if it is waiting for destroy.\n        isWaitingForSaveFile.set(false);\n        if (postForceDestroyIfNeed()) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClose: postForceDestroyIfNeed send destroy message.\");\n        }\n    }\n\n    SonicSession(String id, String url, SonicSessionConfig config) {\n        this.id = id;\n        this.config = config;\n        this.sId = (sNextSessionLogId++);\n        this.srcUrl = statistics.srcUrl = url.trim();\n        this.createdTime = System.currentTimeMillis();\n\n        fileHandler = new Handler(SonicEngine.getInstance().getRuntime().getFileThreadLooper(), new Handler.Callback() {\n            @Override\n            public boolean handleMessage(Message msg) {\n                switch (msg.what) {\n                    case FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE: {\n                        final SonicServer sonicServer = (SonicServer) msg.obj;\n                        saveSonicCacheOnServerClose(sonicServer);\n                        return true;\n                    }\n\n                    case FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED: {\n                        final String htmlString = (String)msg.obj;\n                        doSaveSonicCache(server, htmlString);\n                        return true;\n                    }\n                }\n                return false;\n            }\n        });\n\n        SonicConfig sonicConfig = SonicEngine.getInstance().getConfig();\n        if (sonicConfig.GET_COOKIE_WHEN_SESSION_CREATE) {\n            SonicRuntime runtime = SonicEngine.getInstance().getRuntime();\n            String cookie = runtime.getCookie(srcUrl);\n\n            if (!TextUtils.isEmpty(cookie)) {\n                intent.putExtra(SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE, cookie);\n            }\n        }\n\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") create:id=\" + id + \", url = \" + url + \".\");\n        }\n    }\n\n\n    /**\n     * Start the sonic process\n     */\n    public void start() {\n        if (!sessionState.compareAndSet(STATE_NONE, STATE_RUNNING)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") start error:sessionState=\" + sessionState.get() + \".\");\n            return;\n        }\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") now post sonic flow task.\");\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSonicSessionStart();\n            }\n        }\n        statistics.sonicStartTime = System.currentTimeMillis();\n        isWaitingForSessionThread.set(true);\n\n        SonicEngine.getInstance().getRuntime().postTaskToSessionThread(new Runnable() {\n            @Override\n            public void run() {\n                runSonicFlow(true);\n            }\n        });\n\n        notifyStateChange(STATE_NONE, STATE_RUNNING, null);\n    }\n\n    private void runSonicFlow(boolean firstRequest) {\n        if (STATE_RUNNING != sessionState.get()) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") runSonicFlow error:sessionState=\" + sessionState.get() + \".\");\n            return;\n        }\n\n        statistics.sonicFlowStartTime = System.currentTimeMillis();\n\n        String cacheHtml = null;\n        SonicDataHelper.SessionData sessionData;\n        sessionData = getSessionData(firstRequest);\n\n        if (firstRequest) {\n            cacheHtml = SonicCacheInterceptor.getSonicCacheData(this);\n            statistics.cacheVerifyTime = System.currentTimeMillis();\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") runSonicFlow verify cache cost \" + (statistics.cacheVerifyTime - statistics.sonicFlowStartTime) + \" ms\");\n            handleFlow_LoadLocalCache(cacheHtml); // local cache if exist before connection\n        }\n\n        boolean hasHtmlCache = !TextUtils.isEmpty(cacheHtml) || !firstRequest;\n\n        final SonicRuntime runtime = SonicEngine.getInstance().getRuntime();\n        if (!runtime.isNetworkValid()) {\n            //Whether the network is available\n            if (hasHtmlCache && !TextUtils.isEmpty(config.USE_SONIC_CACHE_IN_BAD_NETWORK_TOAST)) {\n                runtime.postTaskToMainThread(new Runnable() {\n                    @Override\n                    public void run() {\n                        if (clientIsReady.get() && !isDestroyedOrWaitingForDestroy()) {\n                            runtime.showToast(config.USE_SONIC_CACHE_IN_BAD_NETWORK_TOAST, Toast.LENGTH_LONG);\n                        }\n                    }\n                }, 1500);\n            }\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") runSonicFlow error:network is not valid!\");\n        } else {\n            handleFlow_Connection(hasHtmlCache, sessionData);\n            statistics.connectionFlowFinishTime = System.currentTimeMillis();\n        }\n\n        // Update session state\n        switchState(STATE_RUNNING, STATE_READY, true);\n\n        isWaitingForSessionThread.set(false);\n\n        // Current session can be destroyed if it is waiting for destroy.\n        if (postForceDestroyIfNeed()) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") runSonicFlow:send force destroy message.\");\n        }\n    }\n\n\n    public boolean refresh() {\n        if (!sessionState.compareAndSet(STATE_READY, STATE_RUNNING)) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") refresh error:sessionState=\" + sessionState.get() + \".\");\n            return false;\n        }\n\n        wasInterceptInvoked.set(false);\n        clientIsReload.set(true);\n\n        srcResultCode = finalResultCode = SONIC_RESULT_CODE_UNKNOWN;\n\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") now refresh sonic flow task.\");\n\n        statistics.sonicStartTime = System.currentTimeMillis();\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSonicSessionRefresh();\n            }\n        }\n\n        isWaitingForSessionThread.set(true);\n\n        SonicEngine.getInstance().getRuntime().postTaskToSessionThread(new Runnable() {\n            @Override\n            public void run() {\n                runSonicFlow(false);\n            }\n        });\n\n        notifyStateChange(STATE_READY, STATE_RUNNING, null);\n        return true;\n    }\n\n    protected Intent createConnectionIntent(SonicDataHelper.SessionData sessionData) {\n        Intent connectionIntent = new Intent();\n        SonicUtils.log(TAG, Log.INFO, String.format(\"Session (%s) send sonic request, etag=(%s), templateTag=(%s)\", id, sessionData.eTag, sessionData.templateTag));\n        connectionIntent.putExtra(getCustomHeadFieldEtagKey(), sessionData.eTag);\n        connectionIntent.putExtra(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, sessionData.templateTag);\n\n        String hostDirectAddress = SonicEngine.getInstance().getRuntime().getHostDirectAddress(srcUrl);\n        if (!TextUtils.isEmpty(hostDirectAddress)) {\n            connectionIntent.putExtra(SonicSessionConnection.DNS_PREFETCH_ADDRESS, hostDirectAddress);\n            statistics.isDirectAddress = true;\n        }\n\n        SonicRuntime runtime = SonicEngine.getInstance().getRuntime();\n        SonicConfig sonicConfig = SonicEngine.getInstance().getConfig();\n        if (!sonicConfig.GET_COOKIE_WHEN_SESSION_CREATE) {\n            String cookie = runtime.getCookie(srcUrl);\n            if (!TextUtils.isEmpty(cookie)) {\n                connectionIntent.putExtra(SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE, cookie);\n            }\n        } else {\n            connectionIntent.putExtra(SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE, intent.getStringExtra(SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE));\n        }\n\n        String userAgent = runtime.getUserAgent();\n        if (!TextUtils.isEmpty(userAgent)) {\n            userAgent += \" Sonic/\" + SonicConstants.SONIC_VERSION_NUM;\n        } else {\n            userAgent = \"Sonic/\" + SonicConstants.SONIC_VERSION_NUM;\n        }\n        connectionIntent.putExtra(SonicSessionConnection.HTTP_HEAD_FILED_USER_AGENT, userAgent);\n        return connectionIntent;\n\n    }\n\n    /**\n     * Initiate a network request to obtain server data.\n     *\n     * @param hasCache Indicates local sonic cache is exist or not.\n     * @param sessionData  SessionData holds eTag templateTag\n     */\n    protected void handleFlow_Connection(boolean hasCache, SonicDataHelper.SessionData sessionData) {\n        // create connection for current session\n        statistics.connectionFlowStartTime = System.currentTimeMillis();\n\n        if (config.SUPPORT_CACHE_CONTROL && statistics.connectionFlowStartTime < sessionData.expiredTime) {\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG,  \"session(\" + sId + \") won't send any request in \" + (sessionData.expiredTime - statistics.connectionFlowStartTime) + \".ms\");\n            }\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionHitCache();\n                }\n            }\n            return;\n        }\n\n        server = new SonicServer(this, createConnectionIntent(sessionData));\n\n        // Connect to web server\n        int responseCode = server.connect();\n        if (SonicConstants.ERROR_CODE_SUCCESS == responseCode) {\n            responseCode = server.getResponseCode();\n            // If the page has set cookie, sonic will set the cookie to kernel.\n            long startTime = System.currentTimeMillis();\n            Map<String, List<String>> headerFieldsMap = server.getResponseHeaderFields();\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") connection get header fields cost = \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n\n            startTime = System.currentTimeMillis();\n            setCookiesFromHeaders(headerFieldsMap, shouldSetCookieAsynchronous());\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") connection set cookies cost = \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n        }\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_Connection: respCode = \" + responseCode + \", cost \" + (System.currentTimeMillis() - statistics.connectionFlowStartTime) + \" ms.\");\n\n        // Destroy before server response\n        if (isDestroyedOrWaitingForDestroy()) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_Connection error: destroy before server response!\");\n            return;\n        }\n\n        // when find preload links in headers\n        String preloadLink = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_LINK);\n        if (!TextUtils.isEmpty(preloadLink)) {\n            preloadLinks = Arrays.asList(preloadLink.split(\";\"));\n            handleFlow_PreloadSubResource();\n        }\n\n        // When response code is 304\n        if (HttpURLConnection.HTTP_NOT_MODIFIED == responseCode) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_Connection: Server response is not modified.\");\n            handleFlow_NotModified();\n            return;\n        }\n\n        // When response code is not 304 nor 200\n        if (HttpURLConnection.HTTP_OK != responseCode) {\n            handleFlow_HttpError(responseCode);\n            SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, responseCode);\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_Connection error: response code(\" + responseCode + \") is not OK!\");\n            return;\n        }\n\n        String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_Connection: cacheOffline is \" + cacheOffline + \".\");\n\n        // When cache-offline is \"http\": which means sonic server is in bad condition, need feed back to run standard http request.\n        if (OFFLINE_MODE_HTTP.equalsIgnoreCase(cacheOffline)) {\n            if (hasCache) {\n                //stop loading local sonic cache.\n                handleFlow_ServiceUnavailable();\n            }\n            long unavailableTime = System.currentTimeMillis() + SonicEngine.getInstance().getConfig().SONIC_UNAVAILABLE_TIME;\n            SonicDataHelper.setSonicUnavailableTime(id, unavailableTime);\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionUnAvailable();\n                }\n            }\n            return;\n        }\n\n        // When cacheHtml is empty, run First-Load flow\n        if (!hasCache) {\n            handleFlow_FirstLoad();\n            return;\n        }\n\n        // Handle cache-offline : false or null.\n        if (TextUtils.isEmpty(cacheOffline) || OFFLINE_MODE_FALSE.equalsIgnoreCase(cacheOffline)) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_Connection error: Cache-Offline is empty or false!\");\n            SonicUtils.removeSessionCache(id);\n            return;\n        }\n\n\n        String eTag = server.getResponseHeaderField(getCustomHeadFieldEtagKey());\n        String templateChange = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_CHANGE);\n\n        // When eTag is empty, run fix logic\n        if (TextUtils.isEmpty(eTag) || TextUtils.isEmpty(templateChange)) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_Connection error: eTag is ( \" + eTag + \" ) , templateChange is ( \" + templateChange + \" )!\");\n            SonicUtils.removeSessionCache(id);\n            return;\n        }\n\n        // When templateChange is false : means data update\n        if (\"false\".equals(templateChange) || \"0\".equals(templateChange)) {\n            handleFlow_DataUpdate(server.getUpdatedData());\n        } else {\n            handleFlow_TemplateChange(server.getResponseData(clientIsReload.get()));\n        }\n    }\n\n    @Nullable\n    private SonicDataHelper.SessionData getSessionData(boolean firstRequest) {\n        SonicDataHelper.SessionData sessionData;\n        if (firstRequest) {\n            sessionData = SonicDataHelper.getSessionData(id);\n        } else {\n            //get sessionData from last connection\n            if (server != null) {\n                sessionData = new SonicDataHelper.SessionData();\n                sessionData.eTag = server.getResponseHeaderField(getCustomHeadFieldEtagKey());\n                sessionData.templateTag = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n                if ((TextUtils.isEmpty(sessionData.eTag) || TextUtils.isEmpty(sessionData.templateTag)) && config.SUPPORT_LOCAL_SERVER) {\n                    server.separateTemplateAndData();\n                    sessionData.eTag = server.getResponseHeaderField(getCustomHeadFieldEtagKey());\n                    sessionData.templateTag = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n                }\n                sessionData.sessionId = id;\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") runSonicFlow error:server is not valid!\");\n                sessionData = new SonicDataHelper.SessionData();\n            }\n        }\n        return sessionData;\n    }\n\n    protected abstract void handleFlow_LoadLocalCache(String cacheHtml);\n\n    /**\n     * Handle sonic first {@link SonicSession#SONIC_RESULT_CODE_FIRST_LOAD} logic.\n     */\n    protected abstract void handleFlow_FirstLoad();\n\n\n    /**\n     * Handle data update {@link SonicSession#SONIC_RESULT_CODE_DATA_UPDATE} logic.\n     * @param serverRsp Server response data.\n     */\n    protected abstract void handleFlow_DataUpdate(String serverRsp);\n\n    /**\n     * Handle template update {@link SonicSession#SONIC_RESULT_CODE_TEMPLATE_CHANGE} logic.\n     * @param newHtml new Html string from web-server\n     */\n    protected abstract void handleFlow_TemplateChange(String newHtml);\n\n    protected abstract void handleFlow_HttpError(int responseCode);\n\n    protected abstract void handleFlow_ServiceUnavailable();\n\n    protected void handleFlow_NotModified() {\n        Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n        msg.arg1 = SONIC_RESULT_CODE_HIT_CACHE;\n        msg.arg2 = SONIC_RESULT_CODE_HIT_CACHE;\n        mainHandler.sendMessage(msg);\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionHitCache();\n            }\n        }\n    }\n\n    /**\n     * Handle sub resource preload when find \"sonic-link\" header in http response.\n     */\n    private void handleFlow_PreloadSubResource() {\n        if (preloadLinks == null || preloadLinks.isEmpty()) {\n            return;\n        }\n        SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n            @Override\n            public void run() {\n                if (resourceDownloaderEngine == null) {\n                    resourceDownloaderEngine = new SonicDownloadEngine(SonicDownloadCache.getSubResourceCache());\n                }\n                resourceDownloaderEngine.addSubResourcePreloadTask(preloadLinks);\n            }\n        }, 0);\n    }\n\n\n\n    void setIsPreload(String url) {\n        this.isPreload = true;\n        this.srcUrl = statistics.srcUrl = url.trim();\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") is preload, new url=\" + url + \".\");\n        }\n    }\n\n    public boolean isPreload() {\n        return isPreload;\n    }\n\n    public SonicSessionStatistics getStatistics() {\n        return statistics;\n    }\n\n    protected boolean addSessionStateChangedCallback(Callback callback) {\n        return stateChangedCallbackList.add(new WeakReference<Callback>(callback));\n    }\n\n    protected boolean removeSessionStateChangedCallback(Callback callback) {\n        return stateChangedCallbackList.remove(new WeakReference<Callback>(callback));\n    }\n\n\n    public boolean addSessionCallback(SonicSessionCallback callback) {\n        return sessionCallbackList.add(new WeakReference<SonicSessionCallback>(callback));\n    }\n\n    public boolean removeSessionCallback(SonicSessionCallback callback) {\n        WeakReference<SonicSessionCallback> ref = null;\n        for (WeakReference<SonicSessionCallback> reference : sessionCallbackList) {\n            if (reference != null && reference.get() == callback) {\n                ref = reference;\n                break;\n            }\n        }\n\n        if (ref != null) {\n            return sessionCallbackList.remove(ref);\n        } else {\n            return false;\n        }\n    }\n\n    public String getCurrentUrl() {\n        return srcUrl;\n    }\n\n    public int getFinalResultCode() {\n        return finalResultCode;\n    }\n\n    public int getSrcResultCode() {\n        return srcResultCode;\n    }\n\n    public boolean isDestroyedOrWaitingForDestroy() {\n        return STATE_DESTROY == sessionState.get() || isWaitingForDestroy.get();\n    }\n\n    /**\n     * Destroy the session if it is waiting for destroy and it is can be destroyed.\n     *\n     * @return Return true if the session is waiting for destroy and it is can be destroyed.\n     */\n    protected boolean postForceDestroyIfNeed() {\n        if (isWaitingForDestroy.get() && canDestroy()) {\n            mainHandler.sendEmptyMessage(SESSION_MSG_FORCE_DESTROY);\n            return true;\n        }\n        return false;\n    }\n\n    protected boolean canDestroy() {\n        if (isWaitingForSessionThread.get() || isWaitingForSaveFile.get()) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") canDestroy:false, isWaitingForSessionThread=\" + isWaitingForDestroy.get() + \", isWaitingForSaveFile=\" + isWaitingForSaveFile.get());\n            return false;\n        }\n        return true;\n    }\n\n    protected boolean switchState(int fromState, int toState, boolean notify) {\n        if (sessionState.compareAndSet(fromState, toState)) {\n            if (notify) {\n                synchronized (sessionState) {\n                    sessionState.notify();\n                }\n            }\n            notifyStateChange(fromState, toState, null);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * If the kernel obtain inputStream from a <code>SonicSessionStream</code>, the inputStream\n     * will be closed when the kernel reads the data.This method is invoked when the sonicSessionStream\n     * close.\n     *\n     * <p>\n     *  If the html is read complete, sonic will separate the html to template and data, and save these\n     *  data.\n     *\n     * @param sonicServer The actual server connection of current SonicSession.\n     * @param readComplete Whether the html is read complete.\n     */\n    public void onServerClosed(final SonicServer sonicServer, final boolean readComplete) {\n        // if the session has been destroyed, exit directly\n        if(isDestroyedOrWaitingForDestroy()) {\n            return;\n        }\n\n        // set pendingWebResourceStream to null，or it has a problem when client reload the page.\n        if (null != pendingWebResourceStream) {\n            pendingWebResourceStream = null;\n        }\n\n        isWaitingForSaveFile.set(true);\n        long onCloseStartTime = System.currentTimeMillis();\n\n        //Separate and save html.\n        if (readComplete) {\n            String cacheOffline = sonicServer.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n            if (SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, sonicServer.getResponseHeaderFields())) {\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClose:offline->\" + cacheOffline + \" , post separateAndSaveCache task.\");\n\n                Message message = Message.obtain();\n                message.what = FILE_THREAD_SAVE_CACHE_ON_SERVER_CLOSE;\n                message.obj = sonicServer;\n                fileHandler.sendMessageDelayed(message, 1500);\n                return;\n            }\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClose:offline->\" + cacheOffline + \" , so do not need cache to file.\");\n        } else {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") onClose error:readComplete = false!\" );\n        }\n\n        // Current session can be destroyed if it is waiting for destroy.\n        isWaitingForSaveFile.set(false);\n        if (postForceDestroyIfNeed()) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClose: postForceDestroyIfNeed send destroy message in chromium_io thread.\");\n        }\n\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") onClose cost \" + (System.currentTimeMillis() - onCloseStartTime) + \" ms.\");\n        }\n    }\n\n    protected void postTaskToSaveSonicCache(final String htmlString) {\n        Message msg = Message.obtain();\n        msg.what = FILE_THREAD_SAVE_CACHE_ON_SESSION_FINISHED;\n        msg.obj = htmlString;\n\n        fileHandler.sendMessageDelayed(msg, 1500);\n    }\n\n    protected void doSaveSonicCache(SonicServer sonicServer, String htmlString) {\n        // if the session has been destroyed, exit directly\n        if(isDestroyedOrWaitingForDestroy() || server == null) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") doSaveSonicCache: save session files fail. Current session is destroy!\");\n            return;\n        }\n\n        long startTime = System.currentTimeMillis();\n        String template = sonicServer.getTemplate();\n        String updatedData = sonicServer.getUpdatedData();\n\n        if (!TextUtils.isEmpty(htmlString) && !TextUtils.isEmpty(template)) {\n            String newHtmlSha1 = sonicServer.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_HTML_SHA1);\n            if (TextUtils.isEmpty(newHtmlSha1)) {\n                newHtmlSha1 = SonicUtils.getSHA1(htmlString);\n            }\n\n            String eTag = sonicServer.getResponseHeaderField(getCustomHeadFieldEtagKey());\n            String templateTag = sonicServer.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n\n            Map<String, List<String>> headers = sonicServer.getResponseHeaderFields();\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionSaveCache(htmlString, template, updatedData);\n                }\n            }\n\n            if (SonicUtils.saveSessionFiles(id, htmlString, template, updatedData, headers)) {\n                long htmlSize = new File(SonicFileUtils.getSonicHtmlPath(id)).length();\n                SonicUtils.saveSonicData(id, eTag, templateTag, newHtmlSha1, htmlSize, headers);\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") doSaveSonicCache: save session files fail.\");\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_WRITE_FILE_FAIL);\n            }\n        } else {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") doSaveSonicCache: save separate template and data files fail.\");\n            SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_SPLIT_HTML_FAIL);\n        }\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") doSaveSonicCache: finish, cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n    }\n\n    /**\n     * When the session state changes, notify the listeners.\n     *\n     * @param oldState  The old state.\n     * @param newState  The nex state.\n     * @param extraData The extra data.\n     */\n    protected void notifyStateChange(int oldState, int newState, Bundle extraData) {\n        Callback callback;\n        for (WeakReference<Callback> callbackWeakRef : stateChangedCallbackList) {\n            callback = callbackWeakRef.get();\n            if (null != callback) {\n                callback.onSessionStateChange(this, oldState, newState, extraData);\n            }\n        }\n    }\n\n    /**\n     * Record the sonic mode, notify the result to page if necessary.\n     *\n     * @param srcCode   The original mode.\n     * @param finalCode The final mode.\n     * @param notify    Whether notify te result to page.\n     */\n    protected void setResult(int srcCode, int finalCode, boolean notify) {\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \")  setResult: srcCode=\" + srcCode + \", finalCode=\" + finalCode + \".\");\n        statistics.originalMode = srcResultCode = srcCode;\n        statistics.finalMode = finalResultCode = finalCode;\n\n        if (!notify) return;\n\n        if (wasNotified.get()) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \")  setResult: notify error -> already has notified!\");\n        }\n\n        if (null == diffDataCallback) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \")  setResult: notify fail as webCallback is not set, please wait!\");\n            return;\n        }\n\n        if (this.finalResultCode == SONIC_RESULT_CODE_UNKNOWN) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \")  setResult: notify fail finalResultCode is not set, please wait!\");\n            return;\n        }\n\n        wasNotified.compareAndSet(false, true);\n\n        final JSONObject json = new JSONObject();\n        try {\n            if (finalResultCode == SONIC_RESULT_CODE_DATA_UPDATE) {\n                JSONObject pendingObject = new JSONObject(pendingDiffData);\n\n                if (!pendingObject.has(\"local_refresh_time\")) {\n                    SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") setResult: no any updated data. \" + pendingDiffData);\n                    pendingDiffData = \"\";\n                    return;\n                } else {\n                    long timeDelta = System.currentTimeMillis() - pendingObject.optLong(\"local_refresh_time\", 0);\n                    if (timeDelta > 30 * 1000) {\n                        SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") setResult: notify fail as receive js call too late, \" + (timeDelta / 1000.0) + \" s.\");\n                        pendingDiffData = \"\";\n                        return;\n                    } else {\n                        if (SonicUtils.shouldLog(Log.DEBUG)) {\n                            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") setResult: notify receive js call in time: \" + (timeDelta / 1000.0) + \" s.\");\n                        }\n                        if (timeDelta > 0) json.put(\"local_refresh_time\", timeDelta);\n                    }\n                }\n\n\n                pendingObject.remove(WEB_RESPONSE_LOCAL_REFRESH_TIME);\n                json.put(WEB_RESPONSE_DATA, pendingObject.toString());\n            }\n            json.put(WEB_RESPONSE_CODE, finalResultCode);\n            json.put(WEB_RESPONSE_SRC_CODE, srcResultCode);\n\n            final JSONObject extraJson = new JSONObject();\n            if (server != null) {\n                extraJson.put(getCustomHeadFieldEtagKey(), server.getResponseHeaderField(getCustomHeadFieldEtagKey()));\n                extraJson.put(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG, server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG));\n                extraJson.put(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE, server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE));\n            }\n            extraJson.put(\"isReload\", clientIsReload);\n\n            json.put(WEB_RESPONSE_EXTRA, extraJson);\n        } catch (Throwable e) {\n            e.printStackTrace();\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") setResult: notify error -> \" + e.getMessage());\n        }\n\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            String logStr = json.toString();\n            if (logStr.length() > 512) {\n                logStr = logStr.substring(0, 512);\n            }\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") setResult: notify now call jsCallback, jsonStr = \" + logStr);\n        }\n\n\n        pendingDiffData = null;\n        long delta = 0L;\n        if (clientIsReload.get()) {\n            delta = System.currentTimeMillis() - statistics.diffDataCallbackTime;\n            delta = delta >= 2000 ? 0L : delta;\n        }\n\n        if (delta > 0L ) {\n            delta = 2000L - delta;\n            SonicEngine.getInstance().getRuntime().postTaskToMainThread(new Runnable() {\n                @Override\n                public void run() {\n                    if (diffDataCallback != null) {\n                        diffDataCallback.callback(json.toString());\n                        statistics.diffDataCallbackTime = System.currentTimeMillis();\n                    }\n                }\n            }, delta);\n        } else {\n            diffDataCallback.callback(json.toString());\n            statistics.diffDataCallbackTime = System.currentTimeMillis();\n        }\n\n    }\n\n    public boolean bindClient(SonicSessionClient client) {\n        if (null == this.sessionClient) {\n            this.sessionClient = client;\n            client.bindSession(this);\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") bind client.\");\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Client informs sonic that it is ready.\n     * Client ready means it's webview has been initialized, can start load url or load data.\n     *\n     * @return True if it is set for the first time\n     */\n    public boolean onClientReady() {\n        return false;\n    }\n\n    /**\n     * When the webview initiates a resource interception, the client invokes the method to retrieve the data\n     *\n     * @param url The url of this session\n     * @return Return the data to kernel\n     */\n    public final Object onClientRequestResource(String url) {\n        String currentThreadName = Thread.currentThread().getName();\n        if (CHROME_FILE_THREAD.equals(currentThreadName)) {\n            resourceInterceptState.set(RESOURCE_INTERCEPT_STATE_IN_FILE_THREAD);\n        } else {\n            resourceInterceptState.set(RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD);\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"onClientRequestResource called in \" + currentThreadName + \".\");\n            }\n        }\n        Object object = isMatchCurrentUrl(url)\n                ? onRequestResource(url)\n                : (resourceDownloaderEngine != null ? resourceDownloaderEngine.onRequestSubResource(url, this) : null);\n        resourceInterceptState.set(RESOURCE_INTERCEPT_STATE_NONE);\n        return object;\n    }\n\n    /**\n     * Whether should set cookie asynchronous or not , if {@code onClientRequestResource} is calling\n     * in IOThread, it should not call set cookie synchronous which will handle in IOThread as it may\n     * cause deadlock\n     * More about it see {https://issuetracker.google.com/issues/36989494#c8}\n     * Fix VasSonic issue {https://github.com/Tencent/VasSonic/issues/90}\n     *\n     * @return Return the data to kernel\n     */\n    protected boolean shouldSetCookieAsynchronous() {\n        return RESOURCE_INTERCEPT_STATE_IN_OTHER_THREAD == resourceInterceptState.get();\n    }\n\n    /**\n     * Set cookies to webview from headers\n     *\n     * @param headers headers from server response\n     * @param executeInNewThread whether execute in new thread or not\n     * @return Set cookie success or not\n     */\n    protected boolean setCookiesFromHeaders(Map<String, List<String>> headers, boolean executeInNewThread) {\n        if (null != headers) {\n            final List<String> cookies = headers.get(SonicSessionConnection.HTTP_HEAD_FILED_SET_COOKIE.toLowerCase());\n            if (null != cookies && 0 != cookies.size()) {\n                if (!executeInNewThread) {\n                    return SonicEngine.getInstance().getRuntime().setCookie(getCurrentUrl(), cookies);\n                } else {\n                    SonicUtils.log(TAG, Log.INFO, \"setCookiesFromHeaders asynchronous in new thread.\");\n                    SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            SonicEngine.getInstance().getRuntime().setCookie(getCurrentUrl(), cookies);\n                        }\n                    }, 0L);\n                }\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * When the webview initiates a main resource interception, the client invokes this method to retrieve the data\n     *\n     * @param url The url of this session\n     * @return Return the data to kernel\n     */\n    protected Object onRequestResource(String url) {\n        return null;\n    }\n\n\n\n    /**\n     * Client will call this method to obtain the update data when the page shows the content.\n     *\n     * @param diffDataCallback  Sonic provides the latest data to the page through this callback\n     * @return The result\n     */\n    public boolean onWebReady(SonicDiffDataCallback diffDataCallback) {\n        return false;\n    }\n\n    public boolean onClientPageFinished(String url) {\n        if (isMatchCurrentUrl(url)) {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onClientPageFinished:url=\" + url + \".\");\n            wasOnPageFinishInvoked.set(true);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Whether the incoming url matches the current url,it will\n     * ignore url parameters\n     *\n     * @param url The incoming url.\n     * @return Whether the incoming url matches the current url.\n     */\n    public boolean isMatchCurrentUrl(String url) {\n        try {\n            Uri currentUri = Uri.parse(srcUrl);\n            Uri uri = Uri.parse(url);\n\n            String currentPath = (currentUri.getHost() + currentUri.getPath());\n            String pendingPath = uri.getHost() + uri.getPath();\n\n            if (currentUri.getHost().equalsIgnoreCase(uri.getHost())) {\n                if (!currentPath.endsWith(\"/\")) currentPath = currentPath + \"/\";\n                if (!pendingPath.endsWith(\"/\")) pendingPath = pendingPath + \"/\";\n                return currentPath.equalsIgnoreCase(pendingPath);\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"isMatchCurrentUrl error:\" + e.getMessage());\n        }\n        return false;\n    }\n\n    /**\n     * Get header info with the original url of current session.\n     *\n     * @return The header info.\n     */\n    protected HashMap<String, String> getHeaders() {\n        if (null != server) {\n            return SonicUtils.getFilteredHeaders(server.getResponseHeaderFields());\n        }\n        return null;\n    }\n\n    /**\n     * Get the charset from the latest response http header.\n     * @return The charset.\n     */\n    protected String getCharsetFromHeaders() {\n        HashMap<String, String> headers = getHeaders();\n        return getCharsetFromHeaders(headers);\n    }\n\n    public String getCharsetFromHeaders(Map<String, String> headers) {\n        String charset = SonicUtils.DEFAULT_CHARSET;\n        String key = SonicSessionConnection.HTTP_HEAD_FIELD_CONTENT_TYPE.toLowerCase();\n        if (headers != null && headers.containsKey(key)) {\n            String headerValue = headers.get(key);\n            if (!TextUtils.isEmpty(headerValue) ) {\n                charset = SonicUtils.getCharset(headerValue);\n            }\n        }\n        return charset;\n    }\n\n    /**\n     * Get header info from local cache headers\n     *\n     * @return The header info.\n     */\n    protected HashMap<String, String> getCacheHeaders() {\n        String headerFilePath = SonicFileUtils.getSonicHeaderPath(id);\n        return SonicUtils.getFilteredHeaders(SonicFileUtils.getHeaderFromLocalCache(headerFilePath));\n    }\n\n    public SonicSessionClient getSessionClient() {\n        return sessionClient;\n    }\n\n    protected String getCustomHeadFieldEtagKey() {\n        return server != null ? server.getCustomHeadFieldEtagKey() : SonicSessionConnection.CUSTOM_HEAD_FILED_ETAG;\n    }\n\n    public void destroy() {\n        destroy(false);\n    }\n\n    protected void destroy(boolean force) {\n        int curState = sessionState.get();\n        if (STATE_DESTROY != curState) {\n\n            if (null != sessionClient) {\n                sessionClient = null;\n            }\n\n            if (null != pendingWebResourceStream) {\n                try {\n                    pendingWebResourceStream.close();\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"pendingWebResourceStream.close error:\" + e.getMessage());\n                }\n                pendingWebResourceStream = null;\n            }\n\n            if (null != pendingDiffData) {\n                pendingDiffData = null;\n            }\n\n            clearSessionData();\n\n            checkAndClearCacheData();\n\n            if (force || canDestroy()) {\n                sessionState.set(STATE_DESTROY);\n                synchronized (sessionState) {\n                    sessionState.notify();\n                }\n\n                if (null != server && !force) {\n                    server.disconnect();\n                    server = null;\n                }\n\n                notifyStateChange(curState, STATE_DESTROY, null);\n\n                mainHandler.removeMessages(SESSION_MSG_FORCE_DESTROY);\n\n                stateChangedCallbackList.clear();\n\n                isWaitingForDestroy.set(false);\n\n                for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                    SonicSessionCallback callback = ref.get();\n                    if (callback != null) {\n                        callback.onSessionDestroy();\n                    }\n                }\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") final destroy, force=\" + force + \".\");\n                return;\n            }\n\n            if (isWaitingForDestroy.compareAndSet(false, true)) {\n                mainHandler.sendEmptyMessageDelayed(SESSION_MSG_FORCE_DESTROY, 6000);\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") waiting for destroy, current state =\" + curState + \".\");\n            }\n        }\n    }\n\n    protected void clearSessionData() {\n\n    }\n\n    /**\n     * check and clear the sonic cache and resource cache\n     */\n    private void checkAndClearCacheData() {\n        SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n            @Override\n            public void run() {\n                if (SonicUtils.shouldClearCache(SonicEngine.getInstance().getConfig().SONIC_CACHE_CHECK_TIME_INTERVAL)) {\n                    SonicEngine.getInstance().trimSonicCache();\n                    SonicUtils.saveClearCacheTime(System.currentTimeMillis());\n                }\n            }\n        }, 50);\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionCallback.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\n/**\n * The life circle callback of SonicSession\n */\ninterface SonicSessionCallback {\n    /**\n     * This method will be called while sonic load local cache.\n     * @param cacheHtml Current sonic local cache.\n     */\n    void onSessionLoadLocalCache(String cacheHtml);\n\n    /**\n     * This method will be called when sonic receive updated data from server.\n     * @param serverRsp Server response data.\n     */\n    void onSessionDataUpdated(String serverRsp);\n\n    /**\n     * This method will be called when sonic first send request and receive server data\n     * @param html The new html content from server.\n     */\n    void onSessionFirstLoad(String html);\n\n    /**\n     * This method will be called when sonic receive error.\n     * @param responseCode Http response code\n     */\n    void onSessionHttpError(int responseCode);\n\n    /**\n     * This method will be called when current sonic cache is the same with remote server.\n     */\n    void onSessionHitCache();\n\n    /**\n     * This method will be called when sonic request is invalid and server return \"Cache-Offline: http\"\n     */\n    void onSessionUnAvailable();\n\n    /**\n     * This method will be called when sonic handle template change.\n     * @param newHtml\n     */\n    void onSessionTemplateChanged(String newHtml);\n\n    /**\n     * This method will be called when sonic save cache from server.\n     *\n     * @param htmlString The whole html content.\n     * @param templateString The template content.\n     * @param dataString The data content.\n     */\n    void onSessionSaveCache(String htmlString, String templateString, String dataString);\n\n    /**\n     * This method will be called when sonic start to send request.\n     */\n    void onSonicSessionStart() ;\n\n    /**\n     * This method will be called when sonic session destroy.\n     */\n    void onSessionDestroy();\n\n    /**\n     * This method will be called when sonic session refresh.\n     */\n    void onSonicSessionRefresh();\n\n    /**\n     * an empty implementation of {@link SonicSessionCallback}\n     */\n    public class SimpleCallbackImpl implements SonicSessionCallback {\n\n        @Override\n        public void onSessionLoadLocalCache(String cacheHtml) {\n\n        }\n\n        @Override\n        public void onSessionDataUpdated(String serverRsp) {\n\n        }\n\n        @Override\n        public void onSessionFirstLoad(String html) {\n\n        }\n\n        @Override\n        public void onSessionHttpError(int responseCode) {\n\n        }\n\n        @Override\n        public void onSessionHitCache() {\n\n        }\n\n        @Override\n        public void onSessionUnAvailable() {\n\n        }\n\n        @Override\n        public void onSessionTemplateChanged(String newHtml) {\n\n        }\n\n        @Override\n        public void onSessionSaveCache(String htmlString, String templateString, String dataString) {\n\n        }\n\n        @Override\n        public void onSonicSessionStart() {\n\n        }\n\n        @Override\n        public void onSessionDestroy() {\n\n        }\n\n        @Override\n        public void onSonicSessionRefresh() {\n\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionClient.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Bundle;\n\nimport java.util.HashMap;\n\n/**\n * <code>SonicSessionClient</code> is a thin API class that delegates its public API to\n * a backend WebView class instance, such as loadUrl and loadDataWithBaseUrl.\n */\n\npublic abstract class SonicSessionClient {\n\n    /**\n     * Sonic session of current(this) client\n     */\n    private SonicSession session;\n\n    /**\n     * Notify client is ready to accept data\n     */\n    public void clientReady() {\n        if (session != null) {\n            session.onClientReady();\n        }\n    }\n\n    /**\n     * Webview ask the host client to intercept request, this method should be called when webview\n     * call shouldInterceptRequest.\n     *\n     * @param url The target url which need to request web response\n     *\n     * @return The data to kernel.\n     */\n    public Object requestResource(String url) {\n        if (session != null) {\n            return session.onClientRequestResource(url);\n        }\n        return null;\n    }\n\n    /**\n     * The page execute a java script function to invoke a native method by javascript interface,\n     * this callback will be called when sonic has finished diff data.\n     * @param callback A callback of web page\n     */\n    public void getDiffData(SonicDiffDataCallback callback) {\n        if (session != null) {\n            session.onWebReady(callback);\n        }\n    }\n\n    /**\n     * We need to tell the session when onPageFinished is called by WebViewClient since to make a\n     * better reload when current hit template-changed case.\n     *\n     * @param url The target url which is page finished\n     */\n    public void pageFinish(String url) {\n        if (session != null) {\n            session.onClientPageFinished(url);\n        }\n    }\n\n    /**\n     * Bind a sonic session to current client\n     *\n     * @param session A sonic session\n     */\n    public void bindSession(SonicSession session) {\n        this.session = session;\n    }\n\n    /**\n     * We add this method to decoupling webview since some application may use x5 webview or others.\n     *\n     * @param url   Url which need to load\n     * @param extraData Extra data\n     */\n    public abstract void loadUrl(String url, Bundle extraData);\n\n\n    /**\n     * We add this method to decoupling webview since some application may use x5 webview or others.\n     *\n     * @param baseUrl    The URL to use as the page's base URL. If null defaults to\n     *                   'about:blank'.\n     * @param data       A String of data in the given encoding\n     * @param mimeType   the MIMEType of the data, e.g. 'text/html'. If null,\n     *                   defaults to 'text/html'.\n     * @param encoding   The encoding of the data\n     * @param historyUrl The URL to use as the history entry. If null defaults\n     *                   to 'about:blank'. If non-null, this must be a valid URL.\n     */\n    public abstract void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl);\n\n    /**\n     * We add this method to decoupling webview since some application may use x5 webview or others.\n     *\n     * @param baseUrl    The URL to use as the page's base URL. If null defaults to\n     *                   'about:blank'.\n     * @param data       A String of data in the given encoding\n     * @param mimeType   The MIMEType of the data, e.g. 'text/html'. If null,\n     *                   defaults to 'text/html'.\n     * @param encoding   The encoding of the data\n     * @param historyUrl The URL to use as the history entry. If null defaults\n     *                   to 'about:blank'. If non-null, this must be a valid URL.\n     * @param headers    The headers\n     */\n    public abstract void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap<String, String> headers);\n\n    /**\n     * We add this method to decoupling webview since some application may use x5 webview or others.\n     * When we hit template-change case, webview may load twice(first load:local cache second load:new page)\n     * when user press back button, if we do not clear history,it will return to the first load case\n     * which will make user feel unsure about the action. So we need to clear history if need.\n     */\n    public void clearHistory() {\n\n    }\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionConfig.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport java.util.Map;\n\n/**\n *\n * The sonicSession configurations. A sonicSession configuration describes\n * the http(s) connection time out, the way sonicSession's id be generated and\n * so on\n *\n */\npublic class SonicSessionConfig {\n\n    /**\n     * Http(s) connection time out , default 5s\n     */\n    int CONNECT_TIMEOUT_MILLIS = 5000;\n\n    /**\n     * Http(s) read time out, default 15s\n     */\n    int READ_TIMEOUT_MILLIS = 15000;\n\n    /**\n     * Buffer size when read data from network, default 10KB\n     */\n    int READ_BUF_SIZE = 1024 * 10;\n\n    /**\n     * Preloaded session expiration time, default 3 minute\n     */\n    long PRELOAD_SESSION_EXPIRED_TIME = 3 * 60 * 1000;\n\n    /**\n     * Accept diff data or not, if accept diff data server will return\n     * only update data when local exists html data.\n     */\n    boolean ACCEPT_DIFF_DATA = true;\n\n    /**\n     * Local data is related to user id or nor, if true local data is used only by this user.\n     */\n    boolean IS_ACCOUNT_RELATED = true;\n\n    /**\n     * Need reload url in bad network or not.\n     */\n    boolean RELOAD_IN_BAD_NETWORK = false;\n\n    /**\n     * SonicSession start flow when created or not, if true, SonicSession will load local data\n     * and initiate an http request when created, or these will be do when client ready\n     */\n    boolean AUTO_START_WHEN_CREATE = true;\n\n    /**\n     * Need to check the Cache-Control response header or not.\n     */\n    boolean SUPPORT_CACHE_CONTROL = false;\n\n    /**\n     * Use local Sonic Server or not. If SUPPORT_LOCAL_SERVER is true, Sonic will treat normal request as sonic request\n     * to separate html into template and data file.\n     */\n    boolean SUPPORT_LOCAL_SERVER = false;\n\n    /**\n     * The toast when network unavailable\n     */\n    String USE_SONIC_CACHE_IN_BAD_NETWORK_TOAST = \"Bad Network!\";\n\n    /**\n     * The mode of SonicSession, include{@link QuickSonicSession} and {@link StandardSonicSession}\n     */\n    int sessionMode = SonicConstants.SESSION_MODE_QUICK;\n\n    /**\n     * {@link SonicCacheInterceptor} object, provider local data\n     */\n    SonicCacheInterceptor cacheInterceptor = null;\n\n    /**\n     *{@link SonicSessionConnectionInterceptor} object, provider SonicSessionConnection\n     */\n    SonicSessionConnectionInterceptor connectionInterceptor = null;\n\n    /**\n     * The custom request headers which will be sent to web server\n     */\n    Map<String, String> customRequestHeaders = null;\n\n    /**\n     * The custom response headers which will be sent to webView for intercept WebResourceResponse\n     */\n    Map<String, String> customResponseHeaders = null;\n\n    @Override\n    public boolean equals(Object other) {\n        if (other instanceof SonicSessionConfig) {\n            SonicSessionConfig config = (SonicSessionConfig)other;\n            return sessionMode == config.sessionMode && SUPPORT_LOCAL_SERVER == config.SUPPORT_LOCAL_SERVER;\n        }\n\n        return false;\n\n    }\n\n    private SonicSessionConfig() {\n\n    }\n\n    /**\n     * Builder for SonicSessionConfig\n     */\n    public static class Builder {\n\n        private final SonicSessionConfig target;\n\n        public Builder() {\n            target = new SonicSessionConfig();\n        }\n\n        public Builder setConnectTimeoutMillis(int connectTimeoutMillis) {\n            target.CONNECT_TIMEOUT_MILLIS = connectTimeoutMillis;\n            return this;\n        }\n\n        public Builder setReadTimeoutMillis(int readTimeoutMillis) {\n            target.READ_TIMEOUT_MILLIS = readTimeoutMillis;\n            return this;\n        }\n\n        public Builder setReadBufferSize(int readBufferSize) {\n            target.READ_BUF_SIZE = readBufferSize;\n            return this;\n        }\n\n        public Builder setPreloadSessionExpiredTimeMillis(long preloadSessionExpiredTimeMillis) {\n            target.PRELOAD_SESSION_EXPIRED_TIME = preloadSessionExpiredTimeMillis;\n            return this;\n        }\n\n        public Builder setAcceptDiff(boolean enable) {\n            target.ACCEPT_DIFF_DATA = enable;\n            return this;\n        }\n\n        public Builder setIsAccountRelated(boolean value) {\n            target.IS_ACCOUNT_RELATED = value;\n            return this;\n        }\n\n        public Builder setReloadInBadNetwork(boolean reloadInBadNetwork) {\n            target.RELOAD_IN_BAD_NETWORK = reloadInBadNetwork;\n            return this;\n        }\n\n        public Builder setAutoStartWhenCreate(boolean autoStartWhenCreate) {\n            target.AUTO_START_WHEN_CREATE = autoStartWhenCreate;\n            return this;\n        }\n\n        public Builder setUseSonicCacheInBadNetworkToastMessage(String toastMessage) {\n            target.USE_SONIC_CACHE_IN_BAD_NETWORK_TOAST = toastMessage;\n            return this;\n        }\n\n        public Builder setSessionMode(int sessionMode) {\n            target.sessionMode = sessionMode;\n            return this;\n        }\n\n        public Builder setCacheInterceptor(SonicCacheInterceptor interceptor) {\n            target.cacheInterceptor = interceptor;\n            return this;\n        }\n\n        public Builder setConnectionInterceptor(SonicSessionConnectionInterceptor interceptor) {\n            target.connectionInterceptor = interceptor;\n            return this;\n        }\n\n        public Builder setCustomRequestHeaders(Map<String, String> customRequestHeaders) {\n            target.customRequestHeaders = customRequestHeaders;\n            return this;\n        }\n\n        public Builder setCustomResponseHeaders(Map<String, String> customResponseHeaders) {\n            target.customResponseHeaders = customResponseHeaders;\n            return this;\n        }\n\n        public Builder setSupportCacheControl(boolean supportCacheControl) {\n            target.SUPPORT_CACHE_CONTROL = supportCacheControl;\n            return this;\n        }\n\n        public Builder setSupportLocalServer(boolean enable) {\n            target.SUPPORT_LOCAL_SERVER = enable;\n            return this;\n        }\n\n\n        public SonicSessionConfig build() {\n            return target;\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionConnection.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Intent;\nimport android.os.Looper;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport java.io.BufferedInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.SocketTimeoutException;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.zip.GZIPInputStream;\n\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLSession;\n\n/**\n *\n * The abstract class <code>SonicSessionConnection</code> is the superclass\n * of all classes that represent a communications link between the\n * application and a URL. Instances of this class can be used both to\n * read from and to write to the resource referenced by the URL\n */\npublic abstract class SonicSessionConnection {\n\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicSessionConnection\";\n\n    /**\n     * HTTP header:sonic-etag-key. <br>\n     * This header represents that the \"eTag\" key can be modified by service.\n     */\n    public final static String CUSTOM_HEAD_FILED_SONIC_ETAG_KEY = \"sonic-etag-key\";\n\n    /**\n     * HTTP header:eTag. <br>\n     * This header represents SHA1 value of the whole website, including template and data.\n     */\n    public final static String CUSTOM_HEAD_FILED_ETAG = \"eTag\";\n\n    /**\n     * HTTP header:accept-diff. <br>\n     * This header represents that client accepts data incremental scene updates or not.\n     */\n    public final static String CUSTOM_HEAD_FILED_ACCEPT_DIFF = \"accept-diff\";\n\n    /**\n     * HTTP header:template_tag. <br>\n     * This header represents SHA1 value of the template file.\n     */\n    public final static String CUSTOM_HEAD_FILED_TEMPLATE_TAG = \"template-tag\";\n\n    /**\n     * HTTP header:template_change. <br>\n     * This header indicates whether the template file has changed or not.\n     */\n    public final static String CUSTOM_HEAD_FILED_TEMPLATE_CHANGE = \"template-change\";\n\n    /**\n     * HTTP header:cache-offline. <br>\n     * This header indicates whether the website needs to be refreshed or not.\n     */\n    public final static String CUSTOM_HEAD_FILED_CACHE_OFFLINE = \"cache-offline\";\n\n    /**\n     * HTTP header:dns-prefetch-address <br>\n     * This header represents the ip address of the server. <br>\n     * Sonic Connection will use this ip to connect to server to avoid the cost time of DNS resolution.\n     */\n    public final static String DNS_PREFETCH_ADDRESS = \"dns-prefetch-address\";\n\n    /**\n     * HTTP Header:sdk_version. <br>\n     * This header represents the version of SDK.\n     */\n    public final static String CUSTOM_HEAD_FILED_SDK_VERSION = \"sonic-sdk-version\";\n\n    /**\n     * HTTP Header:dns-prefetch. <br>\n     * This header indicates that Sonic connection has used the ip represented by {@link #DNS_PREFETCH_ADDRESS}\n     */\n    public final static String CUSTOM_HEAD_FILED_DNS_PREFETCH = \"sonic-dns-prefetch\";\n\n    /**\n     * HTTP header: . <br>\n     *\n     */\n    public final static String CUSTOM_HEAD_FILED_HTML_SHA1 = \"sonic-html-sha1\";\n\n    /**\n     * HTTP Header：Content-Security-Policy. <br>\n     * This header represents the HTML CSP.\n     */\n    public final static String HTTP_HEAD_CSP = \"Content-Security-Policy\";\n\n    /**\n     * HTTP Header：Content-Security-Policy-Report-Only. <br>\n     * This header represents the HTML Content-Security-Policy-Report-Only.\n     */\n    public final static String HTTP_HEAD_CSP_REPORT_ONLY = \"Content-Security-Policy-Report-Only\";\n\n    /**\n     * HTTP Header：Set-Cookie. <br>\n     * This header represents the HTML Set-Cookie.\n     */\n    public final static String HTTP_HEAD_FILED_SET_COOKIE = \"Set-Cookie\";\n\n    /**\n     * HTTP Header : Cache-Control. <br>\n     * This header represents the strategy of cache control.\n     */\n    public final static String HTTP_HEAD_FIELD_CACHE_CONTROL = \"Cache-Control\";\n\n    /**\n     * HTTP Header : Expires. <br>\n     */\n    public final static String HTTP_HEAD_FIELD_EXPIRES = \"Expires\";\n\n    /**\n     * HTTP 1.0 Header : Pragma. <br>\n     * This old header represents the old strategy of cache control.\n     */\n    public final static String HTTP_HEAD_FIELD_PRAGMA = \"Pragma\";    //1.0\n\n    /**\n     * HTTP Header : Content-Type. <br>\n     */\n    public final static String HTTP_HEAD_FIELD_CONTENT_TYPE = \"Content-Type\";\n\n    /**\n     * HTTP Header : Content-Length. <br>\n     */\n    public final static String HTTP_HEAD_FIELD_CONTENT_LENGTH = \"Content-Length\";\n\n    /**\n     * HTTP Request Header : Cookie. <br>\n     */\n    public final static String HTTP_HEAD_FIELD_COOKIE = \"Cookie\";\n\n    /**\n     * HTTP Request Header：User-Agent. <br>\n     */\n    public final static String HTTP_HEAD_FILED_USER_AGENT = \"User-Agent\";\n\n    public final static String HTTP_HEAD_FILED_IF_NOT_MATCH = \"If-None-Match\";\n\n    /**\n     * HTTP Response Header: Link. <br>\n     */\n    public final static String CUSTOM_HEAD_FILED_LINK = \"sonic-link\";\n\n    /**\n     * SonicSession Object used by SonicSessionConnection.\n     */\n    protected final SonicSession session;\n\n    /**\n     * This intent saves all of the initialization param.\n     */\n    protected final Intent intent;\n\n    /**\n     * The input stream that reads from this open connection.\n     */\n    protected BufferedInputStream responseStream;\n\n    /**\n     * The field that reads from the headerFields of this open connection.\n     */\n    protected String mCustomHeadFieldEtagKey;\n\n    /**\n     * Constructor\n     * @param session The SonicSession instance\n     * @param intent The intent\n     */\n    public SonicSessionConnection(SonicSession session, Intent intent) {\n        this.session = session;\n        this.intent = intent != null ? intent : new Intent();\n    }\n\n    /**\n     *\n     * Opens a communications link to the resource referenced by Sonic session\n     *\n     * @return Returns the response code of connection\n     */\n    public synchronized int connect() {\n        return internalConnect();\n    }\n\n\n    /**\n     * Disconnect the communications link to the resource referenced by Sonic session\n     */\n    public abstract void disconnect();\n\n\n    public abstract int getResponseCode();\n\n    public abstract Map<String, List<String>> getResponseHeaderFields();\n\n    /**\n     *\n     * @param key  the name of a header field.\n     * @return Returns the value of the named header field.\n     */\n    public abstract String getResponseHeaderField(String key);\n\n    /**\n     *\n     * @return Returns an input stream that reads from this open connection.\n     */\n    public synchronized BufferedInputStream getResponseStream() {\n        if (responseStream == null) {\n            responseStream = internalGetResponseStream();\n        }\n\n        return responseStream;\n    }\n\n    protected abstract int internalConnect();\n\n    protected abstract BufferedInputStream internalGetResponseStream();\n\n    public String getCustomHeadFieldEtagKey() {\n        if (TextUtils.isEmpty(mCustomHeadFieldEtagKey)) {\n            mCustomHeadFieldEtagKey = internalGetCustomHeadFieldEtag();\n        }\n        return mCustomHeadFieldEtagKey;\n    }\n\n    protected abstract String internalGetCustomHeadFieldEtag();\n\n\n    public static class SessionConnectionDefaultImpl extends SonicSessionConnection {\n\n        /**\n         *  A default http connection referred to by the {@code com.tencent.sonic.sdk.SonicSession#currUrl}.\n         */\n        protected final URLConnection connectionImpl;\n\n\n\n        public SessionConnectionDefaultImpl(SonicSession session, Intent intent) {\n            super(session, intent);\n            connectionImpl = createConnection();\n            initConnection(connectionImpl);\n        }\n\n        protected URLConnection createConnection() {\n\n            String currentUrl = session.srcUrl;\n\n            if (TextUtils.isEmpty(currentUrl)) {\n                return null;\n            }\n\n            URLConnection connection = null;\n            try {\n                URL url = new URL(currentUrl);\n                String dnsPrefetchAddress = intent.getStringExtra(SonicSessionConnection.DNS_PREFETCH_ADDRESS);\n                String originHost = null;\n                /*\n                 * Use the ip value mapped by {@code SonicSessionConnection.DNS_PREFETCH_ADDRESS} to avoid the cost time of DNS resolution.\n                 * Meanwhile it can reduce the risk from hijacking http session.\n                 */\n                if (!TextUtils.isEmpty(dnsPrefetchAddress)) {\n                    originHost = url.getHost();\n                    url = new URL(currentUrl.replace(originHost, dnsPrefetchAddress));\n                    SonicUtils.log(TAG, Log.INFO, \"create UrlConnection with DNS-Prefetch(\" + originHost + \" -> \" + dnsPrefetchAddress + \").\");\n                }\n                connection = url.openConnection();\n                if (connection != null) {\n                    if (connection instanceof HttpURLConnection) {\n                        ((HttpURLConnection) connection).setInstanceFollowRedirects(false);\n                    }\n\n                    if (!TextUtils.isEmpty(originHost)) {\n                        /*\n                         * If originHost is not empty, that means connection uses the ip value instead of http host.\n                         * So http header need to set the Host and {@link com.tencent.sonic.sdk.SonicSessionConnection.CUSTOM_HEAD_FILED_DNS_PREFETCH} request property.\n                         */\n                        connection.setRequestProperty(\"Host\", originHost);\n\n                        connection.setRequestProperty(SonicSessionConnection.CUSTOM_HEAD_FILED_DNS_PREFETCH, url.getHost());\n                        if (connection instanceof HttpsURLConnection) { // 如果属于https，需要特殊处理，比如支持sni\n                            /*\n                             * If the scheme of url is https, then it needs extra processing, such as the sni support.\n                             */\n                            final String finalOriginHost = originHost;\n                            final URL finalUrl = url;\n                            HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;\n                            httpsConnection.setSSLSocketFactory(new SonicSniSSLSocketFactory(SonicEngine.getInstance().getRuntime().getContext(), originHost));\n                            httpsConnection.setHostnameVerifier(new HostnameVerifier() {\n                                @Override\n                                public boolean verify(String hostname, SSLSession session) {\n                                    boolean verifySuccess = false;\n                                    long startTime = System.currentTimeMillis();\n                                    if (finalUrl.getHost().equals(hostname)) {\n                                        verifySuccess = HttpsURLConnection.getDefaultHostnameVerifier().verify(finalOriginHost, session);\n                                        SonicUtils.log(TAG, Log.DEBUG, \"verify hostname cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n                                    }\n                                    return verifySuccess;\n                                }\n                            });\n                        }\n                    }\n                }\n            } catch (Throwable e) {\n                if (connection != null) {\n                    connection = null;\n                }\n                SonicUtils.log(TAG, Log.ERROR, \"create UrlConnection fail, error:\" + e.getMessage() + \".\");\n            }\n            return connection;\n        }\n\n        protected boolean initConnection(URLConnection connection) {\n            if (null != connection) {\n                SonicSessionConfig config = session.config;\n                connection.setConnectTimeout(config.CONNECT_TIMEOUT_MILLIS);\n                connection.setReadTimeout(config.READ_TIMEOUT_MILLIS);\n                /*\n                 *  {@link SonicSessionConnection#CUSTOM_HEAD_FILED_ACCEPT_DIFF} is need to be set If client accepts incrementally updates. <br>\n                 *  <p><b>Note: It doesn't support incrementally updated for template file.</b><p/>\n                 */\n                connection.setRequestProperty(CUSTOM_HEAD_FILED_ACCEPT_DIFF, config.ACCEPT_DIFF_DATA ? \"true\" : \"false\");\n\n//                String eTag = intent.getStringExtra(getCustomHeadFieldEtagKey());\n                String eTag = intent.getStringExtra(!TextUtils.isEmpty(mCustomHeadFieldEtagKey) ? mCustomHeadFieldEtagKey : CUSTOM_HEAD_FILED_ETAG);\n                if (null == eTag) eTag = \"\";\n                connection.setRequestProperty(HTTP_HEAD_FILED_IF_NOT_MATCH, eTag);\n\n                String templateTag = intent.getStringExtra(CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n                if (null == templateTag) templateTag = \"\";\n                connection.setRequestProperty(CUSTOM_HEAD_FILED_TEMPLATE_TAG, templateTag);\n\n                connection.setRequestProperty(\"method\", \"GET\");\n                connection.setRequestProperty(\"Accept-Encoding\", \"gzip\");\n                connection.setRequestProperty(\"Accept-Language\", \"zh-CN,zh;\");\n                connection.setRequestProperty(CUSTOM_HEAD_FILED_SDK_VERSION, \"Sonic/\" + SonicConstants.SONIC_VERSION_NUM);\n\n                // set custom request headers\n                if (null != config.customRequestHeaders && 0 != config.customRequestHeaders.size()) {\n                    for (Map.Entry<String, String> entry : config.customRequestHeaders.entrySet()) {\n                        connection.setRequestProperty(entry.getKey(), entry.getValue());\n                    }\n                }\n\n                String cookie = intent.getStringExtra(HTTP_HEAD_FIELD_COOKIE);\n                if (!TextUtils.isEmpty(cookie)) {\n                    connection.setRequestProperty(HTTP_HEAD_FIELD_COOKIE, cookie);\n                } else {\n                    SonicUtils.log(TAG, Log.ERROR, \"create UrlConnection cookie is empty\");\n                }\n\n                connection.setRequestProperty(HTTP_HEAD_FILED_USER_AGENT, intent.getStringExtra(HTTP_HEAD_FILED_USER_AGENT));\n\n                return true;\n            }\n            return false;\n        }\n\n        @Override\n        protected synchronized int internalConnect() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                HttpURLConnection httpURLConnection = (HttpURLConnection) connectionImpl;\n                try {\n                    httpURLConnection.connect();\n                    return SonicConstants.ERROR_CODE_SUCCESS;\n                } catch (Throwable e) {\n                    String errMsg = e.getMessage();\n                    SonicUtils.log(TAG, Log.ERROR, \"connect error:\" + errMsg);\n\n                    if (e instanceof IOException) {\n                        if (e instanceof SocketTimeoutException) {\n                            return SonicConstants.ERROR_CODE_CONNECT_TOE;\n                        }\n\n                        if (!TextUtils.isEmpty(errMsg) && errMsg.contains(\"timeoutexception\")) {\n                            return SonicConstants.ERROR_CODE_CONNECT_TOE;\n                        }\n                        return SonicConstants.ERROR_CODE_CONNECT_IOE;\n                    }\n\n                    if (e instanceof NullPointerException) {\n                        return SonicConstants.ERROR_CODE_CONNECT_NPE;\n                    }\n                }\n            }\n            return SonicConstants.ERROR_CODE_UNKNOWN;\n        }\n\n        @Override\n        public void disconnect() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                final HttpURLConnection httpURLConnection = (HttpURLConnection) connectionImpl;\n                if (Looper.myLooper() == Looper.getMainLooper()) {\n                    SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            try {\n                                httpURLConnection.disconnect();\n                            } catch (Throwable e) {\n                                SonicUtils.log(TAG, Log.ERROR, \"disconnect error:\" + e.getMessage());\n                            }\n                        }\n                    }, 0);\n                } else {\n                    try {\n                        httpURLConnection.disconnect();\n                    } catch (Exception e) {\n                        SonicUtils.log(TAG, Log.ERROR, \"disconnect error:\" + e.getMessage());\n                    }\n                }\n            }\n        }\n\n        @Override\n        protected BufferedInputStream internalGetResponseStream() {\n            if (null == responseStream && null != connectionImpl) {\n                try {\n                    InputStream inputStream = connectionImpl.getInputStream();\n                    if (\"gzip\".equalsIgnoreCase(connectionImpl.getContentEncoding())) {\n                        responseStream = new BufferedInputStream(new GZIPInputStream(inputStream));\n                    } else {\n                        responseStream = new BufferedInputStream(inputStream);\n                    }\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"getResponseStream error:\" + e.getMessage() + \".\");\n                }\n            }\n            return responseStream;\n        }\n\n        @Override\n        public int getResponseCode() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                try {\n                    return ((HttpURLConnection) connectionImpl).getResponseCode();\n                } catch (Throwable e) {\n                    String errMsg = e.getMessage();\n                    SonicUtils.log(TAG, Log.ERROR, \"getResponseCode error:\" + errMsg);\n\n                    if (e instanceof IOException) {\n                        if (e instanceof SocketTimeoutException) {\n                            return SonicConstants.ERROR_CODE_CONNECT_TOE;\n                        }\n\n\n                        if (!TextUtils.isEmpty(errMsg) && errMsg.contains(\"timeoutexception\")) {\n                            return SonicConstants.ERROR_CODE_CONNECT_TOE;\n                        }\n\n                        return SonicConstants.ERROR_CODE_CONNECT_IOE;\n                    }\n\n                    if (e instanceof NullPointerException) {\n                        return SonicConstants.ERROR_CODE_CONNECT_NPE;\n                    }\n                }\n            }\n            return SonicConstants.ERROR_CODE_UNKNOWN;\n        }\n\n        @Override\n        public Map<String, List<String>> getResponseHeaderFields() {\n            if (null == connectionImpl) {\n                return null;\n            }\n\n            try {\n                return connectionImpl.getHeaderFields();\n            } catch (Throwable e) {\n                SonicUtils.log(TAG, Log.ERROR, \"getHeaderFields error:\" + e.getMessage());\n                return new HashMap<String, List<String>>();\n            }\n        }\n\n        @Override\n        public String getResponseHeaderField(String key) {\n            Map<String, List<String>> responseHeaderFields = getResponseHeaderFields();\n            if (null != responseHeaderFields && 0 != responseHeaderFields.size()) {\n                List<String> responseHeaderValues = responseHeaderFields.get(key.toLowerCase());\n                if (null != responseHeaderValues && 0 != responseHeaderValues.size()) {\n                    StringBuilder stringBuilder = new StringBuilder(responseHeaderValues.get(0));\n                    for (int index = 1, size = responseHeaderValues.size(); index < size; ++index) {\n                        stringBuilder.append(',');\n                        stringBuilder.append(responseHeaderValues.get(index));\n                    }\n                    return stringBuilder.toString();\n                }\n            }\n            return null;\n        }\n\n        @Override\n        protected String internalGetCustomHeadFieldEtag() {\n            String sonicEtagValue = getResponseHeaderField(CUSTOM_HEAD_FILED_SONIC_ETAG_KEY);\n            SonicUtils.log(TAG, Log.INFO, \"internalGetCustomHeadFieldEtag ~ sonicEtag:\" + sonicEtagValue);\n            return !TextUtils.isEmpty(sonicEtagValue) ? sonicEtagValue : CUSTOM_HEAD_FILED_ETAG;\n        }\n    }\n}"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionConnectionInterceptor.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Intent;\n\n/**\n * <code>SonicSessionConnectionInterceptor</code> provide a <code>SonicSessionConnection</code>.\n * If an {@link SonicSessionConfig}does not set <code>SonicSessionConnectionInterceptor</code>\n * sonic will use {@link com.tencent.sonic.sdk.SonicSessionConnection.SessionConnectionDefaultImpl}\n * as default.\n *\n */\npublic abstract class SonicSessionConnectionInterceptor {\n\n    public abstract SonicSessionConnection getConnection(SonicSession session, Intent intent);\n\n    public static SonicSessionConnection getSonicSessionConnection(SonicSession session, Intent intent) {\n        SonicSessionConnectionInterceptor interceptor = session.config.connectionInterceptor;\n        if (interceptor != null) {\n            return interceptor.getConnection(session, intent);\n        }\n        return new SonicSessionConnection.SessionConnectionDefaultImpl(session, intent);\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionStatistics.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport java.net.HttpURLConnection;\n\n\n/**\n * The Statistic model specifies the data models which are required to be used to provide\n * the performance data described by the specific attributes in a SonicSession.\n */\npublic class SonicSessionStatistics {\n    \n    /**\n     * Original url\n     */\n    public String srcUrl;\n\n    /**\n     * Sonic final mode{@link SonicSession#finalResultCode}\n     */\n    public int finalMode;\n\n    /**\n     * Sonic original mode{@link SonicSession#srcResultCode}\n     */\n    public int originalMode;\n\n    /**\n     * Sonic start {@link SonicSession#start()} time\n     */\n    public long sonicStartTime;\n\n    /**\n     * Sonic flow start{@link SonicSession#runSonicFlow(boolean)} time\n     */\n    public long sonicFlowStartTime;\n\n    /**\n     * The time that sonic begin verify local data\n     */\n    public long cacheVerifyTime;\n\n    /**\n     * The time sonic initiate the http(s) request\n     */\n    public long connectionFlowStartTime;\n\n    /**\n     * The http(s) connect{@link HttpURLConnection#connect()} response time\n     */\n    public long connectionConnectTime;\n\n    /**\n     * The http(s) getResponseCode{@link HttpURLConnection#getResponseCode()} response time\n     */\n    public long connectionRespondTime;\n\n    /**\n     * Sonic flow end time\n     */\n    public long connectionFlowFinishTime;\n\n    /**\n     * Is IP direct\n     */\n    public boolean isDirectAddress;\n\n\n    /**\n     * The time when website try get diff data.\n     */\n    public long diffDataCallbackTime;\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionStream.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.support.annotation.NonNull;\nimport android.util.Log;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.ref.WeakReference;\n\n/**\n *\n * A <code>SonicSessionStream</code> obtains input bytes\n * from a <code>memStream</code> and a <code>netStream</code>.\n * <code>memStream</code>is read data from network, <code>netStream</code>is unread data from network.\n *\n */\npublic class SonicSessionStream extends InputStream {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicSessionStream\";\n\n    /**\n     * Unread data from network\n     */\n    private BufferedInputStream netStream;\n\n    /**\n     * Read data from network\n     */\n    private BufferedInputStream memStream;\n\n    /**\n     * OutputStream include <code>memStream</code> data and <code>netStream</code> data\n     */\n    private ByteArrayOutputStream outputStream;\n\n    /**\n     * <code>netStream</code> data completed flag\n     */\n    private boolean netStreamReadComplete = true;\n\n    /**\n     * <code>memStream</code> data completed flag\n     */\n    private boolean memStreamReadComplete = true;\n\n    /**\n     * When <code>SonicSessionStream</code> close the stream will invoke the <code>Callback</code>\n     */\n    public interface Callback {\n        /**\n         * Close callback\n         *\n         * @param readComplete <code>SonicSessionStream</code> data has read completed\n         * @param outputStream outputStream include <code>memStream</code> data and <code>netStream</code> data\n         */\n        void onClose(boolean readComplete, ByteArrayOutputStream outputStream);\n    }\n\n    /**\n     * Callback WeakReference\n     */\n    private final WeakReference<Callback> callbackWeakReference;\n\n    /**\n     * Constructor\n     *\n     * @param callback     Callback\n     * @param outputStream Read data from network\n     * @param netStream    Unread data from network\n     */\n    public SonicSessionStream(Callback callback, ByteArrayOutputStream outputStream, BufferedInputStream netStream) {\n        if (null != netStream) {\n            this.netStream = netStream;\n            this.netStreamReadComplete = false;\n        }\n\n        if (outputStream != null) {\n            this.outputStream = outputStream;\n            this.memStream = new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray()));\n            this.memStreamReadComplete = false;\n        } else {\n            this.outputStream = new ByteArrayOutputStream();\n        }\n\n        callbackWeakReference = new WeakReference<Callback>(callback);\n    }\n\n    /**\n     * Closes this input stream and releases any system resources\n     * associated with the stream and invoke the callback's onClose method\n     *\n     */\n    @Override\n    public void close() throws IOException {\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"close: memory stream and socket stream, netStreamReadComplete=\" + netStreamReadComplete + \", memStreamReadComplete=\" + memStreamReadComplete);\n        }\n\n        Throwable error = null;\n        try {\n            if (null != memStream) {\n                memStream.close();\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"close memStream error:\" + e.getMessage());\n            error = e;\n        } finally {\n            memStream = null;\n        }\n\n        try {\n            if (null != netStream) {\n                netStream.close();\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"close netStream error:\" + e.getMessage());\n            error = e;\n        } finally {\n            netStream = null;\n        }\n\n        Callback callback = callbackWeakReference.get();\n        if (null != callback) {\n            callback.onClose(netStreamReadComplete && memStreamReadComplete, outputStream);\n        }\n        outputStream = null;\n\n        if (error != null) {\n            SonicUtils.log(TAG, Log.ERROR, \"throw error:\" + error.getMessage());\n            if (error instanceof IOException) {\n                throw (IOException)error;\n            } else { // Turn all exceptions to IO exceptions to prevent scenes that the kernel can not capture\n                throw new IOException(error);\n            }\n        }\n    }\n\n    /**\n     *\n     * <p>\n     * Reads a single byte from this stream and returns it as an integer in the\n     * range from 0 to 255. Returns -1 if the end of the stream has been\n     * reached. Blocks until one byte has been read, the end of the source\n     * stream is detected or an exception is thrown.\n     *\n     * @throws IOException if the stream is closed or another IOException occurs.\n     */\n    @Override\n    public synchronized int read() throws IOException {\n\n        int c = -1;\n\n        try {\n            if (null != memStream && !memStreamReadComplete) {\n                c = memStream.read();\n            }\n\n            if (-1 == c) {\n                memStreamReadComplete = true;\n                if (null != netStream && !netStreamReadComplete) {\n                    c = netStream.read();\n                    if (-1 != c) {\n                        outputStream.write(c);\n                    } else {\n                        netStreamReadComplete = true;\n                    }\n                }\n            }\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"read error:\" + e.getMessage());\n            if (e instanceof IOException) {\n                throw e;\n            } else {//Turn all exceptions to IO exceptions to prevent scenes that the kernel can not capture\n                throw new IOException(e);\n            }\n        }\n\n        return c;\n    }\n\n    /**\n     * Reads a byte of data from this input stream\n     * Equivalent to {@code read(buffer, 0, buffer.length)}.\n     */\n    @Override\n    public synchronized int read(@NonNull byte[] buffer) throws IOException {\n        return read(buffer, 0, buffer.length);\n    }\n\n    /**\n     *\n     * Reads up to {@code byteCount} bytes from this stream and stores them in\n     * the byte array {@code buffer} starting at {@code byteOffset}.\n     * Returns the number of bytes actually read or -1 if the end of the stream\n     * has been reached.\n     *\n     * @throws IndexOutOfBoundsException if {@code byteOffset < 0 || byteCount < 0 || byteOffset + byteCount > buffer.length}.\n     * @throws IOException               if the stream is closed or another IOException occurs.\n     */\n    public synchronized int read(@NonNull byte[] buffer, int byteOffset, int byteCount) throws IOException {\n        int arrayLength = buffer.length;\n        if ((byteOffset | byteCount) < 0 || byteOffset > arrayLength || arrayLength - byteOffset < byteCount) {\n            throw new ArrayIndexOutOfBoundsException();\n        }\n\n        for (int i = 0; i < byteCount; ++i) {\n            int c;\n            try {\n                if ((c = read()) == -1) {\n                    return i == 0 ? -1 : i;\n                }\n            } catch (IOException e) {\n                if (i != 0) {\n                    return i;\n                }\n                throw e;\n            }\n            buffer[byteOffset + i] = (byte) c;\n        }\n        return byteCount;\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSessionThreadPool.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.support.annotation.NonNull;\nimport android.util.Log;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.SynchronousQueue;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * SonicSession ThreadPool\n */\n\nclass SonicSessionThreadPool {\n\n    /**\n     * Log filter\n     */\n    private final static String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicSessionThreadPool\";\n\n    /**\n     * Singleton object\n     */\n    private final static SonicSessionThreadPool sInstance = new SonicSessionThreadPool();\n\n    /**\n     * ExecutorService object (Executors.newCachedThreadPool())\n     */\n    private final ExecutorService executorServiceImpl;\n\n    /**\n     * SonicSession ThreadFactory\n     */\n    private static class SessionThreadFactory implements ThreadFactory {\n\n        /**\n         * Thread group\n         */\n        private final ThreadGroup group;\n\n        /**\n         * Thread number\n         */\n        private final AtomicInteger threadNumber = new AtomicInteger(1);\n\n        /**\n         * Thread prefix name\n         */\n        private final static String NAME_PREFIX = \"pool-sonic-session-thread-\";\n\n        /**\n         * Constructor\n         */\n        SessionThreadFactory() {\n            SecurityManager securityManager = System.getSecurityManager();\n            this.group = securityManager != null ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();\n        }\n\n        /**\n         * Constructs a new {@code Thread}.  Implementations may also initialize\n         * priority, name, daemon status, {@code ThreadGroup}, etc.\n         *\n         * @param r A runnable to be executed by new thread instance\n         * @return Constructed thread, or {@code null} if the request to\n         * create a thread is rejected\n         */\n        public Thread newThread(@NonNull Runnable r) {\n            Thread thread = new Thread(this.group, r, NAME_PREFIX + this.threadNumber.getAndIncrement(), 0L);\n            if (thread.isDaemon()) {\n                thread.setDaemon(false);\n            }\n\n            if (thread.getPriority() != 5) {\n                thread.setPriority(5);\n            }\n\n            return thread;\n        }\n    }\n\n    /**\n     * Constructor and initialize thread pool object\n     * default one core pool and the maximum number of threads is 6\n     *\n     */\n    private SonicSessionThreadPool() {\n        executorServiceImpl = new ThreadPoolExecutor(1, 6,\n                60L, TimeUnit.SECONDS,\n                new SynchronousQueue<Runnable>(),\n                new SessionThreadFactory());\n    }\n\n    /**\n     * Executes the given command at some time in the future.  The command\n     * may execute in a new thread, in a pooled thread, or in the calling\n     * thread, at the discretion of the {@code Executor} implementation.\n     *\n     * @param task The runnable task\n     * @return Submit success or not\n     */\n    private boolean execute(Runnable task) {\n        try {\n            executorServiceImpl.execute(task);\n            return true;\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"execute task error:\" + e.getMessage());\n            return false;\n        }\n    }\n\n    /**\n     * Post an runnable to the pool thread\n     *\n     * @param task The runnable task\n     * @return Submit success or not\n     */\n\n    static boolean postTask(Runnable task) {\n        return sInstance.execute(task);\n    }\n\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSniSSLSocketFactory.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.content.Context;\nimport android.net.SSLCertificateSocketFactory;\nimport android.net.SSLSessionCache;\nimport android.util.Log;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.InetSocketAddress;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLException;\nimport javax.net.ssl.SSLPeerUnverifiedException;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\n\n/**\n *\n * Implement IP direct support for SNI type in https scenarios\n * main method{ public Socket createSocket(Socket s, String host, int port, boolean autoClose)}\n *\n */\n\nclass SonicSniSSLSocketFactory extends SSLSocketFactory {\n\n    /**\n     * Log filter\n     */\n    private final static String TAG = SonicConstants.SONIC_PARAMETER_NAME_PREFIX + \"SonicSniSSLSocketFactory\";\n\n    /**\n     * Host name，use to certificate validation\n     */\n    private final String targetHostName;\n\n    /**\n     * SSLSocketFactory implementation class\n     */\n    private final SSLCertificateSocketFactory sslSocketFactory;\n\n    SonicSniSSLSocketFactory(Context context, String targetHostName) {\n        super();\n        this.targetHostName = targetHostName;\n        this.sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0, new SSLSessionCache(context));\n    }\n\n    /**\n     * Returns the names of the cipher suites that are enabled by default.\n     *\n     * @return The names of the cipher suites that are enabled by default.\n     */\n    @Override\n    public String[] getDefaultCipherSuites() {\n        return sslSocketFactory.getDefaultCipherSuites();\n    }\n\n    /**\n     * Returns the names of the cipher suites that are supported and could be\n     * enabled for an SSL connection.\n     *\n     * @return The names of the cipher suites that are supported.\n     */\n    @Override\n    public String[] getSupportedCipherSuites() {\n        return sslSocketFactory.getDefaultCipherSuites();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>This method verifies the peer's certificate hostname after connecting\n     */\n    @Override\n    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {\n        // The socket connection is completed, you need to upgrade the TLS layer, so the host will be replaced by a real domain name.\n        return sslSocketFactory.createSocket(s, targetHostName, port, autoClose);\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>This method verifies the peer's certificate hostname after connecting\n     */\n    @Override\n    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {\n        Socket socket = createSocket();\n        socket.connect(new InetSocketAddress(host, port));\n        verifyHostname(socket, targetHostName);\n        return socket;\n    }\n\n    /**\n     * Creates a new socket which is not connected to any remote host.\n     * You must use {@link Socket#connect} to connect the socket.\n     *\n     * <p class=\"caution\"><b>Warning:</b> Hostname verification is not performed\n     * with this method.  You MUST verify the server's identity after connecting\n     * the socket to avoid man-in-the-middle attacks.</p>\n     */\n    @Override\n    public Socket createSocket() throws IOException {\n        return sslSocketFactory.createSocket();\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p>This method verifies the peer's certificate hostname after connecting\n     */\n    @Override\n    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {\n        Socket socket = createSocket();\n        socket.bind(new InetSocketAddress(localHost, localPort));\n        socket.connect(new InetSocketAddress(host, port));\n        verifyHostname(socket, targetHostName);\n        return socket;\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * <p class=\"caution\"><b>Warning:</b> Hostname verification is not performed\n     * with this method.  You MUST verify the server's identity after connecting\n     * the socket to avoid man-in-the-middle attacks.</p>\n     */\n    @Override\n    public Socket createSocket(InetAddress host, int port) throws IOException {\n        return sslSocketFactory.createSocket(host, port);\n    }\n    /**\n     * {@inheritDoc}\n     *\n     * <p class=\"caution\"><b>Warning:</b> Hostname verification is not performed\n     * with this method.  You MUST verify the server's identity after connecting\n     * the socket to avoid man-in-the-middle attacks.</p>\n     */\n    @Override\n    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {\n        return sslSocketFactory.createSocket(address, port, localAddress, localPort);\n    }\n\n    /**\n     * Verify the hostname of the certificate used by the other end of a\n     * connected socket.  You MUST call this if you did not supply a hostname\n     * to {@link #createSocket()}.  It is harmless to call this method\n     * redundantly if the hostname has already been verified.\n     *\n     * <p>Wildcard certificates are allowed to verify any matching hostname,\n     * so \"foo.bar.example.com\" is verified if the peer has a certificate\n     * for \"*.example.com\".\n     *\n     * @param socket An SSL socket which has been connected to a server\n     * @param hostname The expected hostname of the remote server\n     * @throws IOException if something goes wrong handshaking with the server\n     * @throws SSLPeerUnverifiedException if the server cannot prove its identity\n     *\n     */\n    public static void verifyHostname(Socket socket, String hostname) throws IOException {\n        if (!(socket instanceof SSLSocket)) {\n            throw new IllegalArgumentException(\"Attempt to verify non-SSL socket\");\n        }\n\n        // The code at the start of OpenSSLSocketImpl.startHandshake()\n        // ensures that the call is idempotent, so we can safely call it.\n        SSLSocket ssl = (SSLSocket) socket;\n        ssl.startHandshake();\n\n        SSLSession session = ssl.getSession();\n        if (session == null) {\n            throw new SSLException(\"Cannot verify SSL socket without session\");\n        }\n\n        if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) {\n            SonicUtils.log(TAG, Log.ERROR, \"sonic SSL error:Cannot verify hostname\" + hostname + \")!\");\n            throw new SSLPeerUnverifiedException(\"Cannot verify hostname: \" + hostname);\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicUtils.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.annotation.TargetApi;\nimport android.content.SharedPreferences;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport org.json.JSONObject;\n\nimport java.io.File;\nimport java.nio.charset.Charset;\nimport java.security.MessageDigest;\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.TimeZone;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Sonic Utils\n */\npublic class SonicUtils {\n\n    /**\n     * the default charset is UTF-8.\n     */\n    public static final String DEFAULT_CHARSET = Charset.defaultCharset().name();\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicUtils\";\n\n    /**\n     * Sonic template tag :the beginning of title label\n     * title is considered part of the data in sonic\n     */\n    private static final String SONIC_TAG_TITLE_OPEN = \"<title>\";\n\n    /**\n     * Sonic template tag :the end of title label\n     */\n    private static final String SONIC_TAG_TITLE_CLOSE = \"</title>\";\n\n    /**\n     * Sonic template tag:\n     */\n    private static final String SONIC_TAG_TITLE_KEY = \"{title}\";\n\n    /**\n     * Sonic pattern : through the pattern sonic splits the html to template and data\n     */\n    private static final String SONIC_TAG_PATTERN = \"<!--sonicdiff-?(\\\\w*)-->([\\\\s\\\\S]+?)<!--sonicdiff-?(\\\\w*)-end-->\";\n\n    /**\n     * The beginning of sonic pattern\n     */\n    private static final String SONIC_TAG_DIFF_BEGIN = \"<!--sonicdiff-\";\n\n    /**\n     * the end of sonic pattern\n     */\n    private static final String SONIC_TAG_DIFF_END = \"-->\";\n\n    /**\n     * The beginning of data key\n     */\n    private static final String SONIC_TAG_KEY_BEGIN = \"{\";\n\n    /**\n     * the end of data key\n     */\n    private static final String SONIC_TAG_KEY_END = \"}\";\n\n    /**\n     * the key of last cache check and clear time saved in SharedPreference\n     */\n    private static final String SONIC_CLEAR_CACHE_TIME = \"check_and_clear_cache_time\";\n\n    /**\n     * Logger function\n     *\n     * @param level Level of this log，such like Log.DEBUG.\n     * @return Should log or not\n     */\n    public static boolean shouldLog(int level) {\n        return SonicEngine.getInstance().getRuntime().shouldLog(level);\n    }\n\n    /**\n     * Logger function\n     *\n     * @param tag Used to identify the source of a log message.  It usually identifies\n     *        the class or activity where the log call occurs.\n     * @param level Level of this log，such like Log.DEBUG.\n     * @param message The message you would like logged.\n     */\n    public static void log(String tag, int level, String message) {\n        SonicEngine.getInstance().getRuntime().log(tag, level, message);\n    }\n\n    /**\n     * Save sonic data to SharedPreferences, such as the eTag, template tag and so on\n     *\n     * @param sessionId   A unique session id\n     * @param eTag        Html eTag\n     * @param templateTag Template tag\n     * @param htmlSha1    Html sha1\n     * @param htmlSize    Html size\n     */\n    @TargetApi(Build.VERSION_CODES.GINGERBREAD)\n    static void saveSonicData(String sessionId, String eTag, String templateTag, String htmlSha1,\n                              long htmlSize, Map<String, List<String>> headers) {\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"saveSonicData sessionId = \" + sessionId + \", eTag = \" + eTag + \", templateTag = \" + templateTag + \",htmlSha1 = \" + htmlSha1 + \", htmlSize = \" + htmlSize );\n        }\n        SonicDataHelper.SessionData sessionData = new SonicDataHelper.SessionData();\n        sessionData.sessionId = sessionId;\n        handleCacheControl(headers, sessionData);\n        sessionData.eTag = eTag;\n        sessionData.templateTag = templateTag;\n        sessionData.htmlSha1 = htmlSha1;\n        sessionData.htmlSize = htmlSize;\n        sessionData.templateUpdateTime = System.currentTimeMillis();\n        SonicDataHelper.saveSessionData(sessionId, sessionData);\n    }\n\n    /**\n     * Calculate the expired time of session cache depends on the response header Cache-Control.\n     * @param headers response headers\n     * @param sessionData session data\n     */\n    private static void handleCacheControl(Map<String, List<String>> headers, SonicDataHelper.SessionData sessionData) {\n        List<String> responseHeaderValues;\n        if (headers.containsKey(SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL.toLowerCase())) {\n            responseHeaderValues = headers.get(SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL.toLowerCase());\n            if (responseHeaderValues != null && responseHeaderValues.size() > 0) {\n                String header = responseHeaderValues.get(0).toLowerCase();\n                if (header.contains(\"max-age\")) {\n                    int index = header.indexOf(\"max-age\");\n                    String temp = header.substring(index);\n                    int endIndex = temp.indexOf(\",\");\n                    endIndex = endIndex == -1 ? temp.length() : endIndex;\n                    String maxAgeStr = temp.substring(8, endIndex);\n                    try {\n                        long maxAgeTime = Long.parseLong(maxAgeStr) * 1000;\n                        if (maxAgeTime != 0) {\n                            sessionData.expiredTime = maxAgeTime + System.currentTimeMillis();\n                        }\n                    } catch (Exception e) {\n                        log(TAG, Log.ERROR, \"handleCacheControl:sessionId(\" + sessionData.sessionId + \") error:\" + e.getMessage());\n                    }\n                } else if (header.contains(\"private\") || header.contains(\"public\")) {\n                    //max 5min\n                    sessionData.expiredTime = System.currentTimeMillis() + SonicEngine.getInstance().getConfig().SONIC_CACHE_MAX_AGE;\n                }\n            } else if (headers.containsKey(SonicSessionConnection.HTTP_HEAD_FIELD_EXPIRES)) {\n                responseHeaderValues = headers.get(SonicSessionConnection.HTTP_HEAD_FIELD_EXPIRES);\n                if (responseHeaderValues != null && responseHeaderValues.size() > 0) {\n                    String header = responseHeaderValues.get(0);\n                    DateFormat df = new SimpleDateFormat(\"EEE, dd MMM yyyy hh:mm:ss z\", Locale.US);\n                    df.setTimeZone(TimeZone.getTimeZone(\"GMT\"));\n                    try {\n                        Date date = df.parse(header);\n                        sessionData.expiredTime = date.getTime() + 8 * 60 * 60 * 1000;\n                    } catch (Exception e) {\n                        log(TAG, Log.ERROR, \"handleCacheControl:sessionId(\" + sessionData.sessionId + \") error:\" + e.getMessage());\n                    }\n                }\n            }\n\n            //The max age of sonic cache is {@link com.tencent.sonic.sdk.SonicConfig.SONIC_CACHE_MAX_AGE}\n            long maxAge = System.currentTimeMillis() + SonicEngine.getInstance().getConfig().SONIC_CACHE_MAX_AGE;\n            if (sessionData.expiredTime > maxAge) {\n                sessionData.expiredTime = maxAge;\n            }\n        }\n    }\n\n    /**\n     * save resource data to database, such as resource sha1, resource size etc.\n     *\n     * @param resourceUrl the resource url\n     * @param resourceSha1 the resource sha1\n     * @param resourceSize the resource size\n     */\n    public static void saveSonicResourceData(String resourceUrl, String resourceSha1, long resourceSize) {\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"saveSonicResourceData resourceUrl = \" + resourceUrl + \", resourceSha1 = \" + resourceSha1 + \", resourceSize = \" + resourceSize);\n        }\n        SonicResourceDataHelper.ResourceData resourceData = new SonicResourceDataHelper.ResourceData();\n        resourceData.resourceId = getMD5(resourceUrl);\n        resourceData.resourceSha1 = resourceSha1;\n        resourceData.resourceSize = resourceSize;\n        handleResourceExpireTime(resourceUrl, resourceData);\n        resourceData.lastUpdateTime = System.currentTimeMillis();\n        SonicResourceDataHelper.saveResourceData(resourceData.resourceId, resourceData);\n    }\n\n    /**\n     * parse the cache expired time from resource url parameters.\n     *\n     * @param resourceUrl the resource url\n     * @param resourceData the resource data\n     */\n    private static void handleResourceExpireTime(String resourceUrl, SonicResourceDataHelper.ResourceData resourceData) {\n        Uri uri = Uri.parse(resourceUrl);\n        String maxAgeStr = uri.getQueryParameter(\"max-age\");\n        if (TextUtils.isEmpty(maxAgeStr)) {\n            resourceData.expiredTime = Long.MAX_VALUE;\n        } else {\n            try {\n                long maxAgeTime = Long.parseLong(maxAgeStr) * 1000;\n                if (maxAgeTime != 0) {\n                    resourceData.expiredTime = maxAgeTime + System.currentTimeMillis();\n                }\n            } catch (Exception e) {\n                log(TAG, Log.ERROR, \"handleResourceExpireTime:resourceUrl(\" + resourceUrl + \") error:\" + e.getMessage());\n            }\n        }\n    }\n\n    /**\n     * Obtain the difference data between the server and the local data\n     *\n     * @param sessionId      A unique session id\n     * @param serverDataJson Server data\n     * @return Difference data between the server and the local data\n     */\n    static JSONObject getDiffData(String sessionId, JSONObject serverDataJson) {\n        JSONObject diffData;\n        try {\n            String localDataString = SonicFileUtils.readFile(new File(SonicFileUtils.getSonicDataPath(sessionId)));\n            if (!TextUtils.isEmpty(localDataString)) {\n                JSONObject localDataJson = new JSONObject(localDataString);\n                diffData = getDiffData(localDataJson, serverDataJson);\n            } else {\n                diffData = serverDataJson;\n            }\n            if (diffData != null && diffData.length() > 0) {\n                diffData.put(\"local_refresh_time\", System.currentTimeMillis());\n            }\n        } catch (Throwable e) {\n            diffData = null;\n            log(TAG, Log.ERROR, \"getDiffData error1:\" + e.getMessage());\n        }\n        return diffData;\n    }\n\n    static JSONObject getDiffData(JSONObject localDataJson, JSONObject serverDataJson){\n        if(localDataJson == null || serverDataJson == null){\n            return null;\n        }\n\n        JSONObject diffData = new JSONObject();\n        try {\n            Iterator<?> iterator = serverDataJson.keys();\n            String key;\n            String serverData;\n            String localData;\n            while (iterator.hasNext()) {\n                key = iterator.next().toString();\n                serverData = serverDataJson.optString(key);\n                localData = localDataJson.optString(key);\n                if (!serverData.equals(localData)) {\n                    diffData.put(key, serverData);\n                    if (shouldLog(Log.DEBUG)) {\n                        log(TAG, Log.DEBUG, \"getDiffData:find diff data, key ->\" + key + \", length=\" + serverData.length() + \".\");\n                    }\n                }\n            }\n        }catch (Throwable e){\n            diffData = null;\n            log(TAG, Log.ERROR, \"getDiffData error2:\" + e.getMessage());\n        }\n\n        return diffData;\n    }\n\n    static String buildHtml(final String sessionId, JSONObject dataJson, String sha1, int dataMaxSize) {\n        File templateFile = new File(SonicFileUtils.getSonicTemplatePath(sessionId));\n        if (templateFile.exists()) {\n            String templateString = SonicFileUtils.readFile(templateFile);\n            if (!TextUtils.isEmpty(templateString)) {\n\n                final String htmlString = buildHtml(templateString, dataJson, dataMaxSize);\n\n                if (TextUtils.isEmpty(sha1) || sha1.equalsIgnoreCase(SonicUtils.getSHA1(htmlString))) {\n                    return htmlString;\n                }\n\n                SonicEngine.getInstance().getRuntime().postTaskToThread(new Runnable() {\n                    @Override\n                    public void run() {\n                        String path = SonicFileUtils.getSonicHtmlPath(sessionId) + \".tmp\";\n                        SonicFileUtils.writeFile(htmlString, path);\n                    }\n                }, 0);\n\n                log(TAG, Log.ERROR, \"buildHtml error: verify sha1 error.\");\n                return null;\n            } else {\n                log(TAG, Log.ERROR, \"buildHtml error: template string is empty.\");\n            }\n        } else {\n            log(TAG, Log.ERROR, \"buildHtml error: template file is not exists.\");\n        }\n        return null;\n    }\n\n    /**\n     * Build the template and data into html\n     * @param templateString The contents of the template\n     * @param dataJson       The contents of the data\n     * @param dataMaxSize    the length of data.Through it to determine StringBuilder's original length\n     * @return final html string\n     */\n    static String buildHtml(String templateString, JSONObject dataJson, int dataMaxSize) {\n        if (TextUtils.isEmpty(templateString) || dataJson == null) {\n            return null;\n        }\n        StringBuilder htmlStringBuilder = new StringBuilder(templateString.length() + dataMaxSize);\n        htmlStringBuilder.append(templateString);\n        String key;\n        String data;\n        int index;\n        Iterator<?> iterator = dataJson.keys();\n        while (iterator.hasNext()) {\n            key = iterator.next().toString();\n            data = dataJson.optString(key);\n            index = htmlStringBuilder.indexOf(key);\n            if (-1 != index) {\n                htmlStringBuilder.replace(index, index + key.length(), data);\n            }\n        }\n        return htmlStringBuilder.toString();\n    }\n\n    /**\n     * Save sonic files, such as html, template and data\n     *\n     * @param sessionId      A unique session id\n     * @param htmlString     Html content\n     * @param templateString Template content\n     * @param dataString     Data content\n     * @return The result of save files.true if all data is saved successfully\n     */\n    static boolean saveSessionFiles(String sessionId, String htmlString, String templateString, String dataString, Map<String, List<String>> headers) {\n        if (!TextUtils.isEmpty(htmlString) && !SonicFileUtils.writeFile(htmlString, SonicFileUtils.getSonicHtmlPath(sessionId))) {\n            log(TAG, Log.ERROR, \"saveSessionData error: write html file fail.\");\n            return false;\n        }\n\n        if (!TextUtils.isEmpty(templateString) && !SonicFileUtils.writeFile(templateString, SonicFileUtils.getSonicTemplatePath(sessionId))) {\n            log(TAG, Log.ERROR, \"saveSessionData error: write template file fail.\");\n            return false;\n        }\n\n        if (!TextUtils.isEmpty(dataString) && !SonicFileUtils.writeFile(dataString, SonicFileUtils.getSonicDataPath(sessionId))) {\n            log(TAG, Log.ERROR, \"saveSessionData error: write data file fail.\");\n            return false;\n        }\n\n        if (headers != null && headers.size() > 0\n                &&!SonicFileUtils.writeFile(SonicFileUtils.convertHeadersToString(headers), SonicFileUtils.getSonicHeaderPath(sessionId))) {\n            log(TAG, Log.ERROR, \"saveSessionData error: write header file fail.\");\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * save resource files, including resource and headers.\n     *\n     * @param resourceName resource file name\n     * @param resourceBytes resource bytes content\n     * @param headers resource headers\n     * @return The result of save files. true if all data is saved successfully.\n     */\n    public static boolean saveResourceFiles(String resourceName, byte[] resourceBytes, Map<String, List<String>> headers) {\n        if (resourceBytes != null && !SonicFileUtils.writeFile(resourceBytes, SonicFileUtils.getSonicResourcePath(resourceName))) {\n            log(TAG, Log.ERROR, \"saveResourceFiles error: write resource data fail.\");\n            return false;\n        }\n\n        if (headers != null && headers.size() > 0\n                &&!SonicFileUtils.writeFile(SonicFileUtils.convertHeadersToString(headers), SonicFileUtils.getSonicResourceHeaderPath(resourceName))) {\n            log(TAG, Log.ERROR, \"saveResourceFiles error: write header file fail.\");\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Get filtered headers by session id, this method will return a map of header(k-v) which\n     * will not contains \"Set-Cookie\", \"Cache-Control\", \"Expires\".\n     *\n     * @param srcHeaders      The source headers\n     * @return The headers of sessionId\n     */\n    public static HashMap<String, String> getFilteredHeaders(Map<String, List<String>> srcHeaders) {\n        HashMap<String, String> headers = new HashMap<String, String>();\n        if (null != srcHeaders) {\n            List<String> headerValues;\n            try {\n                for (Map.Entry<String, List<String>> entry : srcHeaders.entrySet()) {\n                    if (\"Set-Cookie\".equalsIgnoreCase(entry.getKey()) || \"Cache-Control\".equalsIgnoreCase(entry.getKey()) ||\n                            \"Expires\".equalsIgnoreCase(entry.getKey()) || \"Etag\".equalsIgnoreCase(entry.getKey())) {\n                        // forbid webview kernel to run cache related logic\n                        continue;\n                    }\n                    headerValues = entry.getValue();\n                    if (null != headerValues && 1 == headerValues.size()) {\n                        headers.put(entry.getKey(), headerValues.get(0));\n                    }\n                }\n            } catch (Throwable e) {\n                SonicUtils.log(TAG, Log.ERROR, \"getFilteredHeaders error! \" + e.getMessage());\n            }\n        }\n        return headers;\n    }\n\n    /**\n     * Find and get the charset from the Content-Type value.\n     * @param headerValue The value corresponding to the HTTP Header Content-Type\n     * @return The charset.\n     */\n    static String getCharset(String headerValue) {\n        String charset = DEFAULT_CHARSET;\n        if (!TextUtils.isEmpty(headerValue) ) {\n            headerValue = headerValue.toLowerCase();\n            int index = headerValue.indexOf(\"charset\");\n            if (index != -1) {\n                String temp = headerValue.substring(index);\n                temp = temp.replace(\" \", \"\");\n                int endIndex = temp.indexOf(\";\");\n                endIndex = endIndex == -1 ? temp.length() : endIndex;\n                charset = temp.substring(8, endIndex);\n\n                charset = TextUtils.isEmpty(charset) ? DEFAULT_CHARSET : charset;\n            }\n        }\n        return charset;\n    }\n\n    /**\n     * Separate html into templates and data\n     *\n     * @param sessionId             A unique session id\n     * @param htmlString            Html content\n     * @param templateStringBuilder StringBuilder to save template content\n     * @param dataStringBuilder     StringBuilder to save data content\n     * @return The result of separate\n     */\n    static boolean separateTemplateAndData(String sessionId, String htmlString, StringBuilder templateStringBuilder, StringBuilder dataStringBuilder) {\n        long startTime = System.currentTimeMillis();\n        log(TAG, Log.INFO, \"separateTemplateAndData:sessionId(\" + sessionId + \") start, htmlString = \" + (htmlString.length() > 128 ? htmlString.substring(0, 128) : htmlString));\n\n        JSONObject info = new JSONObject();\n        int lastEnd = 0;\n        try {\n            Pattern pattern = Pattern.compile(SONIC_TAG_PATTERN, Pattern.MULTILINE);\n            Matcher matcher = pattern.matcher(htmlString);\n            while (matcher.find()) {\n                String dataInfo = matcher.group();\n                String dataMark = SONIC_TAG_DIFF_BEGIN;\n                int markLen = dataMark.length();\n                int keyStart = dataInfo.indexOf(dataMark);\n                int keyEnd = dataInfo.indexOf(SONIC_TAG_DIFF_END);\n                String key = null;\n                if (keyStart != -1 && keyStart + markLen < keyEnd) {\n                    key = dataInfo.substring(keyStart + markLen, keyEnd);\n                }\n\n                key = SONIC_TAG_KEY_BEGIN + key + SONIC_TAG_KEY_END;\n                if (SonicUtils.shouldLog(Log.DEBUG)) {\n                    SonicUtils.log(TAG, Log.DEBUG, \"separateTemplateAndData:sessionId(\" + sessionId + \"), key = \" + key);\n                }\n\n                if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(dataInfo)) {\n                    info.put(key, dataInfo);\n                    int start = matcher.start();\n                    templateStringBuilder.append(htmlString.substring(lastEnd, start));\n                    templateStringBuilder.append(key);\n                    lastEnd = matcher.end();\n                }\n            }\n\n            if (lastEnd < htmlString.length() && templateStringBuilder.length() > 0) {\n                templateStringBuilder.append(htmlString.substring(lastEnd, htmlString.length()));\n            }\n\n            int titleStart = templateStringBuilder.indexOf(SONIC_TAG_TITLE_OPEN);\n            int titleEnd = templateStringBuilder.indexOf(SONIC_TAG_TITLE_CLOSE, titleStart + SONIC_TAG_TITLE_OPEN.length()) + SONIC_TAG_TITLE_CLOSE.length();\n            if (titleStart != -1 && titleStart < titleEnd) {\n                String key = SONIC_TAG_TITLE_KEY;\n                info.put(key, templateStringBuilder.substring(titleStart, titleEnd));\n                templateStringBuilder.replace(titleStart, titleEnd, key);\n            }\n\n            dataStringBuilder.append(info.toString());\n\n        } catch (Exception e) {\n            log(TAG, Log.ERROR, \"separateTemplateAndData:sessionId(\" + sessionId + \") error:\" + e.getMessage());\n            return false;\n        }\n        log(TAG, Log.INFO, \"separateTemplateAndData:sessionId(\" + sessionId + \") end, cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n        return true;\n    }\n\n    /**\n     * Remove a unique session cache, include memory cache and disk cache\n     *\n     * @param sessionId A unique session id\n     */\n    static void removeSessionCache(String sessionId) {\n        SonicDataHelper.removeSessionData(sessionId);\n        SonicFileUtils.deleteSonicFiles(sessionId);\n    }\n\n    /**\n     * Remove a unique resource cache.\n     *\n     * @param resourceId a unique resource id\n     */\n    public static void removeResourceCache(String resourceId) {\n        SonicResourceDataHelper.removeResourceData(resourceId);\n        SonicFileUtils.deleteResourceFiles(resourceId);\n    }\n\n    /**\n     * Remove all session cache, include memory cache and disk cache\n     *\n     */\n    static boolean removeAllSessionCache() {\n        File cacheRootDir = new File(SonicFileUtils.getSonicCacheDirPath());\n        if (cacheRootDir.exists()) {\n            SonicDataHelper.clear();\n            return SonicFileUtils.deleteAllChildFiles(cacheRootDir);\n        }\n        return false;\n    }\n\n    /**\n     * According to cache-offline head and Cache-Control header to decide whether to save data\n     *\n     * @param isSupportCacheControl Indicates whether to check Cache-Control header or not\n     * @param cacheOffline Cache-offline head\n     * @param headers Response http headers\n     *\n     * @return need or not\n     */\n    static boolean needSaveData(boolean isSupportCacheControl, String cacheOffline, Map<String, List<String>> headers) {\n        boolean needSaveData =  !TextUtils.isEmpty(cacheOffline) && (SonicSession.OFFLINE_MODE_STORE.equals(cacheOffline) || SonicSession.OFFLINE_MODE_TRUE.equals(cacheOffline));\n        if (needSaveData && isSupportCacheControl) {\n            //check http header Cache-Control\n            List<String> responseHeaderValues = headers.get(SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL.toLowerCase());\n            if (headers.containsKey(SonicSessionConnection.HTTP_HEAD_FIELD_CACHE_CONTROL)) {\n                if (responseHeaderValues != null && responseHeaderValues.size() > 0) {\n                    String header = responseHeaderValues.get(0).toLowerCase();\n                    if (header.contains(\"no-cache\") || header.contains(\"no-store\") || header.contains(\"must-revalidate\")) {\n                        needSaveData = false;\n                    }\n                }\n            } else if (headers.containsKey(SonicSessionConnection.HTTP_HEAD_FIELD_PRAGMA)) {\n                needSaveData = false;\n            }\n        }\n\n        return needSaveData;\n    }\n\n    /**\n     * According to cache-offline head decide whether to refresh page\n     *\n     * @param cacheOffline Cache-offline head\n     * @return need refresh or not\n     */\n    static boolean needRefreshPage(String cacheOffline) {\n        return !TextUtils.isEmpty(cacheOffline) && (SonicSession.OFFLINE_MODE_FALSE.equals(cacheOffline) || SonicSession.OFFLINE_MODE_TRUE.equals(cacheOffline));\n    }\n\n\n    static String addSonicUrlParam(String url, String paramKey, String paramValue) {\n        if (!TextUtils.isEmpty(url)) {\n            StringBuilder stringBuilder = new StringBuilder(url);\n\n            int paramKeyIndex;\n            int nextParamStartIndex;\n            int paramStartIndex = stringBuilder.lastIndexOf(\"/\");\n            if (paramStartIndex < 0) paramStartIndex = 0;\n            String paramKeyPattern1 = \"&\" + paramKey + \"=\";\n            String paramKeyPattern2 = \"?\" + paramKey + \"=\";\n            int paramKeyPattern = paramKeyPattern1.length();\n            try {\n                do {\n                    paramKeyIndex = stringBuilder.indexOf(paramKeyPattern1, paramStartIndex);\n                    if (-1 == paramKeyIndex) {\n                        paramKeyIndex = stringBuilder.indexOf(paramKeyPattern2, paramStartIndex);\n                    }\n                    if (paramKeyIndex > 0) {\n                        nextParamStartIndex = stringBuilder.indexOf(\"&\", paramKeyIndex + paramKeyPattern);\n                        if (nextParamStartIndex > 0) {\n                            stringBuilder.replace(paramKeyIndex + 1, nextParamStartIndex + 1, \"\");\n                        } else {\n                            stringBuilder.replace(paramKeyIndex, stringBuilder.length(), \"\");\n                        }\n                    } else {\n                        break;\n                    }\n                } while (true);\n            } catch (Throwable e) {\n                log(TAG, Log.ERROR, \"addSonicUrlParam error:\" + e.getMessage());\n                return url;\n            }\n            if (-1 != stringBuilder.indexOf(\"?\")) {\n                stringBuilder.append(\"&\").append(paramKey).append(\"=\").append(paramValue);\n            } else {\n                stringBuilder.append(\"?\").append(paramKey).append(\"=\").append(paramValue);\n            }\n            return stringBuilder.toString();\n        }\n        return url;\n    }\n\n\n    /**\n     * Get mime type for url simply.\n     * (Maybe {@code android.webkit.MimeTypeMap.getMimeTypeFromExtension} is better.)\n     * @param url target url\n     * @return mime type\n     */\n    public static String getMime(String url) {\n        String mime = \"text/html\";\n        Uri currentUri = Uri.parse(url);\n        String path = currentUri.getPath();\n        if (path.endsWith(\".css\")) {\n            mime = \"text/css\";\n        } else if (path.endsWith(\".js\")) {\n            mime = \"application/x-javascript\";\n        } else if (path.endsWith(\".jpg\") || path.endsWith(\".gif\") ||\n                path.endsWith(\".png\") || path.endsWith(\".jpeg\") ||\n                path.endsWith(\".webp\") || path.endsWith(\".bmp\")) {\n            mime = \"image/*\";\n        }\n        return mime;\n    }\n\n\n    private static final char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7',\n            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\n\n\n    static String getSHA1(String content) {\n        if (TextUtils.isEmpty(content)) {\n            return \"\";\n        }\n        return getSHA1(content.getBytes());\n    }\n\n    public static String getSHA1(byte[] contentBytes) {\n        if (contentBytes == null || contentBytes.length <= 0) {\n            return \"\";\n        }\n        try {\n            MessageDigest sha1 = MessageDigest.getInstance(\"SHA1\");\n            sha1.update(contentBytes, 0, contentBytes.length);\n            return toHexString(sha1.digest());\n        } catch (Exception e) {\n            return \"\";\n        }\n    }\n\n\n    public static String getMD5(String content) {\n        if (TextUtils.isEmpty(content))\n            return \"\";\n        try {\n            MessageDigest sha1 = MessageDigest.getInstance(\"MD5\");\n            sha1.update(content.getBytes(), 0, content.getBytes().length);\n            return toHexString(sha1.digest());\n        } catch (Exception e) {\n            return \"\";\n        }\n    }\n\n    private static String toHexString(byte b[]) {\n        StringBuilder sb = new StringBuilder(b.length * 2);\n        for (byte aB : b) {\n            sb.append(hexChar[(aB & 0xf0) >>> 4]);\n            sb.append(hexChar[aB & 0xf]);\n        }\n        return sb.toString();\n    }\n\n    /**\n     *\n     * @param timeInterval The time interval between check and clear sonic cache\n     * @return true if we should clear sonic cache.\n     */\n    static boolean shouldClearCache(long timeInterval) {\n        SharedPreferences sp = SonicEngine.getInstance().getRuntime().getSonicSharedPreferences();\n        long lastCheckTime = sp.getLong(SONIC_CLEAR_CACHE_TIME, 0L);\n        return System.currentTimeMillis() - lastCheckTime > timeInterval;\n    }\n\n    /**\n     * save the clear cache time.\n     *\n     * @param timestamp time when clear the cache\n     */\n    static void saveClearCacheTime(long timestamp) {\n        SharedPreferences sp = SonicEngine.getInstance().getRuntime().getSonicSharedPreferences();\n        sp.edit().putLong(SONIC_CLEAR_CACHE_TIME, timestamp).apply();\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/StandardSonicSession.java",
    "content": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n *\n * https://opensource.org/licenses/BSD-3-Clause\n *\n * 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.\n *\n *\n */\n\npackage com.tencent.sonic.sdk;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport org.json.JSONObject;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.lang.ref.WeakReference;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n/**\n *\n * A subclass of SonicSession.\n * StandardSonicSession only uses the way of {@link SonicSessionClient#loadUrl(String, Bundle)}\n * (not loadData). When client initiates a resource interception, the user can set response and header\n * information (such as csp) for the kernel.\n *\n * <p>\n * See also {@link QuickSonicSession}\n */\npublic class StandardSonicSession extends SonicSession implements Handler.Callback {\n\n    /**\n     * Log filter\n     */\n    private static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"StandardSonicSession\";\n\n    private static final String TEMPLATE_CHANGE_BUNDLE_PARAMS_REFRESH = \"refresh\";\n\n    private static final int CLIENT_CORE_MSG_BEGIN = COMMON_MSG_END;\n\n    /**\n     * The message will be sent When client is ready.\n     */\n    private static final int CLIENT_MSG_CLIENT_READY = CLIENT_CORE_MSG_BEGIN + 1;\n\n    private final Object webResponseLock = new Object();\n\n    /**\n     * Whether {@link SonicSession#pendingWebResourceStream} is read from cache or not\n     */\n    private final AtomicBoolean isCachePendingStream = new AtomicBoolean(false);\n\n    StandardSonicSession(String id, String url, SonicSessionConfig config) {\n        super(id, url, config);\n    }\n\n    public int getSrcResultCode() {\n        return srcResultCode;\n    }\n\n\n    @Override\n    public boolean handleMessage(Message msg) {\n\n        // fix issue[https://github.com/Tencent/VasSonic/issues/89]\n        if (super.handleMessage(msg)) {\n            return true; // handled by super class\n        }\n\n        switch (msg.what) {\n            case CLIENT_MSG_CLIENT_READY: {\n                sessionClient.loadUrl(srcUrl, new Bundle());\n                break;\n            }\n\n            case CLIENT_MSG_NOTIFY_RESULT: {\n                if (msg.arg2 == SONIC_RESULT_CODE_DATA_UPDATE) {\n                    Bundle data = msg.getData();\n                    pendingDiffData = data.getString(DATA_UPDATE_BUNDLE_PARAMS_DIFF);\n                } else if (msg.arg2 == SONIC_RESULT_CODE_TEMPLATE_CHANGE) {\n                    Bundle data = msg.getData();\n                    if (data.getBoolean(TEMPLATE_CHANGE_BUNDLE_PARAMS_REFRESH, false)) {\n                        SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:load url with preload=2, webCallback is null? ->\" + (null != diffDataCallback));\n                        sessionClient.loadUrl(srcUrl, null);\n                    }\n                }\n                setResult(msg.arg1, msg.arg2, true);\n                break;\n            }\n            case CLIENT_MSG_ON_WEB_READY: {\n                diffDataCallback = (SonicDiffDataCallback) msg.obj;\n                setResult(srcResultCode, finalResultCode, true);\n                break;\n            }\n\n            default: {\n                if (SonicUtils.shouldLog(Log.DEBUG)) {\n                    SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") can not  recognize refresh type: \" + msg.what);\n                }\n                return false;\n            }\n\n        }\n        return true;\n    }\n\n    public boolean onClientReady() {\n        if (STATE_NONE == sessionState.get()) {\n            start();\n        }\n        if (Looper.getMainLooper() == Looper.myLooper()) {\n            sessionClient.loadUrl(srcUrl, new Bundle());\n        } else {\n            Message msg = mainHandler.obtainMessage(CLIENT_MSG_CLIENT_READY);\n            mainHandler.sendMessage(msg);\n        }\n        return true;\n    }\n\n    public boolean onWebReady(SonicDiffDataCallback callback) {\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") onWebReady: webCallback has set ? ->\" + (null != diffDataCallback));\n\n        if (null != diffDataCallback) {\n            diffDataCallback = null;\n            SonicUtils.log(TAG, Log.WARN, \"session(\" + sId + \") onWebReady: call more than once.\");\n        }\n\n        Message msg = Message.obtain();\n        msg.what = CLIENT_MSG_ON_WEB_READY;\n        msg.obj = callback;\n        mainHandler.sendMessage(msg);\n\n        return true;\n    }\n\n    protected Object onRequestResource(String url) {\n        if (!isMatchCurrentUrl(url)) {\n            return null;\n        }\n\n        if (SonicUtils.shouldLog(Log.DEBUG)) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \")  onClientRequestResource:url = \" + url);\n        }\n\n        wasInterceptInvoked.set(true);\n        long startTime = System.currentTimeMillis();\n        if (sessionState.get() == STATE_RUNNING) {\n            synchronized (sessionState) {\n                try {\n                    if (sessionState.get() == STATE_RUNNING) {\n                        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") now wait for pendingWebResourceStream!\");\n                        sessionState.wait(30 * 1000);\n                    }\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") wait for pendingWebResourceStream failed\" + e.getMessage());\n                }\n            }\n        } else {\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") is not in running state: \" + sessionState);\n            }\n        }\n\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") have pending stream? -> \" + (pendingWebResourceStream != null) + \", cost \" + (System.currentTimeMillis() - startTime) + \"ms.\");\n\n        synchronized (webResponseLock) {\n            if (null != pendingWebResourceStream) {\n                Object webResourceResponse;\n                if (!isDestroyedOrWaitingForDestroy()) {\n                    String mime = SonicUtils.getMime(srcUrl);\n                    webResourceResponse = SonicEngine.getInstance().getRuntime().createWebResourceResponse(mime,\n                            isCachePendingStream.get() ? SonicUtils.DEFAULT_CHARSET : getCharsetFromHeaders(),\n                            pendingWebResourceStream,\n                            isCachePendingStream.get() ? getCacheHeaders() : getHeaders());\n                } else {\n                    webResourceResponse = null;\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") onClientRequestResource error: session is destroyed!\");\n\n                }\n                pendingWebResourceStream = null;\n                return webResourceResponse;\n            }\n        }\n\n        return null;\n    }\n\n    @Override\n    protected void handleFlow_LoadLocalCache(String localHtml) {\n        if (!TextUtils.isEmpty(localHtml)) {\n            synchronized (webResponseLock) {\n                pendingWebResourceStream = new ByteArrayInputStream(localHtml.getBytes());\n                isCachePendingStream.set(true);\n            }\n            switchState(STATE_RUNNING, STATE_READY, true);\n        }\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionLoadLocalCache(localHtml);\n            }\n        }\n    }\n\n\n    /**\n     *\n     * Sonic will always read the new data from the server until the local page finish.\n     * If the server data is not read finished sonic will split the read and unread data\n     * into a bridgedStream{@link SonicSessionStream}, otherwise all the read data will be\n     * encapsulated as an inputStream{@link java.io.ByteArrayInputStream}. When client\n     * initiates a resource interception, sonic will provide the bridgedStream or inputStream to\n     * the kernel.\n     *\n     * <p>\n     * If need save and separate data, sonic will save the server data and separate the server\n     * data to template and data.\n     *\n     */\n\n    @Override\n    protected void handleFlow_TemplateChange(String newHtml) {\n        try {\n            SonicUtils.log(TAG, Log.INFO, \"handleFlow_TemplateChange.\");\n            long startTime = System.currentTimeMillis();\n\n            String htmlString = newHtml;\n            // When serverRsp is empty\n            if (TextUtils.isEmpty(htmlString)) {\n                pendingWebResourceStream = server.getResponseStream(wasOnPageFinishInvoked);\n                if (pendingWebResourceStream == null) {\n                    SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_TemplateChange error:server.getResponseStream = null!\");\n                    return;\n                }\n\n                htmlString = server.getResponseData(false);\n            }\n\n            String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n\n            Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n            msg.arg1 = msg.arg2 = SONIC_RESULT_CODE_TEMPLATE_CHANGE;\n\n            synchronized (webResponseLock) {\n                if (!wasInterceptInvoked.get()) {\n                    if (!TextUtils.isEmpty(htmlString)) {\n                        msg.arg2 = SONIC_RESULT_CODE_HIT_CACHE;\n                        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_TemplateChange:oh yeah, templateChange load hit 304.\");\n                    } else {\n                        SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_TemplateChange error:responseDataTuple not complete!\");\n                        return;\n                    }\n                } else {\n                    if (SonicUtils.needRefreshPage(cacheOffline)) {\n                        Bundle data = new Bundle();\n                        data.putBoolean(TEMPLATE_CHANGE_BUNDLE_PARAMS_REFRESH, true);\n                        msg.setData(data);\n                    } else {\n                        msg.arg2 = SONIC_RESULT_CODE_HIT_CACHE;\n                    }\n                }\n                isCachePendingStream.set(false);\n            }\n\n            mainHandler.sendMessage(msg);\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionTemplateChanged(htmlString);\n                }\n            }\n\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") read byte stream cost \" + (System.currentTimeMillis() - startTime) + \" ms, wasInterceptInvoked: \" + wasInterceptInvoked.get());\n            }\n\n            //save and separate data\n            if (SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n                switchState(STATE_RUNNING, STATE_READY, true);\n                if (!TextUtils.isEmpty(htmlString)) {\n                    postTaskToSaveSonicCache(htmlString);\n                }\n            } else if (OFFLINE_MODE_FALSE.equals(cacheOffline)) {\n                SonicUtils.removeSessionCache(id);\n                SonicUtils.log(TAG, Log.INFO, \"handleClientCoreMessage_TemplateChange:offline mode is 'false', so clean cache.\");\n            } else {\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_TemplateChange:offline->\" + cacheOffline + \" , so do not need cache to file.\");\n            }\n\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.DEBUG, \"session(\" + sId + \") handleFlow_TemplateChange error:\" + e.getMessage());\n        }\n    }\n\n    @Override\n    protected void handleFlow_HttpError(int responseCode) {\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionHttpError(responseCode);\n            }\n        }\n    }\n\n    @Override\n    protected void handleFlow_ServiceUnavailable() {\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionUnAvailable();\n            }\n        }\n    }\n\n    /**\n     *\n     * Sonic will always read the new data from the server until client initiates a resource interception\n     * If the server data is not read finished sonic will split the read and unread data into a\n     * bridgedStream{@link SonicSessionStream}, otherwise all the read data will be encapsulated as an\n     * inputStream{@link java.io.ByteArrayInputStream}. When client initiates a resource interception,\n     * sonic will provide the bridgedStream or inputStream to the kernel.\n     *\n     * <p>\n     * If need save and separate data, sonic will save the server data and separate the server data to template and data\n     *\n     */\n    protected void handleFlow_FirstLoad() {\n        synchronized (webResponseLock) {\n            pendingWebResourceStream = server.getResponseStream(wasInterceptInvoked);\n        }\n\n        if (null == pendingWebResourceStream) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_FirstLoad error:server.getResponseStream is null!\");\n            return;\n        }\n\n        Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n        msg.arg1 = msg.arg2 = SONIC_RESULT_CODE_FIRST_LOAD;\n        String htmlString = server.getResponseData(false);\n\n        if (!TextUtils.isEmpty(htmlString)) {\n            try {\n                msg.arg2 = SONIC_RESULT_CODE_HIT_CACHE;\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_FirstLoad:oh yeah, first load hit 304.\");\n            } catch (Throwable e) {\n                synchronized (webResponseLock) {\n                    pendingWebResourceStream = null;\n                }\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_FirstLoad error:\" + e.getMessage() + \".\");\n            }\n        }\n\n        isCachePendingStream.set(false);\n\n        mainHandler.sendMessage(msg);\n\n        for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n            SonicSessionCallback callback = ref.get();\n            if (callback != null) {\n                callback.onSessionFirstLoad(htmlString);\n            }\n        }\n\n        boolean hasCacheData = !TextUtils.isEmpty(htmlString);\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_FirstLoad:hasCacheData=\" + hasCacheData + \".\");\n\n        String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n        if (SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n            if (hasCacheData) {\n                switchState(STATE_RUNNING, STATE_READY, true);\n\n                postTaskToSaveSonicCache(htmlString);\n            }\n        } else {\n            SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_FirstLoad:offline->\" + cacheOffline + \" , so do not need cache to file.\");\n        }\n    }\n\n    /**\n     *\n     * Sonic obtains the difference data between the server and the local data first,then sonic will\n     * build the template and server data into html.If client did not load url before, the new html\n     * will be encapsulated as an inputStream{@link java.io.ByteArrayInputStream},When client initiates\n     * a resource interception, sonic provides the inputStream to the kernel.\n     *\n     * If client did load url before, sonic provides the diff data to page when page obtains the diff data.\n     *\n     * @param serverRsp Server response data.\n     */\n    protected void handleFlow_DataUpdate(String serverRsp) {\n        SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: start.\");\n\n        try {\n            String htmlSha1 = null;\n            String htmlString = null;\n\n            if (TextUtils.isEmpty(serverRsp)) {\n                serverRsp = server.getResponseData(true);\n            } else {\n                htmlString = server.getResponseData(false);\n                htmlSha1 = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_HTML_SHA1);\n            }\n\n            if (TextUtils.isEmpty(serverRsp)) {\n                return;\n            }\n\n            final String eTag = server.getResponseHeaderField(getCustomHeadFieldEtagKey());\n            final String templateTag = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_TEMPLATE_TAG);\n\n            String cacheOffline = server.getResponseHeaderField(SonicSessionConnection.CUSTOM_HEAD_FILED_CACHE_OFFLINE);\n\n            long startTime = System.currentTimeMillis();\n            JSONObject serverRspJson = new JSONObject(serverRsp);\n            final JSONObject serverDataJson = serverRspJson.optJSONObject(\"data\");\n            JSONObject diffDataJson = SonicUtils.getDiffData(id, serverDataJson);\n            Bundle diffDataBundle = new Bundle();\n            if (null != diffDataJson) {\n                diffDataBundle.putString(DATA_UPDATE_BUNDLE_PARAMS_DIFF, diffDataJson.toString());\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"handleFlow_DataUpdate:getDiffData error.\");\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_MERGE_DIFF_DATA_FAIL);\n            }\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"handleFlow_DataUpdate:getDiffData cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n\n            if (SonicUtils.needRefreshPage(cacheOffline)) {\n                if (SonicUtils.shouldLog(Log.INFO)) {\n                    SonicUtils.log(TAG, Log.INFO, \"handleFlow_DataUpdate:loadData was invoked, quick notify web data update.\");\n                }\n                Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n                msg.arg1 = msg.arg2 = SONIC_RESULT_CODE_DATA_UPDATE;\n                msg.setData(diffDataBundle);\n                mainHandler.sendMessage(msg);\n            }\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionDataUpdated(serverRsp);\n                }\n            }\n\n            startTime = System.currentTimeMillis();\n\n            if (TextUtils.isEmpty(htmlString)) {\n                htmlSha1 = serverRspJson.optString(\"html-sha1\");\n                htmlString = SonicUtils.buildHtml(id, serverDataJson, htmlSha1, serverRsp.length());\n            }\n\n            if (SonicUtils.shouldLog(Log.DEBUG)) {\n                SonicUtils.log(TAG, Log.DEBUG, \"handleFlow_DataUpdate:buildHtml cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n            }\n\n            if (!TextUtils.isEmpty(htmlString) && !wasInterceptInvoked.get() && SonicUtils.needRefreshPage(cacheOffline)) {\n                synchronized (webResponseLock) {\n                    pendingWebResourceStream = new ByteArrayInputStream(htmlString.getBytes());\n                    isCachePendingStream.set(false);\n                }\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate:oh yeah, dataUpdate load hit 304.\");\n                mainHandler.removeMessages(CLIENT_MSG_NOTIFY_RESULT);\n                Message msg = mainHandler.obtainMessage(CLIENT_MSG_NOTIFY_RESULT);\n                msg.arg1 = SONIC_RESULT_CODE_DATA_UPDATE;\n                msg.arg2 = SONIC_RESULT_CODE_HIT_CACHE;\n                mainHandler.sendMessage(msg);\n            }\n\n            if (TextUtils.isEmpty(htmlString)) {\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_BUILD_HTML_ERROR);\n            }\n\n            if (null == diffDataJson || null == htmlString\n                    || !SonicUtils.needSaveData(config.SUPPORT_CACHE_CONTROL, cacheOffline, server.getResponseHeaderFields())) {\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: clean session cache.\");\n                SonicUtils.removeSessionCache(id);\n            }\n\n            switchState(STATE_RUNNING, STATE_READY, true);\n\n            Thread.yield();\n\n            startTime = System.currentTimeMillis();\n            Map<String, List<String>> headers = server.getResponseHeaderFields();\n\n            for (WeakReference<SonicSessionCallback> ref : sessionCallbackList) {\n                SonicSessionCallback callback = ref.get();\n                if (callback != null) {\n                    callback.onSessionSaveCache(htmlString, null, serverDataJson.toString());\n                }\n            }\n\n            if (SonicUtils.saveSessionFiles(id, htmlString, null, serverDataJson.toString(), headers)) {\n                long htmlSize = new File(SonicFileUtils.getSonicHtmlPath(id)).length();\n                SonicUtils.saveSonicData(id, eTag, templateTag, htmlSha1, htmlSize, headers);\n                SonicUtils.log(TAG, Log.INFO, \"session(\" + sId + \") handleFlow_DataUpdate: finish save session cache, cost \" + (System.currentTimeMillis() - startTime) + \" ms.\");\n\n            } else {\n                SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_DataUpdate: save session files fail.\");\n                SonicEngine.getInstance().getRuntime().notifyError(sessionClient, srcUrl, SonicConstants.ERROR_CODE_WRITE_FILE_FAIL);\n            }\n\n        } catch (Throwable e) {\n            SonicUtils.log(TAG, Log.ERROR, \"session(\" + sId + \") handleFlow_DataUpdate error:\" + e.getMessage());\n        }\n\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/download/SonicDownloadCache.java",
    "content": "/*\n *\n *  * Tencent is pleased to support the open source community by making VasSonic available.\n *  *\n *  * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *  * 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\n *  *\n *  * https://opensource.org/licenses/BSD-3-Clause\n *  *\n *  * 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.\n *  *\n *  *\n *\n */\n\npackage com.tencent.sonic.sdk.download;\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport com.tencent.sonic.sdk.SonicConstants;\nimport com.tencent.sonic.sdk.SonicEngine;\nimport com.tencent.sonic.sdk.SonicFileUtils;\nimport com.tencent.sonic.sdk.SonicResourceDataHelper;\nimport com.tencent.sonic.sdk.SonicUtils;\n\nimport java.io.File;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Sonic download cache manager\n */\n\npublic abstract class SonicDownloadCache {\n\n    /**\n     * get the cached content according to the url\n     *\n     * @param url the download url\n     * @return bytes of cached content of the url\n     */\n    public abstract byte[] getResourceCache(String url);\n\n    /**\n     * get the cached response headers according to the url\n     *\n     * @param url the download url\n     * @return cached headers of the url\n     */\n    public abstract Map<String, List<String>> getResourceCacheHeader(String url);\n\n    /**\n     *\n     * @return Sub resource cache\n     */\n    public static SonicDownloadCache getSubResourceCache() {\n        return new SonicResourceCache();\n    }\n\n    /**\n     * An sub resource cache implementation {@link SonicDownloadCache}\n     */\n    public static class SonicResourceCache extends SonicDownloadCache {\n\n        /**\n         * log filter\n         */\n        public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicDownloadCache\";\n\n        public byte[] getResourceCache(String resourceUrl) {\n            if (TextUtils.isEmpty(resourceUrl)) {\n                return null;\n            }\n            String resourceId = SonicUtils.getMD5(resourceUrl);\n            SonicResourceDataHelper.ResourceData resourceData = SonicResourceDataHelper.getResourceData(resourceId);\n\n            // the resource cache expired\n            if (resourceData.expiredTime < System.currentTimeMillis()) {\n                return null;\n            }\n\n            boolean verifyError;\n            byte[] resourceBytes = null;\n            // verify local data\n            if (TextUtils.isEmpty(resourceData.resourceSha1)) {\n                verifyError = true;\n                SonicUtils.log(TAG, Log.INFO, \"get resource data(\" + resourceUrl + \"): resource data is empty.\");\n            } else {\n                String resourcePath = SonicFileUtils.getSonicResourcePath(resourceId);\n                File resourceFile = new File(resourcePath);\n                resourceBytes = SonicFileUtils.readFileToBytes(resourceFile);\n                verifyError = resourceBytes == null || resourceBytes.length <= 0;\n                if (verifyError) {\n                    SonicUtils.log(TAG, Log.ERROR, \"get resource data(\" + resourceUrl + \") error:cache data is null.\");\n                } else {\n                    if (SonicEngine.getInstance().getConfig().VERIFY_CACHE_FILE_WITH_SHA1) {\n                        if (!SonicFileUtils.verifyData(resourceBytes, resourceData.resourceSha1)) {\n                            verifyError = true;\n                            resourceBytes = null;\n                            SonicUtils.log(TAG, Log.ERROR, \"get resource data(\" + resourceUrl + \") error:verify html cache with sha1 fail.\");\n                        } else {\n                            SonicUtils.log(TAG, Log.INFO, \"get resource data(\" + resourceUrl + \") verify html cache with sha1 success.\");\n                        }\n                    } else {\n                        if (resourceData.resourceSize != resourceFile.length()) {\n                            verifyError = true;\n                            resourceBytes = null;\n                            SonicUtils.log(TAG, Log.ERROR, \"get resource data(\" + resourceUrl + \") error:verify html cache with size fail.\");\n                        }\n                    }\n                }\n            }\n            // if the local data is faulty, delete it\n            if (verifyError) {\n                long startTime = System.currentTimeMillis();\n                SonicUtils.removeResourceCache(resourceId);\n                resourceData.reset();\n                SonicUtils.log(TAG, Log.INFO, \"get resource data(\" + resourceUrl + \") :verify error so remove session cache, cost \" + +(System.currentTimeMillis() - startTime) + \"ms.\");\n            }\n            return resourceBytes;\n        }\n\n        public Map<String, List<String>> getResourceCacheHeader(String resourceUrl) {\n            String resourceName = SonicUtils.getMD5(resourceUrl);\n            String headerPath = SonicFileUtils.getSonicResourceHeaderPath(resourceName);\n            return SonicFileUtils.getHeaderFromLocalCache(headerPath);\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/download/SonicDownloadCallback.java",
    "content": "/*\n *\n *  * Tencent is pleased to support the open source community by making VasSonic available.\n *  *\n *  * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *  * 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\n *  *\n *  * https://opensource.org/licenses/BSD-3-Clause\n *  *\n *  * 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.\n *  *\n *  *\n *\n */\n\npackage com.tencent.sonic.sdk.download;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * download callback.\n */\n\npublic interface SonicDownloadCallback {\n    /**\n     * notify the download start.\n     */\n    void onStart();\n\n    /**\n     * notify the download progress.\n     *\n     * @param pro downloaded size\n     * @param total total size\n     */\n    void onProgress(int pro, int total);\n\n    /**\n     * notify download success.\n     *\n     * @param content downloaded content bytes\n     * @param rspHeaders http response headers\n     */\n    void onSuccess(byte[] content, Map<String, List<String>> rspHeaders);\n\n    /**\n     * notify download failed.\n     *\n     * @param errorCode error code\n     */\n    void onError(int errorCode);\n\n    /**\n     * notify download finish. <code>onSuccess</code> or <code>onError</code>\n     */\n    void onFinish();\n\n    /**\n     * an empty implementation of {@link SonicDownloadCallback}\n     */\n    class SimpleDownloadCallback implements SonicDownloadCallback {\n\n        @Override\n        public void onStart() { }\n\n        @Override\n        public void onProgress(int pro, int total) { }\n\n        @Override\n        public void onSuccess(byte[] content, Map<String, List<String>> rspHeaders) { }\n\n        @Override\n        public void onError(int errorCode) { }\n\n        @Override\n        public void onFinish() { }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/download/SonicDownloadClient.java",
    "content": "/*\n *\n *  * Tencent is pleased to support the open source community by making VasSonic available.\n *  *\n *  * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *  * 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\n *  *\n *  * https://opensource.org/licenses/BSD-3-Clause\n *  *\n *  * 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.\n *  *\n *  *\n *\n */\n\npackage com.tencent.sonic.sdk.download;\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport com.tencent.sonic.sdk.SonicConstants;\nimport com.tencent.sonic.sdk.SonicSessionStream;\nimport com.tencent.sonic.sdk.SonicUtils;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.zip.GZIPInputStream;\n\nimport static com.tencent.sonic.sdk.SonicSessionConnection.HTTP_HEAD_FIELD_COOKIE;\nimport static java.net.HttpURLConnection.HTTP_OK;\n\n/**\n * Handles a single HTTP resource download\n *\n */\npublic class SonicDownloadClient implements SonicSessionStream.Callback {\n\n    /**\n     * log filter\n     */\n    public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicDownloadClient\";\n\n    /**\n     * download buffer size\n     */\n    private static final int READ_BUFFER_SIZE = 2048;\n\n    /**\n     * Task which record the download info\n     */\n    public static class DownloadTask {\n\n        /**\n         * download in initiate state.\n         */\n        public static final int STATE_INITIATE = 0;\n\n        /**\n         * download in queueing state.\n         */\n        public static final int STATE_QUEUEING = 1;\n\n        /**\n         * the task is in downloading state.\n         */\n        public static final int STATE_DOWNLOADING = 2;\n\n        /**\n         * the task is in download complete state.\n         */\n        public static final int STATE_DOWNLOADED = 3;\n\n        /**\n         * the task is load from cache, not from network.\n         */\n        public static final int STATE_LOAD_FROM_CACHE = 4;\n\n        /**\n         * url of the resource to be download\n         */\n        public String mResourceUrl;\n\n        /**\n         * ip address instead of host to launch a http request\n         */\n        public String mIpAddress;\n\n        /**\n         * cookie to be set in the http download request\n         */\n        public String mCookie;\n\n        /**\n         * the download request's response headers\n         */\n        public Map<String, List<String>> mRspHeaders;\n\n        /**\n         * the network stream or memory stream or the bridge stream\n         */\n        public InputStream mInputStream;\n\n        /**\n         * the task's download state\n         */\n        public AtomicInteger mState = new AtomicInteger(STATE_INITIATE);\n\n        /**\n         * whether the task's responding resource was intercepted by kernel\n         */\n        public final AtomicBoolean mWasInterceptInvoked = new AtomicBoolean(false);\n\n        /**\n         * list of download callback\n         */\n        public List<SonicDownloadCallback> mCallbacks = new ArrayList<SonicDownloadCallback>();\n    }\n\n    /**\n     * A download connection implement.\n     */\n    private final SonicDownloadConnection mConn;\n\n    /**\n     * the responding download task\n     */\n    private DownloadTask mTask;\n\n    private ByteArrayOutputStream mOutputStream;\n\n    /**\n     * whether the download task is finished or is a bridge stream\n     */\n    private boolean mDownloadFinished = false;\n\n    public SonicDownloadClient(DownloadTask task) {\n        mTask = task;\n        mConn = new SonicDownloadConnection(task.mResourceUrl);\n        mOutputStream = new ByteArrayOutputStream();\n    }\n\n    /**\n     * download the resource and notify download progress\n     *\n     * @return response code\n     */\n    public int download() {\n        onStart();\n\n        int resultCode = mConn.connect();\n\n        if (SonicConstants.ERROR_CODE_SUCCESS != resultCode) {\n            onError(resultCode);\n            return resultCode; // error case\n        }\n\n        int responseCode = mConn.getResponseCode();\n        if (responseCode != HTTP_OK) {\n            onError(responseCode);\n            return responseCode;\n        }\n\n        mTask.mRspHeaders = mConn.getResponseHeaderFields();\n        if (getResponseStream(mTask.mWasInterceptInvoked)) {\n            return SonicConstants.ERROR_CODE_SUCCESS;\n        }\n        return SonicConstants.ERROR_CODE_UNKNOWN;\n    }\n\n    private boolean readServerResponse(AtomicBoolean breakCondition) {\n        BufferedInputStream bufferedInputStream = mConn.getResponseStream();\n        if (null == bufferedInputStream) {\n            SonicUtils.log(TAG, Log.ERROR, \"readServerResponse error: bufferedInputStream is null!\");\n            return false;\n        }\n\n        try {\n            byte[] buffer = new byte[READ_BUFFER_SIZE];\n\n            int total = mConn.connectionImpl.getContentLength();\n            int n = 0, sum = 0;\n            while (((breakCondition == null) || !breakCondition.get()) && -1 != (n = bufferedInputStream.read(buffer))) {\n                mOutputStream.write(buffer, 0, n);\n                sum += n;\n                if (total > 0) {\n                    onProgress(sum, total);\n                }\n            }\n\n            if (n == -1) {\n                mDownloadFinished = true;\n                onSuccess(mOutputStream.toByteArray(), mConn.getResponseHeaderFields());\n            }\n        } catch (Exception e) {\n            SonicUtils.log(TAG, Log.ERROR, \"readServerResponse error:\" + e.getMessage() + \".\");\n            return false;\n        }\n\n        return true;\n    }\n\n    private synchronized boolean getResponseStream(AtomicBoolean breakConditions) {\n        if (readServerResponse(breakConditions)) {\n            BufferedInputStream netStream = mDownloadFinished ? null : mConn.getResponseStream();\n            mTask.mInputStream = new SonicSessionStream(this, mOutputStream, netStream);\n            synchronized (mTask.mWasInterceptInvoked) {\n                mTask.mWasInterceptInvoked.notify();\n            }\n            if (mDownloadFinished) {\n                SonicUtils.log(TAG, Log.INFO, \"sub resource compose a memory stream (\" + mTask.mResourceUrl + \").\");\n            } else {\n                SonicUtils.log(TAG, Log.INFO, \"sub resource compose a bridge stream (\" + mTask.mResourceUrl + \").\");\n            }\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public void onClose(boolean readComplete, ByteArrayOutputStream outputStream) {\n        SonicUtils.log(TAG, Log.INFO, \"sub resource bridge stream on close(\" + mTask.mResourceUrl + \").\");\n        if (!mDownloadFinished) {\n            onSuccess(outputStream.toByteArray(), mConn.getResponseHeaderFields());\n        }\n    }\n\n    private void onStart() {\n        for (SonicDownloadCallback callback : mTask.mCallbacks) {\n            if (callback != null) {\n                callback.onStart();\n            }\n        }\n    }\n\n    private void onProgress(int pro, int total) {\n        for (SonicDownloadCallback callback : mTask.mCallbacks) {\n            if (callback != null) {\n                callback.onProgress(pro, total);\n            }\n        }\n    }\n\n    private void onSuccess(byte[] content, Map<String, List<String>> rspHeaders) {\n        for (SonicDownloadCallback callback : mTask.mCallbacks) {\n            if (callback != null) {\n                callback.onSuccess(content, rspHeaders);\n            }\n        }\n        onFinish();\n    }\n\n    private void onError(int errCode) {\n        for (SonicDownloadCallback callback : mTask.mCallbacks) {\n            if (callback != null) {\n                callback.onError(errCode);\n            }\n        }\n        onFinish();\n    }\n\n    private void onFinish() {\n        for (SonicDownloadCallback callback : mTask.mCallbacks) {\n            if (callback != null) {\n                callback.onFinish();\n            }\n        }\n        mConn.disconnect();\n    }\n\n    public class SonicDownloadConnection {\n        final URLConnection connectionImpl;\n\n        private String url;\n\n        private BufferedInputStream responseStream;\n\n        public SonicDownloadConnection(String url) {\n            this.url = url;\n            connectionImpl = createConnection();\n            initConnection(connectionImpl);\n        }\n\n        URLConnection createConnection() {\n            String currentUrl = url;\n            if (TextUtils.isEmpty(currentUrl)) {\n                return null;\n            }\n\n            URLConnection connection = null;\n            try {\n                URL url = new URL(currentUrl);\n                String originHost = null;\n\n                if (!TextUtils.isEmpty(mTask.mIpAddress)) {\n                    originHost = url.getHost();\n                    url = new URL(currentUrl.replace(originHost, mTask.mIpAddress));\n                    SonicUtils.log(TAG, Log.INFO, \"create UrlConnection with DNS-Prefetch(\" + originHost + \" -> \" + mTask.mIpAddress + \").\");\n                }\n                connection = url.openConnection();\n                if (connection != null) {\n                    if (!TextUtils.isEmpty(originHost)) {\n                        connection.setRequestProperty(\"Host\", originHost);\n                    }\n                }\n            } catch (Throwable e) {\n                if (connection != null) {\n                    connection = null;\n                }\n                SonicUtils.log(TAG, Log.ERROR, \"create UrlConnection fail, error:\" + e.getMessage() + \".\");\n            }\n            return connection;\n        }\n\n        boolean initConnection(URLConnection connection) {\n            if (null != connection) {\n                connection.setConnectTimeout(5000);\n                connection.setReadTimeout(15000);\n\n                connection.setRequestProperty(\"method\", \"GET\");\n                connection.setRequestProperty(\"Accept-Encoding\", \"gzip\");\n                connection.setRequestProperty(\"Accept-Language\", \"zh-CN,zh;\");\n\n                if (!TextUtils.isEmpty(mTask.mCookie)) {\n                    connection.setRequestProperty(HTTP_HEAD_FIELD_COOKIE, mTask.mCookie);\n                }\n                return true;\n            }\n            return false;\n        }\n\n        synchronized int connect() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                HttpURLConnection httpURLConnection = (HttpURLConnection) connectionImpl;\n                try {\n                    httpURLConnection.connect();\n                    return SonicConstants.ERROR_CODE_SUCCESS;\n                } catch (IOException e) {\n                    return SonicConstants.ERROR_CODE_CONNECT_IOE;\n                }\n            }\n            return SonicConstants.ERROR_CODE_UNKNOWN;\n        }\n\n        public void disconnect() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                final HttpURLConnection httpURLConnection = (HttpURLConnection) connectionImpl;\n                try {\n                    httpURLConnection.disconnect();\n                } catch (Exception e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"disconnect error:\" + e.getMessage());\n                }\n            }\n        }\n\n        BufferedInputStream getResponseStream() {\n            if (null == responseStream && null != connectionImpl) {\n                try {\n                    InputStream inputStream = connectionImpl.getInputStream();\n                    if (\"gzip\".equalsIgnoreCase(connectionImpl.getContentEncoding())) {\n                        responseStream = new BufferedInputStream(new GZIPInputStream(inputStream));\n                    } else {\n                        responseStream = new BufferedInputStream(inputStream);\n                    }\n                } catch (Throwable e) {\n                    SonicUtils.log(TAG, Log.ERROR, \"getResponseStream error:\" + e.getMessage() + \".\");\n                }\n            }\n            return responseStream;\n        }\n\n        int getResponseCode() {\n            if (connectionImpl instanceof HttpURLConnection) {\n                try {\n                    return ((HttpURLConnection) connectionImpl).getResponseCode();\n                } catch (IOException e) {\n                    String errMsg = e.getMessage();\n                    SonicUtils.log(TAG, Log.ERROR, \"getResponseCode error:\" + errMsg);\n                    return SonicConstants.ERROR_CODE_CONNECT_IOE;\n                }\n            }\n            return SonicConstants.ERROR_CODE_UNKNOWN;\n        }\n\n        Map<String, List<String>> getResponseHeaderFields() {\n            if (null == connectionImpl) {\n                return null;\n            }\n            return connectionImpl.getHeaderFields();\n        }\n    }\n\n    /**\n     * sub resource download callback.\n     */\n    public static class SubResourceDownloadCallback extends SonicDownloadCallback.SimpleDownloadCallback {\n\n        private String resourceUrl;\n\n        public SubResourceDownloadCallback(String url) {\n            this.resourceUrl = url;\n        }\n\n        @Override\n        public void onStart() {\n            if (SonicUtils.shouldLog(Log.INFO)) {\n                SonicUtils.log(TAG, Log.INFO, \"session start download sub resource, url=\" + resourceUrl);\n            }\n        }\n\n        @Override\n        public void onSuccess(byte[] content, Map<String, List<String>> rspHeaders) {\n            // save cache files\n            String fileName = SonicUtils.getMD5(resourceUrl);\n            SonicUtils.saveResourceFiles(fileName, content, rspHeaders);\n            // save resource data to db\n            SonicUtils.saveSonicResourceData(resourceUrl, SonicUtils.getSHA1(content), content.length);\n\n        }\n\n        @Override\n        public void onError(int errorCode) {\n            if (SonicUtils.shouldLog(Log.INFO)) {\n                SonicUtils.log(TAG, Log.INFO, \"session download sub resource error: code = \" + errorCode + \", url=\" + resourceUrl);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/download/SonicDownloadEngine.java",
    "content": "/*\n *\n *  * Tencent is pleased to support the open source community by making VasSonic available.\n *  *\n *  * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *  * 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\n *  *\n *  * https://opensource.org/licenses/BSD-3-Clause\n *  *\n *  * 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.\n *  *\n *  *\n *\n */\n\npackage com.tencent.sonic.sdk.download;\n\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.os.Message;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport com.tencent.sonic.sdk.SonicConstants;\nimport com.tencent.sonic.sdk.SonicEngine;\nimport com.tencent.sonic.sdk.SonicRuntime;\nimport com.tencent.sonic.sdk.SonicSession;\nimport com.tencent.sonic.sdk.SonicUtils;\nimport com.tencent.sonic.sdk.download.SonicDownloadClient.DownloadTask;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentMap;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * an download initiator\n */\npublic class SonicDownloadEngine implements Handler.Callback {\n\n    /**\n     * log filter\n     */\n    public static final String TAG = SonicConstants.SONIC_SDK_LOG_PREFIX + \"SonicDownloadEngine\";\n\n    /**\n     * message code enqueue:\n     * when downloading tasks more than config number, the task should enqueue for waiting.\n     */\n    private static final int MSG_ENQUEUE = 0;\n\n    /**\n     * message code: one download task is complete and the download queue is free.\n     */\n    private static final int MSG_DEQUEUE = 1;\n\n    private ConcurrentMap<String, DownloadTask> resourceTasks = new ConcurrentHashMap<String, DownloadTask>();\n\n\n    /**\n     * A queue implementation using {@link LinkedHashMap}.\n     * A queue with map function.\n     */\n    private static class SonicDownloadQueue\n            extends LinkedHashMap<String, DownloadTask> {\n\n        synchronized DownloadTask dequeue() {\n            if (values().iterator().hasNext()) {\n                DownloadTask task = values().iterator().next();\n                return remove(task.mResourceUrl);\n            }\n            return null;\n        }\n\n        synchronized void enqueue(DownloadTask task) {\n            if (task != null && !TextUtils.isEmpty(task.mResourceUrl)) {\n                put(task.mResourceUrl, task);\n            }\n        }\n    }\n\n    /**\n     * the download task queue.\n     */\n    private final SonicDownloadQueue mQueue;\n\n    /**\n     * download thread handler.\n     */\n    private Handler mHandler;\n\n    /**\n     * number of downloading tasks.\n     */\n    private AtomicInteger mNumOfDownloadingTask;\n\n    /**\n     * A download cache.\n     */\n    private SonicDownloadCache mCache;\n\n    /**\n     *\n     * @param cache A specific implementation of {@link SonicDownloadCache}\n     */\n    public SonicDownloadEngine(SonicDownloadCache cache) {\n        mQueue = new SonicDownloadQueue();\n        HandlerThread queueThread = new HandlerThread(\"Download-Thread\");\n        queueThread.start();\n        mHandler = new Handler(queueThread.getLooper(), this);\n\n        mNumOfDownloadingTask = new AtomicInteger(0);\n        mCache = cache;\n    }\n\n    @Override\n    public boolean handleMessage(Message msg) {\n        switch (msg.what) {\n            case MSG_ENQUEUE: {\n                DownloadTask task = (DownloadTask) msg.obj;\n                mQueue.enqueue(task);\n                task.mState.set(DownloadTask.STATE_QUEUEING);\n                SonicUtils.log(TAG, Log.INFO, \"enqueue sub resource(\" + task.mResourceUrl + \").\");\n                break;\n            }\n            case MSG_DEQUEUE: {\n                if (!mQueue.isEmpty()) {\n                    DownloadTask task = mQueue.dequeue();\n                    startDownload(task);\n                    SonicUtils.log(TAG, Log.INFO, \"dequeue sub resource(\" + task.mResourceUrl + \").\");\n                }\n                break;\n            }\n            default:\n                break;\n        }\n        return false;\n    }\n\n    /**\n     * start downloading one resource.\n     * if the responding cache exists and isn't expire, will use the cache directly and won't launch a http request;\n     * if the number of downloading tasks is bigger than config, the task will be delayed before downloading pool is free.\n     *\n     * @param resourceUrl the resource's url\n     * @param ipAddress if dns prefetch the ip address, will use the ip instead of host\n     * @param cookie set the cookie for the download http request\n     * @param callback a callback used for notify the download progress and result\n     * @return the download task info\n     */\n    public DownloadTask download(String resourceUrl, String ipAddress, String cookie, SonicDownloadCallback callback) {\n        if (TextUtils.isEmpty(resourceUrl)) {\n            return null;\n        }\n\n        synchronized (mQueue) {\n            if (mQueue.containsKey(resourceUrl)) {\n                SonicUtils.log(TAG, Log.INFO, \"sub resource download task has been in queue (\" + resourceUrl + \").\");\n                return mQueue.get(resourceUrl);\n            }\n        }\n\n        final DownloadTask task = new DownloadTask();\n        task.mResourceUrl = resourceUrl;\n        task.mCallbacks.add(callback);\n        task.mCallbacks.add(new SonicDownloadCallback.SimpleDownloadCallback() {\n            @Override\n            public void onFinish() {\n                task.mState.set(DownloadTask.STATE_DOWNLOADED);\n                mHandler.sendEmptyMessage(MSG_DEQUEUE);\n            }\n        });\n\n        // query cache\n        byte[] resourceBytes = mCache.getResourceCache(resourceUrl);\n        if (resourceBytes != null) {\n            task.mInputStream = new ByteArrayInputStream(resourceBytes);\n            task.mRspHeaders = mCache.getResourceCacheHeader(resourceUrl);\n            task.mState.set(DownloadTask.STATE_LOAD_FROM_CACHE);\n            SonicUtils.log(TAG, Log.INFO, \"load sub resource(\" + resourceUrl + \") from cache.\");\n            return task;\n        }\n\n        // no cache then start download\n        task.mIpAddress = ipAddress;\n        task.mCookie = cookie;\n        if (mNumOfDownloadingTask.get() < SonicEngine.getInstance().getConfig().SONIC_MAX_NUM_OF_DOWNLOADING_TASK) {\n            startDownload(task);\n        } else {\n            Message enqueueMsg = mHandler.obtainMessage(MSG_ENQUEUE, task);\n            mHandler.sendMessage(enqueueMsg);\n        }\n        return task;\n    }\n\n    /**\n     * dispatch the download task to really download.\n     *\n     * @param task download task\n     */\n    private void startDownload(final DownloadTask task) {\n        SonicEngine.getInstance().getRuntime().postTaskToSessionThread(new Runnable() {\n            @Override\n            public void run() {\n                mNumOfDownloadingTask.incrementAndGet();\n                task.mState.set(DownloadTask.STATE_DOWNLOADING);\n                SonicDownloadClient engine = new SonicDownloadClient(task);\n                engine.download();\n            }\n        });\n    }\n\n    /**\n     * When the webview initiates a sub resource interception, the client invokes this method to retrieve the data\n     *\n     * @param url The url of sub resource\n     * @param session current sonic session\n     * @return Return the data to kernel\n     */\n    public Object onRequestSubResource(String url, SonicSession session) {\n        if (SonicUtils.shouldLog(Log.INFO)) {\n            SonicUtils.log(TAG, Log.INFO, \"session onRequestSubResource: resource url(\" + url + \").\");\n        }\n\n        InputStream inputStream = null;\n        Map<String, List<String>> headers = null;\n        if (resourceTasks.containsKey(url)) {\n            DownloadTask subRes = resourceTasks.get(url);\n            subRes.mWasInterceptInvoked.set(true);\n            if (subRes.mState.get() == DownloadTask.STATE_INITIATE\n                    || subRes.mState.get() == DownloadTask.STATE_QUEUEING) {\n                return null;\n            } else {\n                if (subRes.mInputStream == null) {\n                    synchronized (subRes.mWasInterceptInvoked) {\n                        try {\n                            subRes.mWasInterceptInvoked.wait(3 * 1000);\n                        } catch (InterruptedException e) {\n                            SonicUtils.log(TAG, Log.ERROR, \"session onRequestSubResource error: \" + e.getMessage());\n                        }\n                    }\n                }\n                if (subRes.mInputStream == null) {\n                    return null;\n                }\n                inputStream = subRes.mInputStream;\n                headers = subRes.mRspHeaders;\n            }\n        } else {\n            return null;\n        }\n\n        Object webResourceResponse;\n        if (!session.isDestroyedOrWaitingForDestroy()) {\n            String mime = SonicUtils.getMime(url);\n            Map<String, String> filteredHeaders = SonicUtils.getFilteredHeaders(headers);\n            webResourceResponse = SonicEngine.getInstance().getRuntime().createWebResourceResponse(mime,\n                    session.getCharsetFromHeaders(filteredHeaders), inputStream, filteredHeaders);\n        } else {\n            webResourceResponse = null;\n            SonicUtils.log(TAG, Log.ERROR, \"session onRequestSubResource error: session is destroyed!\");\n        }\n        return webResourceResponse;\n    }\n\n    /**\n     * preload the sub resource in the \"sonic-link\" header.\n     * @param preloadLinks The links which need to be preloaded.\n     */\n    public void addSubResourcePreloadTask(List<String> preloadLinks) {\n\n        SonicRuntime runtime = SonicEngine.getInstance().getRuntime();\n        for (final String link : preloadLinks) {\n            if (!resourceTasks.containsKey(link)) {\n                resourceTasks.put(link,\n                        download(link,\n                                runtime.getHostDirectAddress(link),\n                                runtime.getCookie(link),\n                                new SonicDownloadClient.SubResourceDownloadCallback(link)\n                        )\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-android/sdk/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">sdk</string>\n</resources>\n"
  },
  {
    "path": "sonic-android/settings.gradle",
    "content": "include ':sample', ':sdk'\n"
  },
  {
    "path": "sonic-iOS/.gitignore",
    "content": "tignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData/\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata/\n\n## Other\n*.moved-aside\n*.xccheckout\n*.xcscmblueprint\n\n## Obj-C/Swift specific\n*.hmap\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# Pods/\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the\n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\n\n# Code Injection\n#\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\niOSInjectionProject/\n\n"
  },
  {
    "path": "sonic-iOS/README.md",
    "content": "## Getting started with iOS\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n### 3.0.0 support!\nTo integrate VasSonic into your Xcode project using CocoaPods, specify it in your Podfile:\n\n```lua\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '8.0'\n\ntarget 'TargetName' do\n    pod 'VasSonic', '3.0.0'\nend\n```\n\n### support cocoapods \nTo integrate VasSonic into your Xcode project using CocoaPods, specify it in your Podfile:\n\n```lua\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '8.0'\n\ntarget 'TargetName' do\n    pod 'VasSonic', '3.0.0'\nend\n```\n\n### Step 1: import and declare\nBuild Sonic.framework for each platform or using the cocoapods;\n\nAdd Sonic.framework to dependency in your main project.\nThen ```@import Sonic``` and register ```SonicURLProtocol``` :\n\nObjective-C\n```Objective-C\n[NSURLProtocol registerClass:[SonicURLProtocol class]];\n\n@interface SonicWebViewController : UIViewController<SonicSessionDelegate,UIWebViewDelegate>\n```\nSwift\n```Swift\nURLProtocol.registerClass(SonicURLProtocol.self)\n\nclass SonicWebViewController : UIViewController, UIWebViewDelegate, SonicSessionDelegate\n```\n\n### Step 2: Implement ```SonicSessionDelegate```\n\nObjective-C\n```Objective-C\n#pragma mark - Sonic Session Delegate\n/*\n * Call back when Sonic will send request.\n */\n- (void)sessionWillRequest:(SonicSession *)session\n{\n    //This callback can be used to set some information, such as cookie and UA.\n}\n/*\n * Call back when Sonic require WebView to reload, e.g template changed or error occurred. \n */\n- (void)session:(SonicSession *)session requireWebViewReload:(NSURLRequest *)request\n{\n    [self.webView loadRequest:request];\n}\n```\nSwift\n\n```Swift\n// MARK: - SonicSessionDelegate\n/*\n * Call back when Sonic will send request.\n */\nfunc sessionWillRequest(_ session: SonicSession!)\n{\n    // This callback can be used to set some information, such as cookie and UA.\n}\n/*\n * Call back when Sonic require WebView to reload, e.g template changed or error occurred. \n */\nfunc session(_ session: SonicSession!, requireWebViewReload request: URLRequest!) {\n{\n    self.webView.loadRequest(request)\n}\n```\n\n### Step 3: Use Sonic in WebView ViewController\n\nObjective-C\n```Objective-C\n- (instancetype)initWithUrl:(NSString *)aUrl\n{\n    if (self = [super init]) {\n        \n        self.url = aUrl;\n        \n        //Create a Sonic session with url.\n        [[SonicClient sharedClient] createSessionWithUrl:self.url withWebDelegate:self];\n    }\n    return self;\n}\n/*\n * Send request with Sonic property immediately after the WebView initialization.\n */\n- (void)loadView\n{\n    [super loadView];\n    \n    self.webView = [[UIWebView alloc]initWithFrame:self.view.bounds];\n    self.webView.delegate = self;\n    self.view = self.webView;\n    \n    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];\n    \n    /*\n     * If SonicSession is not null, Sonic uses custom SonicWebRequest instead of original network request. \n     */\n    if ([[SonicClient sharedClient] sessionWithWebDelegate:self]) {\n        [self.webView loadRequest:sonicWebRequest(request)];\n    }else{\n        [self.webView loadRequest:request];\n    }\n}\n```\n\nSwift\n```Swift\nfunc initWithUrl(aUrl: String) -> SonicWebViewController {\n    if self = super.init() {\n        self.url = aUrl\n        \n        //Create a Sonic session with url.\n        SonicClient.shared().createSession(withUrl: self.url, withWebDelegate: self)\n    }\n    \n    return self\n}\n/*\n * Send request with Sonic property immediately after the WebView initialization.\n */\noverride func loadView() {\n    super.loadView()\n    \n    self.webView = UIWebView.init(frame: self.view.bounds)\n    self.webView.delegate = self\n    self.view = self.webView\n    \n    let request = URLRequest.init(url: URL.init(string: self.url))\n    \n    /*\n     * If SonicSession is not null, Sonic uses custom SonicWebRequest instead of original network request.\n     */\n    if SonicClient.shared().session(withWebDelegate: self) != nil {\n        self.webView.loadRequest(sonicWebRequest(request))\n    }\n    else {\n        self.webView.loadRequest(request)\n    }\n}\n```\n\n### Step 4: Interacts with websites by JavaScript callback.\n\nObjective-C\n```Objective-C\n\n- (void)getDiffData:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n{\n    /*\n     * ViewController which sends the Sonic request and return result through callback. \n     */\n    [[SonicClient sharedClient] sonicUpdateDiffDataByWebDelegate:self.owner completion:^(NSDictionary *result) {\n       \n        /*\n         * Return the result.\n         */\n        NSData *json = [NSJSONSerialization dataWithJSONObject:result options:NSJSONWritingPrettyPrinted error:nil];\n        NSString *jsonStr = [[NSString alloc]initWithData:json encoding:NSUTF8StringEncoding];\n        \n        JSValue *callback = self.owner.jscontext.globalObject;\n        [callback invokeMethod:@\"getDiffDataCallback\" withArguments:@[jsonStr]];\n        \n    }];\n}\n```\n\nSwift\n```Swift\n\nfunc getDiffData(option: Dictionary<String, Any>, withCallBack jscallback: JSValue) {\n    /*\n     * ViewController which sends the Sonic request and return result through callback.\n     */\n    SonicClient.shared().sonicUpdateDiffData(byWebDelegate: self.owner) { (result) in\n        guard let result = result else {return}\n        \n        /*\n         * Return the result.\n         */\n        guard let json = try? JSONSerialization.data(withJSONObject: result, options: JSONSerialization.WritingOptions.prettyPrinted) else {return}\n        \n        guard let jsonStr = String.init(data: json, encoding: String.Encoding.utf8) else {return}\n        \n        guard let callback = self.owner.jscontext.globalObject else {return}\n        \n        callback.invokeMethod(\"getDiffDataCallback\", withArguments: [jsonStr])\n    }\n}\n```\n\n### Step 5: Remove sonic session.\n\nObjective-C\n```Objective-C\n\n- (void)dealloc\n{\n[[SonicClient sharedClient] removeSessionWithWebDelegate:self];\n}\n```\n\nSwift\n```Swift\n\ndeinit {\n    SonicClient.shared().removeSession(withWebDelegate: self)\n}\n```\n\n## Support\nAny problem?\n\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-iOS/SonicSample).\n2. Contact us for help.\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n\n\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicCache.h",
    "content": "//\n//  SonicCache.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicCacheItem.h\"\n#import \"SonicConstants.h\"\n\n/**\n * Manage the memory caches and file cache for all sonic sessions.\n */\n@interface SonicCache : NSObject\n\n/**\n * Return an cache manage instance,it can create or update memory cache and file.\n * cache for each sonic session.\n */\n+ (SonicCache *)shareCache;\n\n/**\n * Success for YES, faild for NO.\n */\n- (BOOL)setupCacheDirectory;\n\n/**\n * Clear memory and file cache.\n */\n- (void)clearAllCache;\n\n/**\n * Delete memory and file cache.\n \n * @param sessionID  an session id to find the memory cache item.\n */\n- (void)removeCacheBySessionID:(NSString *)sessionID;\n\n/**\n * Check if sever disable sonic request.\n \n * @param sessionID  an session id to find saved config params.\n * @result Return if need disable sonic mode for web request.\n */\n- (BOOL)isServerDisableSonic:(NSString *)sessionID;\n\n/**\n * Set a timestamp to record server disable sonic request start.\n * @param sessionID  an session id to find saved config params.\n */\n- (void)saveServerDisableSonicTimeNow:(NSString *)sessionID;\n\n/**\n * Remove the recorded timestamp to enable sonic request.\n \n * @param sessionID  an session id to find saved config params.\n */\n- (void)removeServerDisableSonic:(NSString *)sessionID;\n\n/**\n * Return the dynamic data which split from HTML.\n \n * @param sessionID  an session id to find memory cache item.\n * @result return the dynamic data from memory cache item,\n * if the memory cache item doesn't exist, the create and read data,\n * from file cache data.\n \n */\n- (NSDictionary *)dynamicDataBySessionID:(NSString *)sessionID;\n\n/**\n * Return the template string which split from HTML.\n \n * @param sessionID  an session id to find memory cache item.\n * @result return template string from memory cache item,\n * if the memory cache item doesn't exist, the create and read data,\n * from file cache data.\n \n */\n- (NSString *)templateStringBySessionID:(NSString *)sessionID;\n\n/**\n * Check if there is memory cache or file cache.\n \n * @param sessionID an session id to find memory cache item.\n * @result If there is not exist an memory cache item and file cache data not exist\n * either, then return NO.\n */\n- (BOOL)isFirstLoad:(NSString *)sessionID;\n\n/**\n * @brief Generate the new HTML cache with server upate \"jsonData\".\n \n * @param jsonData The server update data.\n * @param headers the response headers from sonic session.\n * @param url the sonic URL which use to create sessionID for cache item name.\n * @result An cache item which has finish update dynamic data and HTML document cache.\n */\n- (SonicCacheItem *)updateWithJsonData:(NSData *)jsonData\n                        withHtmlString:(NSString *)htmlString\n                   withResponseHeaders:(NSDictionary *)headers\n                               withUrl:(NSString *)url;\n\n/**\n * Save all relation datas\n */\n- (SonicCacheItem *)saveHtmlString:(NSString *)htmlString\n                    templateString:(NSString *)templateString\n                       dynamicData:(NSDictionary *)dataDict\n                   responseHeaders:(NSDictionary *)headers\n                           withUrl:(NSString *)url;\n\n/**\n * Update cache expire time from response headers with session id\n */\n- (void)updateCacheExpireTimeWithResponseHeaders:(NSDictionary *)headers withSessionID:(NSString *)sessionID;\n\n/**\n * Save the response headers\n */\n- (void)saveResponseHeaders:(NSDictionary *)headers withSessionID:(NSString *)sessionID;\n\n/**\n * @brief Get the memory cache item by sessionID.\n * If there no memory cache exist,then create an new item\n           If there has file cache exist,then read require data into memory.\n \n * @param sessionID  an session id to find memory cache item.\n * @result If cache is not exist then return nil.\n */\n- (SonicCacheItem *)cacheForSession:(NSString *)sessionID;\n\n/**\n * Get the file cache update timestamp.\n */\n- (NSString *)localRefreshTimeBySessionID:(NSString *)sessionID;\n\n#pragma mark - Sub resource load\n\n/**\n * Save resource data and configuration information by Resource ID.\n */\n- (BOOL)saveSubResourceData:(NSData *)data withConfig:(NSDictionary *)config withResponseHeaders:(NSDictionary *)responseHeader withSessionID:(NSString *)sessionID;\n\n/**\n * Returns the binary data of the resource.\n */\n- (NSData *)resourceCacheWithSessionID:(NSString *)sessionID;\n\n/**\n * Return the resource's response header field information.\n */\n- (NSDictionary *)responseHeadersWithSessionID:(NSString *)sessionID;\n\n/**\n * Return resource configuration information.\n */\n- (NSDictionary *)resourceConfigWithSessionID:(NSString *)sessionID;\n\n/**\n * Clear the cache with the resource ID.\n */\n- (BOOL)clearResourceWithSessionID:(NSString *)sessionID;\n\n/**\n * Resource save file operation queue.\n */\n+ (NSOperationQueue *)subResourceQueue;\n\n/**\n * Check file cache size, we keep max cache size 30MB\n */\n- (void)checkAndTrimCache;\n\n/**\n * Check and update version\n */\n- (BOOL)upgradeSonicVersion;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicCache.m",
    "content": "//\n//  SonicCache.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicCache.h\"\n#import \"SonicEngine.h\"\n#import \"SonicUtil.h\"\n#import <UIKit/UIKit.h>\n#import <CommonCrypto/CommonDigest.h>\n#import \"SonicDatabase.h\"\n#import \"SonicEventStatistics.h\"\n\n#define SonicRootCacheDirName      @\"SonicCache\"\n\n#define SonicRootCacheConfigDirName @\"SonicConfigCache\"\n\n#define SonicResourceConfigDirName  @\"SonicResourceConfig\"\n\n#define SonicResourceCacheDirName   @\"SonicResourceCache\"\n\n#define kSonicRootCacheTrimTimestampUDF     @\"kSonicRootCacheTrimTimestampUDF\"\n\n#define kSonicResourceCacheTrimTimestampUDF @\"kSonicResourceCacheTrimTimestampUDF\"\n\ntypedef NS_ENUM(NSUInteger, SonicCacheType) {\n    /*\n     * template\n     */\n    SonicCacheTypeTemplate,\n    /*\n     * html\n     */\n    SonicCacheTypeHtml,\n    /*\n     * dynamic data\n     */\n    SonicCacheTypeData,\n    /*\n     * config\n     */\n    SonicCacheTypeConfig,\n    /*\n     * response header\n     */\n    SonicCacheTypeResponseHeader,\n};\n\n@interface SonicCache ()\n\n@property (nonatomic,readonly)NSString *rootCachePath;\n\n@property (nonatomic,readonly)NSString *rootResourceCachePath;\n\n@property (nonatomic,readonly)NSString *rootResourceConfigCachePath;\n\n/*\n * memory cache item manage lock\n */\n@property (nonatomic,retain)NSRecursiveLock *lock;\n/*\n * cache items\n */\n@property (nonatomic,retain)NSMutableDictionary *memoryCache;\n/*\n * the max cache item count in memory\n */\n@property (nonatomic,assign)NSInteger            maxCacheCount;\n/*\n * save the key recently used\n */\n@property (nonatomic,retain)NSMutableArray      *recentlyUsedKey;\n/*\n * save the server disable/enable sonic request timestamp\n */\n@property (nonatomic,retain)NSMutableDictionary *offlineCacheTimeCfg;\n\n@property (nonatomic,retain)SonicDatabase *database;\n\n@end\n\n@implementation SonicCache\n\n+ (SonicCache *)shareCache\n{\n    static SonicCache *_cacheInstance = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _cacheInstance = [[self alloc]init];\n    });\n    return _cacheInstance;\n}\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        [self setupInit];\n    }\n    return self;\n}\n\n+ (NSOperationQueue *)fileQueue\n{\n    static NSOperationQueue *_fileQueue = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _fileQueue = [NSOperationQueue new];\n        _fileQueue.qualityOfService = NSQualityOfServiceDefault;\n        _fileQueue.name = @\"Sonic.File.Cache\";\n        _fileQueue.maxConcurrentOperationCount = 1;\n    });\n    return _fileQueue;\n}\n\n+ (NSOperationQueue *)subResourceQueue\n{\n    static NSOperationQueue *_fileQueue = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _fileQueue = [NSOperationQueue new];\n        _fileQueue.qualityOfService = NSQualityOfServiceDefault;\n        _fileQueue.name = @\"Sonic.Resource.Cache\";\n        _fileQueue.maxConcurrentOperationCount = 1;\n    });\n    return _fileQueue;\n}\n\n- (void)setupInit\n{\n    self.maxCacheCount = [SonicEngine sharedEngine].configuration.maxMemroyCacheItemCount;\n    self.lock = [NSRecursiveLock new];\n    self.memoryCache = [NSMutableDictionary dictionaryWithCapacity:self.maxCacheCount];\n    self.recentlyUsedKey = [NSMutableArray arrayWithCapacity:self.maxCacheCount];\n    \n    //setup cache dir\n    [self setupCacheDirectory];\n    [self setupSubResourceCacheDirectory];\n    \n    //read server disable sonic request timestamps\n    [self setupCacheOfflineTimeCfgDict];\n    \n    //setup database\n    [self setupDatabase];\n    \n    //release the memory cache when did recieved memory warning\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(memoryWarningClearCache) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n}\n\n- (void)setupDatabase\n{\n    NSString *configPath = [self createDirectoryIfNotExist:self.rootCachePath withSubPath:SonicRootCacheConfigDirName];\n    NSString *dbPath = [configPath stringByAppendingPathComponent:SonicCacheDatabase];\n    SonicDatabase *tDatabase = [[SonicDatabase alloc]initWithPath:dbPath];\n    self.database = tDatabase;\n    [tDatabase release];\n}\n\n- (void)memoryWarningClearCache\n{\n    [self clearMemoryCache];\n}\n\n- (void)clearMemoryCache\n{\n    //we need clear or create memory cache in sonic queue\n    dispatchToSonicSessionQueue(^{\n        [self.lock lock];\n        [self.memoryCache removeAllObjects];\n        [self.recentlyUsedKey removeAllObjects];\n        [self.lock unlock];\n    });\n}\n\n- (void)clearAllCache\n{\n    //we need clear or setup file in file queue\n    dealInFileQueue(^{\n        //close database\n        self.database = nil;\n        [SonicFileManager removeItemAtPath:_rootCachePath error:nil];\n        [self setupCacheDirectory];\n        //rebuild database\n        [self setupDatabase];\n    });\n    \n    [self clearResourceCache];\n    [self clearMemoryCache];\n}\n\n- (void)removeCacheBySessionID:(NSString *)sessionID\n{\n    //we need clear or setup file in file queue\n    dealInFileQueue(^{\n        NSString *fileDir = [self sessionSubCacheDir:sessionID];\n        [SonicFileManager removeItemAtPath:fileDir error:nil];\n        [self.database clearWithSessionID:sessionID];\n    });\n    \n    //we need clear or create memory cache in sonic queue\n    dispatchToSonicSessionQueue(^{\n        [self.lock lock];\n        [self.memoryCache removeObjectForKey:sessionID];\n        [self.recentlyUsedKey removeObject:sessionID];\n        [self.lock unlock];\n    });\n}\n\n- (BOOL)isFirstLoad:(NSString *)sessionID\n{\n    if (sessionID.length == 0) {\n        return YES;\n    }\n    \n    SonicCacheItem *session = [self cacheForSession:sessionID];\n    \n    return session.hasLocalCache? NO:YES;\n}\n\n- (BOOL)isServerDisableSonic:(NSString *)sessionID\n{\n    NSNumber *disableStartTime = [self.offlineCacheTimeCfg objectForKey:sessionID];\n    if (!disableStartTime) {\n        return NO;\n    }\n    \n    NSTimeInterval lastTime = [disableStartTime doubleValue];\n    NSTimeInterval timeNow = [[NSDate date] timeIntervalSince1970];\n    \n    return timeNow - lastTime < [SonicEngine sharedEngine].configuration.cacheOfflineDisableTime;\n}\n\n- (void)setupCacheOfflineTimeCfgDict\n{\n    NSString *cfgPath = [_rootCachePath stringByAppendingPathComponent:SonicCacheOfflineDisableList];\n    \n    if (![SonicFileManager fileExistsAtPath:cfgPath]) {\n        self.offlineCacheTimeCfg = [NSMutableDictionary dictionary];\n    }else{\n        NSDictionary *cacheDict = [NSDictionary dictionaryWithContentsOfFile:cfgPath];\n        self.offlineCacheTimeCfg = [NSMutableDictionary dictionaryWithDictionary:cacheDict];\n    }\n}\n\n- (void)saveServerDisableSonicTimeNow:(NSString *)sessionID\n{\n    \n    [self removeCacheBySessionID:sessionID];\n    \n    NSNumber *timeNow = @([[NSDate date] timeIntervalSince1970]);\n    \n    [self.offlineCacheTimeCfg setObject:timeNow forKey:sessionID];\n    \n    NSString *cfgPath = [_rootCachePath stringByAppendingPathComponent:SonicCacheOfflineDisableList];\n\n    dealInFileQueue(^{\n        [self.offlineCacheTimeCfg writeToFile:cfgPath atomically:YES];\n    });\n}\n\n- (void)removeServerDisableSonic:(NSString *)sessionID\n{\n    if (![self.offlineCacheTimeCfg objectForKey:sessionID]) {\n        return;\n    }\n    \n    [self.offlineCacheTimeCfg removeObjectForKey:sessionID];\n    \n    NSString *cfgPath = [_rootCachePath stringByAppendingPathComponent:SonicCacheOfflineDisableList];\n\n    dealInFileQueue(^{\n        [self.offlineCacheTimeCfg writeToFile:cfgPath atomically:YES];\n    });\n}\n\n#pragma mark - Memory Cache\n\n- (SonicCacheItem *)cacheForSession:(NSString *)sessionID\n{\n    SonicCacheItem *cacheItem = nil;\n    \n    [self.lock lock];\n    \n    cacheItem = self.memoryCache[sessionID];\n    \n    if (!cacheItem) {\n        cacheItem = [[SonicCacheItem alloc] initWithSessionID:sessionID];\n        [self memoryCacheItem:cacheItem];\n        [self setupCacheItemFromFile:cacheItem];\n        [cacheItem release];\n    }\n    \n    [self.lock unlock];\n    \n    return cacheItem;\n}\n\n- (void)memoryCacheItem:(SonicCacheItem *)cacheItem\n{\n    [self.memoryCache setObject:cacheItem forKey:cacheItem.sessionID];\n\n    NSUInteger index = [self.recentlyUsedKey indexOfObject:cacheItem.sessionID];\n    \n    if (index != NSNotFound) {\n        [self.recentlyUsedKey removeObjectAtIndex:index];\n    }\n    \n    [self.recentlyUsedKey insertObject:cacheItem.sessionID atIndex:0];\n    \n    if (self.recentlyUsedKey.count > self.maxCacheCount) {\n        NSString *lastUsedKey = [self.recentlyUsedKey lastObject];\n        [self.memoryCache removeObjectForKey:lastUsedKey];\n        [self.recentlyUsedKey removeObject:lastUsedKey];\n    }\n}\n\n#pragma mark - 接口\n\n- (SonicCacheItem *)updateWithJsonData:(NSData *)jsonData\n                        withHtmlString:(NSString *)htmlString\n                   withResponseHeaders:(NSDictionary *)headers\n                         withUrl:(NSString *)url\n{\n    NSString *sessionID = sonicSessionID(url);\n\n    if (!jsonData) {\n        return nil;\n    }\n    \n    NSError *err = nil;\n    NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&err];\n    if (err) {\n        return nil;\n    }\n    \n    SonicCacheItem *cacheItem = [self cacheForSession:sessionID];\n    \n    //dynamic data and template string should read from file so can be used\n    if (!cacheItem.dynamicData) {\n        cacheItem.dynamicData = [NSDictionary dictionaryWithContentsOfFile:[self filePathWithType:SonicCacheTypeData sessionID:sessionID]];\n    }\n    if (!cacheItem.templateString) {\n        cacheItem.templateString = [[[NSString alloc]initWithData:[NSData dataWithContentsOfFile:[self filePathWithType:SonicCacheTypeTemplate sessionID:sessionID]] encoding:NSUTF8StringEncoding]autorelease];\n    }\n    \n    NSMutableDictionary *dynamicData = [NSMutableDictionary dictionaryWithDictionary:cacheItem.dynamicData];\n    NSDictionary *mergeResult = [SonicUtil mergeDynamicData:dataDict[kSonicDataFieldName] withOriginData:dynamicData];\n    \n    if ([mergeResult[@\"diff\"] count] == 0) {\n        NSMutableDictionary *tmpResult = [[mergeResult mutableCopy]autorelease];\n        [tmpResult setObject:dataDict[kSonicDataFieldName] forKey:@\"diff\"];\n        mergeResult = tmpResult;\n    }\n    \n    NSData *htmlData = nil;\n    if (htmlString.length > 0) {\n        htmlData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];\n    }else{\n        //merge new dynamic data with template string to create new HTML cache\n        NSMutableString *html = [NSMutableString stringWithString:cacheItem.templateString];\n        for (NSString *key in dynamicData.allKeys) {\n            [html replaceOccurrencesOfString:key withString:dynamicData[key] options:NSCaseInsensitiveSearch range:NSMakeRange(0, html.length)];\n        }\n        htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];\n    }\n    \n    cacheItem.dynamicData = dynamicData;\n    cacheItem.htmlData = htmlData;\n    cacheItem.diffData = mergeResult[@\"diff\"];\n    NSMutableDictionary *config = [NSMutableDictionary dictionaryWithDictionary:[self createConfigFromResponseHeaders:headers]];\n    NSString *sha1 = dataDict[@\"html-sha1\"];\n    if (sha1.length == 0) {\n        sha1 = @\"\";\n        NSString *errMsg = @\"DataUpdateMode while html-sha1 not exist!\";\n#if DEBUG\n        NSAssert(sha1.length>0, errMsg);\n#endif\n        SonicLogEvent(@\"%@\",errMsg);\n    }\n    [config setObject:sha1 forKey:kSonicSha1];\n    cacheItem.config = config;\n    NSDictionary *filterResponseHeaders = [self filterResponseHeaders:headers];\n    cacheItem.cacheResponseHeaders = filterResponseHeaders;\n    \n    //event\n    NSString *htmlLog = [[[NSString alloc]initWithData:cacheItem.htmlData encoding:NSUTF8StringEncoding]autorelease];\n    NSDictionary *diff = cacheItem.diffData ? cacheItem.diffData:[NSDictionary dictionary];\n    NSString *tempLog = cacheItem.templateString.length > 0? cacheItem.templateString:@\"\";\n    NSDictionary *dynamic = cacheItem.dynamicData? cacheItem.dynamicData:[NSDictionary dictionary];\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionDidSaveCache withEventInfo:@{\n                                                                                                              @\"htmlString\":htmlLog,\n                                                                                                              @\"template\":tempLog,\n                                                                                                              @\"dynamic\":dynamic,\n                                                                                                              @\"diff\":diff,\n                                                                                                              @\"sessionID\":cacheItem.sessionID,\n                                                                                                              @\"url\":url\n                                                                                                              }];\n    \n    \n    dealInFileQueue(^{\n        [self saveHtmlData:htmlData withConfig:config withTemplate:cacheItem.templateString dynamicData:dynamicData withResponseHeaders:filterResponseHeaders withSessionID:sessionID isUpdate:YES];\n    });\n    \n    return cacheItem;\n}\n\n- (SonicCacheItem *)saveHtmlString:(NSString *)htmlString\n                    templateString:(NSString *)templateString\n                       dynamicData:(NSDictionary *)dataDict\n                   responseHeaders:(NSDictionary *)headers\n                           withUrl:(NSString *)url\n{\n    NSString *sessionID = sonicSessionID(url);\n    \n    if (!htmlString || !templateString || headers.count == 0 || sessionID.length == 0) {\n        return nil;\n    }\n    \n    NSData *htmlData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];\n    SonicCacheItem *cacheItem = [self cacheForSession:sessionID];\n    cacheItem.htmlData = htmlData;\n    cacheItem.dynamicData = dataDict;\n    cacheItem.templateString = templateString;\n    NSMutableDictionary *config = [NSMutableDictionary dictionaryWithDictionary:[self createConfigFromResponseHeaders:headers]];\n    NSString *sha1 = getDataSha1(cacheItem.htmlData);\n    [config setObject:sha1 forKey:kSonicSha1];\n    cacheItem.config = config;\n    NSDictionary *filterResponseHeaders = [self filterResponseHeaders:headers];\n    cacheItem.cacheResponseHeaders = filterResponseHeaders;\n    \n    //event\n    NSString *htmlLog = [[[NSString alloc]initWithData:cacheItem.htmlData encoding:NSUTF8StringEncoding]autorelease];\n    NSDictionary *diff = cacheItem.diffData ? cacheItem.diffData:[NSDictionary dictionary];\n    NSString *tempLog = cacheItem.templateString.length > 0? cacheItem.templateString:@\"\";\n    NSDictionary *dynamic = cacheItem.dynamicData? cacheItem.dynamicData:[NSDictionary dictionary];\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionDidSaveCache withEventInfo:@{\n                                                                                                              @\"htmlString\":htmlLog,\n                                                                                                              @\"template\":tempLog,\n                                                                                                              @\"dynamic\":dynamic,\n                                                                                                              @\"diff\":diff,\n                                                                                                              @\"sessionID\":cacheItem.sessionID,\n                                                                                                              @\"url\":url\n                                                                                                              }];\n    dealInFileQueue(^{\n        [self saveHtmlData:htmlData withConfig:config withTemplate:templateString dynamicData:dataDict withResponseHeaders:filterResponseHeaders withSessionID:sessionID isUpdate:NO];\n    });\n    \n    return cacheItem;\n}\n\n- (NSString *)getSonicHeaderETagWithHeaders:(NSDictionary *)headers\n{\n    NSString *keyETag = [headers objectForKey:[SonicHeaderKeyCustomeETag lowercaseString]];\n    if (keyETag && [keyETag isKindOfClass:[NSString class]] && keyETag.length > 0) {\n        // do nothing\n    } else {\n        keyETag = [SonicHeaderKeyETag lowercaseString];\n    }\n    \n    return [headers objectForKey:keyETag];\n}\n\n- (NSDictionary *)createConfigFromResponseHeaders:(NSDictionary *)headers\n{\n    //Etag,template-tag\n    NSString *eTag = [self getSonicHeaderETagWithHeaders:headers];\n    NSString *templateTag = headers[SonicHeaderKeyTemplate];\n    NSTimeInterval timeNow = (long)[[NSDate date ]timeIntervalSince1970]*1000;\n    NSString *localRefresh = [@(timeNow) stringValue];\n    \n    //save configs\n    eTag = eTag.length > 0? eTag:@\"\";\n    templateTag = templateTag.length > 0? templateTag:@\"\";\n    eTag = eTag.length > 0? eTag:@\"\";\n    \n    NSDictionary *cfgDict = @{\n                              // SonicHeaderKeyCustomeETag:[self getCustomSonicHeaderKeyETagWithHeaders:headers]\n                              // [self getCustomSonicHeaderKeyETagWithHeaders:headers]:eTag\n                              SonicHeaderKeyETag:eTag,\n                              SonicHeaderKeyTemplate:templateTag,\n                              kSonicLocalRefreshTime:localRefresh,\n                              };\n    return cfgDict;\n}\n\n/**\n *  Check and save the cache expire timestamp\n */\n- (unsigned long long)createCacheExpireTimeFromHeaders:(NSDictionary *)headers\n{\n    NSString *maxAge = headers[SonicHeaderMaxAge];\n    NSString *expire = headers[SonicHeaderExpire];\n    \n    unsigned long long now =  (unsigned long long)[[NSDate date] timeIntervalSince1970];\n    \n    unsigned long long configMaxCacheTime = [SonicEngine sharedEngine].configuration.maxUnStrictModeCacheSeconds;\n    \n    if(maxAge.length == 0 && expire.length == 0){\n        return now + configMaxCacheTime;\n    }\n    \n    if(maxAge.length > 0){\n        \n        unsigned long long duration = [maxAge longLongValue];\n        \n        duration = MIN(duration, configMaxCacheTime);\n        \n        unsigned long long expireTimestamp = now + duration;\n        \n        return expireTimestamp;\n    }\n    \n    if(expire.length > 0){\n        \n        NSDateFormatter *dateFormatter = [NSDateFormatter new];\n        [dateFormatter setDateFormat:@\"EEE, dd MMM yyyy HH:mm:ss zzz\"];\n        NSDate *date = [dateFormatter dateFromString:expire];\n        unsigned long long expireTime = (unsigned long long)[date timeIntervalSince1970];\n        \n        if (!date) {\n            return now + configMaxCacheTime;\n        }\n        \n        //Beijing 0800 GMT \n        NSTimeZone *system = [NSTimeZone systemTimeZone];\n        NSInteger seconds = [system secondsFromGMTForDate:date];\n        expireTime = expireTime + seconds;\n        \n        unsigned long long configCacheTime = now + configMaxCacheTime;\n        \n        return MIN(expireTime, configCacheTime);\n    }\n    \n    return now + [SonicEngine sharedEngine].configuration.maxUnStrictModeCacheSeconds;\n}\n\n- (void)updateCacheExpireTimeWithResponseHeaders:(NSDictionary *)headers withSessionID:(NSString *)sessionID\n{\n    if (headers.count == 0 || sessionID.length == 0) {\n        return;\n    }\n    \n    SonicCacheItem *cacheItem = [self cacheForSession:sessionID];\n    \n    NSMutableDictionary *mConfig = [NSMutableDictionary dictionaryWithDictionary:cacheItem.config];\n    unsigned long long expireTimestamp = [self createCacheExpireTimeFromHeaders:headers];\n    NSString *expireTime = [@(expireTimestamp) stringValue];\n    [mConfig setObject:expireTime forKey:kSonicLocalCacheExpireTime];\n    cacheItem.config = mConfig;\n    \n    //save to file\n    dealInFileQueue(^{\n       \n        //save the config data\n        [self.database updateWithKeyAndValue:@{kSonicLocalCacheExpireTime:expireTime} withSessionID:sessionID];\n        \n    });\n}\n\n- (void)saveResponseHeaders:(NSDictionary *)headers withSessionID:(NSString *)sessionID\n{\n    NSDictionary *filterHeaders = [self filterResponseHeaders:headers];\n    \n    //save the response headers\n    if (filterHeaders.count > 0) {\n        NSString *rspHeaderPath = [self filePathWithType:SonicCacheTypeResponseHeader sessionID:sessionID];\n        BOOL isSuccess = [filterHeaders writeToFile:rspHeaderPath atomically:YES];\n        if (!isSuccess) {\n            return;\n        }\n    }\n}\n\n#pragma mark File Operation\n\nvoid dealInFileQueue(dispatch_block_t block)\n{\n    NSThread *currentThread = [NSThread currentThread];\n    if ([currentThread.name isEqualToString:[SonicCache fileQueue].name]) {\n        block();\n    }else{\n        NSBlockOperation *blkOp = [NSBlockOperation blockOperationWithBlock:block];\n        [[SonicCache fileQueue] addOperation:blkOp];\n    }\n}\n\n- (NSDictionary *)dynamicDataBySessionID:(NSString *)sessionID\n{\n    return [NSDictionary dictionaryWithContentsOfFile:[self filePathWithType:SonicCacheTypeData sessionID:sessionID]];\n}\n\n- (NSString *)templateStringBySessionID:(NSString *)sessionID\n{\n    return [[[NSString alloc]initWithData:[NSData dataWithContentsOfFile:[self filePathWithType:SonicCacheTypeTemplate sessionID:sessionID]] encoding:NSUTF8StringEncoding]autorelease];\n}\n\n- (void)setupCacheItemFromFile:(SonicCacheItem *)item\n{\n    if (![self isAllCacheExist:item.sessionID]) {\n        [self removeFileCacheOnly:item.sessionID];\n        return;\n    }\n    \n    NSData *htmlData = [NSData dataWithContentsOfFile:[self filePathWithType:SonicCacheTypeHtml sessionID:item.sessionID]];\n    NSDictionary *config = [self.database queryAllKeysWithSessionID:item.sessionID];\n    NSDictionary *cacheHeaders = [NSDictionary dictionaryWithContentsOfFile:[self filePathWithType:SonicCacheTypeResponseHeader sessionID:item.sessionID]];\n\n    NSString *sha1 = config[kSonicSha1];\n    NSString *htmlSha1 = getDataSha1(htmlData);\n    if (![sha1 isEqualToString:htmlSha1]) {\n        [self removeFileCacheOnly:item.sessionID];\n    }else{\n        item.htmlData = htmlData;\n        item.config = config;\n        item.cacheResponseHeaders = cacheHeaders;//sonic 1.1 read headers\n        \n        //sonic 1.0 use this to read\n        if ([config[kSonicCSP] length] > 0) {\n            item.cacheResponseHeaders = @{kSonicCSP:config[kSonicCSP]};\n        }\n        \n        //read templateString and dynamicData where need\n    }\n}\n\n- (BOOL)setupCacheDirectory\n{\n    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);\n    \n    _rootCachePath = [[self createDirectoryIfNotExist:[paths objectAtIndex:0] withSubPath:SonicRootCacheDirName] copy];\n        \n    return _rootCachePath.length > 0;\n}\n\n- (NSString *)createDirectoryIfNotExist:(NSString *)parent withSubPath:(NSString *)subPath\n{\n    if(parent.length == 0 || subPath.length == 0){\n        return nil;\n    }\n    \n    BOOL isDir = YES;\n    NSString *path = [parent stringByAppendingPathComponent:subPath];\n    if (![SonicFileManager fileExistsAtPath:path isDirectory:&isDir]) {\n        NSError *error = nil;\n        [SonicFileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];\n        if (error) {\n            return nil;\n        }\n    }\n    return path;\n}\n\n- (NSString *)sessionSubCacheDir:(NSString *)sessionID\n{\n    return [self createDirectoryIfNotExist:_rootCachePath withSubPath:sessionID];\n}\n\n- (BOOL)isAllCacheExist:(NSString *)sessionID\n{\n    NSUInteger checkList[3] = {\n        SonicCacheTypeHtml,\n        SonicCacheTypeTemplate,\n        SonicCacheTypeResponseHeader\n    };\n    \n    for (int i=0; i<3; i++) {\n        if (![self checkCacheTypeExist:checkList[i] sessionID:sessionID]) { return NO; }\n    }\n    \n    return YES;\n}\n\n- (NSString *)localRefreshTimeBySessionID:(NSString *)sessionID\n{\n    return [self.database queryKey:@\"local_refresh\" withSessionID:sessionID];\n}\n\n- (BOOL)checkCacheTypeExist:(SonicCacheType)type sessionID:(NSString *)sessionID\n{\n    NSString *cachePath = [self filePathWithType:type sessionID:sessionID];\n    \n    return [SonicFileManager fileExistsAtPath:cachePath];\n}\n\n- (NSString *)filePathWithType:(SonicCacheType)cacheType sessionID:(NSString *)sessionID\n{\n    NSString *fileDir = [[SonicCache shareCache] sessionSubCacheDir:sessionID];\n    if (fileDir.length == 0) {\n        return nil;\n    }\n    NSDictionary *extMap = @{\n                             @(SonicCacheTypeConfig):@\"cfg\",\n                             @(SonicCacheTypeTemplate):@\"temp\",\n                             @(SonicCacheTypeHtml):@\"html\",\n                             @(SonicCacheTypeData):@\"data\",\n                             @(SonicCacheTypeResponseHeader):@\"rsp\",\n                             };\n    NSString *cacheFileName = [sessionID stringByAppendingPathExtension:extMap[@(cacheType)]];\n    return [fileDir stringByAppendingPathComponent:cacheFileName];\n}\n\n- (void)removeFileCacheOnly:(NSString *)sessionID\n{\n    dealInFileQueue(^{\n        NSString *fileDir = [self sessionSubCacheDir:sessionID];\n        [SonicFileManager removeItemAtPath:fileDir error:nil];\n    });\n}\n\n- (void)saveHtmlData:(NSData *)htmlData withConfig:(NSDictionary *)config withTemplate:(NSString *)templateString dynamicData:(NSDictionary *)dynamicData withResponseHeaders:(NSDictionary *)responseHeaders withSessionID:(NSString *)sessionID isUpdate:(BOOL)isUpdate\n{\n    if (!htmlData || config.count == 0) {\n        return;\n    }\n    \n    //if is first time to save data, the templateString must't be nil\n    if (!isUpdate && templateString.length == 0) {\n        return;\n    }\n    \n    //if the root cache path didn't created,then we create it\n    if (_rootCachePath.length == 0) {\n        if (![self setupCacheDirectory]) {\n            return;\n        }\n    }\n    \n    //save HTML data\n    if (htmlData) {\n        NSString *htmlPath = [self filePathWithType:SonicCacheTypeHtml sessionID:sessionID];\n        BOOL isSuccess = [htmlData writeToFile:htmlPath atomically:YES];\n        if (!isSuccess) {\n            return;\n        }\n    }\n    \n    //save the template string\n    if (templateString) {\n        NSData *templateData = [templateString dataUsingEncoding:NSUTF8StringEncoding];\n        NSString *tempPath = [self filePathWithType:SonicCacheTypeTemplate sessionID:sessionID];\n        BOOL isSuccess = [templateData writeToFile:tempPath atomically:YES];\n        if (!isSuccess) {\n            [self removeFileCacheOnly:sessionID];\n            return;\n        }\n    }\n    \n    //save the dynamic data\n    if (dynamicData.count > 0) {\n        NSString *dataPath = [self filePathWithType:SonicCacheTypeData sessionID:sessionID];\n        BOOL isSuccess = [dynamicData writeToFile:dataPath atomically:YES];\n        if (!isSuccess) {\n            [self removeFileCacheOnly:sessionID];\n            return;\n        }\n    }\n    \n    //save the response headers\n    if (responseHeaders.count > 0) {\n        NSString *rspHeaderPath = [self filePathWithType:SonicCacheTypeResponseHeader sessionID:sessionID];\n        BOOL isSuccess = [responseHeaders writeToFile:rspHeaderPath atomically:YES];\n        if (!isSuccess) {\n            [self removeFileCacheOnly:sessionID];\n            return;\n        }\n    }\n    \n    //save the config data\n    BOOL isSuccess = [self.database insertWithKeyAndValue:config withSessionID:sessionID];\n    if (!isSuccess) {\n        [self removeFileCacheOnly:sessionID];\n    }\n}\n\n- (NSDictionary *)filterResponseHeaders:(NSDictionary *)responseHeaders\n{\n    if (responseHeaders.count == 0) {\n        return @{};\n    }\n    \n    NSMutableDictionary *mRespHeaders = [NSMutableDictionary dictionaryWithDictionary:responseHeaders];\n    \n    __block NSMutableArray *removeKeys = [NSMutableArray arrayWithArray:@[SonicHeaderMaxAge,SonicHeaderKeyCacheOffline,SonicHeaderExpire,SonicHeaderKeyTemplate,SonicHeaderKeyTemplateChange]];\n    \n    [mRespHeaders enumerateKeysAndObjectsUsingBlock:^(NSString *key, id  _Nonnull obj, BOOL * _Nonnull stop) {\n       \n        if ([[key lowercaseString] rangeOfString:@\"cookie\"].location != NSNotFound) {\n            [removeKeys addObject:key];\n        }\n        \n    }];\n    \n    [mRespHeaders removeObjectsForKeys:removeKeys];\n    \n    return mRespHeaders;\n}\n\n- (void)checkAndTrimCache\n{\n    [self checkAndTrimRootCache];\n    [self checkAndTrimResourceCache];\n}\n\n- (void)checkAndTrimRootCache\n{\n    unsigned long long lastTrimStamp = [[[NSUserDefaults standardUserDefaults] objectForKey:kSonicRootCacheTrimTimestampUDF] longLongValue];\n    unsigned long long duration = currentTimeStamp() - lastTrimStamp;\n    if (duration < [SonicConfiguration defaultConfiguration].rootCacheSizeCheckDuration) {\n        SonicLogEvent(@\"Trim root cache in duration!\");\n        return;\n    }\n    SonicLogEvent(@\"Trim root cache start !\");\n    [self checkAndTrimCacheAtDirPath:_rootCachePath unIncludeSubDir:SonicRootCacheConfigDirName withMaxDirectorySize:[SonicConfiguration defaultConfiguration].cacheMaxDirectorySize withWarningPercent:[SonicConfiguration defaultConfiguration].cacheDirectorySizeWarningPercent];\n    [[NSUserDefaults standardUserDefaults] setObject:[@(currentTimeStamp()) stringValue] forKey:kSonicRootCacheTrimTimestampUDF];\n}\n\n- (void)checkAndTrimCacheAtDirPath:(NSString *)dirPath unIncludeSubDir:(NSString *)unInclueSubDir withMaxDirectorySize:(unsigned long long)maxDirSize withWarningPercent:(CGFloat)warningPercent\n{\n    //Check current root cache directory size\n    if (dirPath.length == 0) {\n        return;\n    }\n\n    unsigned long long cacheSize = [self folderSize:dirPath];\n    \n    CGFloat percent = cacheSize/maxDirSize;\n    \n    if ( percent < warningPercent ) {\n        \n        return;\n        \n    }\n    \n    dealInFileQueue(^{\n        \n        //sort sub directory by update time\n        NSArray *contentArray = [SonicFileManager contentsOfDirectoryAtPath:dirPath error:nil];\n        \n        if (contentArray.count == 0) {\n            return;\n        }\n        \n        NSArray *sortArray = [contentArray sortedArrayUsingComparator:^NSComparisonResult(NSString *fileName1, NSString *fileName2) {\n            \n            NSString *subDir1 = [dirPath stringByAppendingPathComponent:fileName1];\n            NSString *subDir2 = [dirPath stringByAppendingPathComponent:fileName2];\n            \n            NSDictionary *fileAttrs1 = [SonicFileManager attributesOfItemAtPath:subDir1 error:nil];\n            NSDictionary *fileAttrs2 = [SonicFileManager attributesOfItemAtPath:subDir2 error:nil];\n            \n            NSTimeInterval modifyTime1 = [[fileAttrs1 fileModificationDate] timeIntervalSince1970];\n            NSTimeInterval modifyTime2 = [[fileAttrs2 fileModificationDate] timeIntervalSince1970];\n            \n            return modifyTime1 < modifyTime2;\n        }];\n        \n        NSMutableArray *willClearSubDirs = [NSMutableArray array];\n        unsigned long long totalReadSize = 0;\n        \n        for (NSString *fileItem in sortArray) {\n            \n            //special directory\n            if ([fileItem isEqualToString:unInclueSubDir]) {\n                continue;\n            }\n            NSString *subDir = [dirPath stringByAppendingPathComponent:fileItem];\n            \n            unsigned long long fileSize = [self folderSize:subDir];\n            totalReadSize = totalReadSize + fileSize;\n            [willClearSubDirs addObject:fileItem];\n            \n            if ((cacheSize - totalReadSize)/maxDirSize < percent ) {\n                break;\n            }\n        }\n        \n        //do clear action\n        if (totalReadSize > 0 && willClearSubDirs.count > 0) {\n            \n            for (NSString *fileItem in willClearSubDirs) {\n                \n                NSString *subDir = [dirPath stringByAppendingPathComponent:fileItem];\n                \n                [SonicFileManager removeItemAtPath:subDir error:nil];\n                \n                SonicLogEvent(@\"trim clear cache at subDir :%@\",subDir);\n            }\n        }\n        \n    });\n}\n\n- (unsigned long long int)folderSize:(NSString *)folderPath {\n    NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:folderPath error:nil];\n    NSEnumerator *filesEnumerator = [filesArray objectEnumerator];\n    NSString *fileName;\n    unsigned long long int fileSize = 0;\n    \n    while (fileName = [filesEnumerator nextObject]) {\n        NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:fileName] error:nil];\n        fileSize += [fileDictionary fileSize];\n    }\n    \n    return fileSize;\n}\n\n- (BOOL)upgradeSonicVersion\n{\n    [self clearAllCache];\n\n    return YES;\n}\n\n#pragma mark - Sub resource load\n\n- (void)clearResourceCache\n{\n    [SonicFileManager removeItemAtPath:_rootResourceCachePath error:nil];\n    [SonicFileManager removeItemAtPath:_rootResourceConfigCachePath error:nil];\n    [self setupSubResourceCacheDirectory];\n}\n\n- (BOOL)setupSubResourceConfigDirectory\n{\n    NSString *configPath = [self createDirectoryIfNotExist:_rootCachePath withSubPath:SonicRootCacheConfigDirName];\n    _rootResourceConfigCachePath = [[self createDirectoryIfNotExist:configPath withSubPath:SonicResourceConfigDirName] copy];\n    \n    return _rootResourceConfigCachePath.length > 0;\n}\n\n- (BOOL)setupSubResourceCacheDirectory\n{\n    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);\n    \n    _rootResourceCachePath = [[self createDirectoryIfNotExist:[paths objectAtIndex:0] withSubPath:SonicResourceCacheDirName] copy];\n    \n    SonicLogEvent(@\"resource cache path:%@\",_rootResourceCachePath);\n    \n    [self setupSubResourceConfigDirectory];\n\n    return _rootResourceCachePath.length > 0;\n}\n\n- (NSString *)resourcePathWithFileType:(SonicCacheType)type withSessionID:(NSString *)sessionID\n{\n    NSDictionary *extMap = @{\n                             @(SonicCacheTypeConfig):@\"cfg\",\n                             @(SonicCacheTypeData):@\"data\",\n                             @(SonicCacheTypeResponseHeader):@\"rsp\",\n                             };\n    NSString *subResourcePath = nil;\n    if (type == SonicCacheTypeConfig) {\n        subResourcePath = [[_rootResourceConfigCachePath stringByAppendingPathComponent:sessionID]stringByAppendingPathExtension:extMap[@(type)]];\n    }else{\n        NSString *sessionSubDir = [self createDirectoryIfNotExist:_rootResourceCachePath withSubPath:sessionID];\n        subResourcePath = [[sessionSubDir stringByAppendingPathComponent:sessionID]stringByAppendingPathExtension:extMap[@(type)]];\n    }\n    return subResourcePath;\n}\n\n- (BOOL)saveSubResourceData:(NSData *)data withConfig:(NSDictionary *)config withResponseHeaders:(NSDictionary *)responseHeader withSessionID:(NSString *)sessionID\n{\n    NSString *cacheFilePath = [self resourcePathWithFileType:SonicCacheTypeData withSessionID:sessionID];\n    BOOL isSuccess = [data writeToFile:cacheFilePath atomically:YES];\n    if (!isSuccess) {\n        return isSuccess;\n    }\n    \n    NSString *responsePath = [self resourcePathWithFileType:SonicCacheTypeResponseHeader withSessionID:sessionID];\n    isSuccess = [responseHeader writeToFile:responsePath atomically:YES];\n    if (!isSuccess) {\n        return isSuccess;\n    }\n    \n    NSString *cfgPath = [self resourcePathWithFileType:SonicCacheTypeConfig withSessionID:sessionID];\n    isSuccess = [config writeToFile:cfgPath atomically:YES];\n    if (!isSuccess) {\n        [SonicFileManager removeItemAtPath:cacheFilePath error:nil];\n    }\n    \n    SonicLogEvent(@\"resource save state:%d sessionID:%@\",isSuccess,sessionID);\n    \n    return isSuccess;\n}\n\n- (NSDictionary *)responseHeadersWithSessionID:(NSString *)sessionID\n{\n    NSString *responsePath = [self resourcePathWithFileType:SonicCacheTypeResponseHeader withSessionID:sessionID];\n    return [NSDictionary dictionaryWithContentsOfFile:responsePath];\n}\n\n- (NSData *)resourceCacheWithSessionID:(NSString *)sessionID\n{\n    NSString *cacheFilePath = [self resourcePathWithFileType:SonicCacheTypeData withSessionID:sessionID];\n    return [NSData dataWithContentsOfFile:cacheFilePath];\n}\n\n- (NSDictionary *)resourceConfigWithSessionID:(NSString *)sessionID\n{\n    NSString *configPath = [self resourcePathWithFileType:SonicCacheTypeConfig withSessionID:sessionID];\n    return [NSDictionary dictionaryWithContentsOfFile:configPath];\n}\n\n- (BOOL)clearResourceWithSessionID:(NSString *)sessionID\n{\n    NSString *responsePath = [self resourcePathWithFileType:SonicCacheTypeResponseHeader withSessionID:sessionID];\n    NSString *cacheFilePath = [self resourcePathWithFileType:SonicCacheTypeData withSessionID:sessionID];\n    NSString *configPath = [self resourcePathWithFileType:SonicCacheTypeConfig withSessionID:sessionID];\n    [SonicFileManager removeItemAtPath:responsePath error:nil];\n    [SonicFileManager removeItemAtPath:cacheFilePath error:nil];\n    [SonicFileManager removeItemAtPath:configPath error:nil];\n    return YES;\n}\n\n- (void)checkAndTrimResourceCache\n{\n    unsigned long long lastTrimStamp = [[[NSUserDefaults standardUserDefaults] objectForKey:kSonicResourceCacheTrimTimestampUDF] longLongValue];\n    unsigned long long duration = currentTimeStamp() - lastTrimStamp;\n    if (duration < [SonicConfiguration defaultConfiguration].resourceCacheSizeCheckDuration) {\n        SonicLogEvent(@\"Trim resource cache in duration!\");\n        return;\n    }\n    //event\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_TrimCache withEventInfo:@{@\"msg\":@\"Trim resource cache start !\"}];\n    [self checkAndTrimCacheAtDirPath:SonicResourceCacheDirName unIncludeSubDir:nil withMaxDirectorySize:[SonicConfiguration defaultConfiguration].resourcCacheMaxDirectorySize withWarningPercent:[SonicConfiguration defaultConfiguration].cacheDirectorySizeWarningPercent];\n    [[NSUserDefaults standardUserDefaults] setObject:[@(currentTimeStamp()) stringValue] forKey:kSonicResourceCacheTrimTimestampUDF];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicCacheItem.h",
    "content": "//\n//  SonicCacheItem.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * Memory cache item.\n */\n@interface SonicCacheItem : NSObject\n\n/** Html. */\n@property (nonatomic,retain)NSData         *htmlData;\n\n/** Config. */\n@property (nonatomic,retain)NSDictionary   *config;\n\n/** Session. */\n@property (nonatomic,readonly)NSString     *sessionID;\n\n/** Template string. */\n@property (nonatomic,copy)  NSString       *templateString;\n\n/** Generated by local dynamic data and server dynamic data. */\n@property (nonatomic,retain)NSDictionary   *diffData;\n\n/** Sonic divide HTML to tepmlate and dynamic data.  */\n@property (nonatomic,retain)NSDictionary   *dynamicData;\n\n/** Is there file cache exist. */\n@property (nonatomic,readonly)BOOL         hasLocalCache;\n\n/** Last refresh time.  */\n@property (nonatomic,readonly)NSString     *lastRefreshTime;\n\n/** Cache some header fields which will be used later. */\n@property (nonatomic,retain)NSDictionary   *cacheResponseHeaders;\n\n/** Initialize an item with session id. */\n- (instancetype)initWithSessionID:(NSString *)aSessionID;\n\n/**\n * Check if current cache expired\n */\n- (BOOL)isCacheExpired;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicCacheItem.m",
    "content": "//\n//  SonicCacheItem.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicCacheItem.h\"\n#import \"SonicCache.h\"\n#import \"SonicConstants.h\"\n#import \"SonicUtil.h\"\n\n\n@implementation SonicCacheItem\n\n- (instancetype)init NS_UNAVAILABLE\n{\n    return nil;\n}\n\n- (instancetype)initWithSessionID:(NSString *)aSessionID\n{\n    if (self = [super init]) {\n        \n        _sessionID = [aSessionID copy];\n                \n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    if (_sessionID) {\n        [_sessionID release];\n        _sessionID = nil;\n    }\n    if (_cacheResponseHeaders) {\n        [_cacheResponseHeaders release];\n        _cacheResponseHeaders = nil;\n    }\n    if (self.config) {\n        self.config = nil;\n    }\n    if (self.htmlData) {\n        self.htmlData = nil;\n    }\n    if (self.templateString) {\n        self.templateString = nil;\n    }\n    if (self.diffData) {\n        self.diffData = nil;\n    }\n    if (self.dynamicData) {\n        self.dynamicData = nil;\n    }\n    [super dealloc];\n}\n\n- (BOOL)hasLocalCache\n{\n    return self.htmlData.length > 0? YES:NO;\n}\n\n- (NSString *)lastRefreshTime\n{\n    if (!self.config) {\n        return nil;\n    }\n    return self.config[kSonicLocalRefreshTime];\n}\n\n- (BOOL)isCacheExpired\n{\n    //NO cache !\n    if (self.htmlData == nil) {\n        return YES;\n    }\n    \n    unsigned long long now = (unsigned long long)[[NSDate date] timeIntervalSince1970];\n    \n    unsigned long long cacheExpireTime = [self.config[kSonicLocalCacheExpireTime] longLongValue];\n    \n    return now > cacheExpireTime;\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicDatabase.h",
    "content": "//\n//  SonicDatabase.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@interface SonicDatabase : NSObject\n\n/**\n * Init database with dbPath\n */\n- (instancetype)initWithPath:(NSString *)dbPath;\n\n/**\n * Insert validate key-value to configs for sessionID\n */\n- (BOOL)insertWithKeyAndValue:(NSDictionary *)keyValues withSessionID:(NSString *)sessionID;\n\n/**\n * Update key-value to configs for sessionID\n */\n- (BOOL)updateWithKeyAndValue:(NSDictionary *)keyValues withSessionID:(NSString *)sessionID;\n\n/**\n * Query all configs for sessionID\n */\n- (NSDictionary *)queryAllKeysWithSessionID:(NSString *)sessionID;\n\n/**\n * Query the key for sessionID\n */\n- (NSString *)queryKey:(NSString *)key withSessionID:(NSString *)sessionID;\n\n/**\n * Delete configs for sessionID\n */\n- (BOOL)clearWithSessionID:(NSString *)sessionID;\n\n/**\n * close database\n */\n- (void)close;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Cache/SonicDatabase.m",
    "content": "//\n//  SonicDatabase.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicDatabase.h\"\n#import \"sqlite3.h\"\n#import \"SonicEventStatistics.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n/**\n *  create a config table to save data;important: all column used text type,because of that is easy to access and update\n */\n\n#define SonicCreateTableSql @\"create table if not exists 'config' ('sessionID' text primary key not null,'local_refresh' text,'template-tag' text,'etag' text,'sha1' text,'cache-expire-time' text)\"\n\n@interface SonicDatabase()\n{\n    sqlite3 *_db;\n}\n\n@end\n\n@implementation SonicDatabase\n\n- (instancetype)initWithPath:(NSString *)dbPath\n{\n    if (self = [super init]) {\n        \n        int ret = sqlite3_open(dbPath.UTF8String, &_db);\n        \n        if (ret != SQLITE_OK) {\n            \n            SonicLogEvent(@\"database open db faild :%@ code:%d\",dbPath,ret);\n        }\n        \n        [self createConfigTableIfNotExist];\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [self close];\n    [super dealloc];\n}\n\n- (void)close\n{\n    if (!_db) {\n        return;\n    }\n    sqlite3_close(_db);\n    _db = nil;\n}\n\n- (void)createConfigTableIfNotExist\n{\n   [self execSql:SonicCreateTableSql];\n}\n\n- (BOOL)execSql:(NSString *)sql\n{\n    \n    int ret = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);\n    if (ret != SQLITE_OK) {\n        SonicLogEvent(@\"sql error:%@\",sql);\n    }\n    return ret == SQLITE_OK;\n}\n\n- (NSDictionary *)querySql:(NSString *)sql withQueryResultKey:(NSArray *)keys\n{\n    if (sql.length == 0 || keys.count == 0) {\n        return nil;\n    }\n    \n    sqlite3_stmt *stmt;\n    \n    int ret = sqlite3_prepare_v2(_db, [sql UTF8String], -1,&stmt, 0);\n    \n    if (ret != SQLITE_OK) {\n        sqlite3_finalize(stmt);\n        return nil;\n    }\n    \n    for (NSString *key in keys) {\n        \n        int nameIndex = sqlite3_bind_parameter_index(stmt, key.UTF8String);\n        \n        if (nameIndex > 0) {\n            \n            sqlite3_bind_text(stmt, nameIndex, key.UTF8String, -1, SQLITE_STATIC);\n            \n        }\n    }\n    \n    int rc = sqlite3_step(stmt);\n    \n    if (rc != SQLITE_ROW) {\n        sqlite3_finalize(stmt);\n        return nil;\n    }\n    \n    NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];\n    \n    NSInteger column_count = sqlite3_column_count(stmt);\n    \n    for (int columnIdx = 0; columnIdx < column_count; columnIdx++) {\n        \n        const char *key = (const char *)sqlite3_column_name(stmt, columnIdx);\n        const char *value = (const char *)sqlite3_column_text(stmt, columnIdx);\n        \n        if (key) {\n            NSString *v = @\"\";\n            if (value && strcmp(key, value) != 0) {\n                v = [NSString stringWithUTF8String:value];\n            }\n            NSString *keyStr = [NSString stringWithUTF8String:key];\n            [resultDict setObject:v forKey:keyStr];\n        }\n    }\n    \n    sqlite3_finalize(stmt);\n    \n    return resultDict;\n}\n\n- (BOOL)insertWithKeyAndValue:(NSDictionary *)keyValues withSessionID:(NSString *)sessionID\n{\n    if (keyValues.count == 0) {\n        return NO;\n    }\n    \n    //clear if exist\n    NSString *isExistSql = [NSString stringWithFormat:@\"select 'sessionID' from config where sessionID = '%@'\",sessionID];\n    BOOL isExist = [self execSql:isExistSql];\n    if (isExist) {\n        [self clearWithSessionID:sessionID];\n    }\n    \n    return [self execSqlWithKeyAndValue:keyValues withSessionID:sessionID withUpdate:NO table:@\"config\"];\n}\n\n- (BOOL)updateWithKeyAndValue:(NSDictionary *)keyValues withSessionID:(NSString *)sessionID\n{\n    return [self execSqlWithKeyAndValue:keyValues withSessionID:sessionID withUpdate:YES table:@\"config\"];\n}\n\n- (BOOL)execSqlWithKeyAndValue:(NSDictionary *)keyValues withSessionID:(NSString *)sessionID withUpdate:(BOOL)isUpdate table:(NSString *)table\n{\n    if (keyValues.count == 0 || sessionID.length == 0) {\n        return NO;\n    }\n    \n    NSMutableString *dataPart = [NSMutableString string];\n    NSMutableString *keySort = [NSMutableString string];\n    \n    [keySort appendFormat:@\"(\"];\n    [dataPart appendFormat:@\"(\"];\n    \n    //insert session\n    if (!isUpdate) {\n        [keySort appendString:@\"sessionID,\"];\n        [dataPart appendFormat:@\"'%@',\",sessionID];\n    }\n    \n    NSMutableString *updateValues = [NSMutableString string];\n    for (int index = 0; index < keyValues.allKeys.count; index++) {\n        \n        NSString *key = keyValues.allKeys[index];\n        NSString *value = keyValues[key];\n\n        if (isUpdate) {\n            if (index != keyValues.count - 1 && keyValues.count > 0) {\n                if ([key rangeOfString:@\"-\"].location != NSNotFound) {\n                    [updateValues appendFormat:@\"set \\\"%@\\\" = '%@',\",key,value];\n                }else{\n                    [updateValues appendFormat:@\"set %@ = '%@',\",key,value];\n                }\n            }else{\n                if ([key rangeOfString:@\"-\"].location != NSNotFound) {\n                    [updateValues appendFormat:@\"set \\\"%@\\\" = '%@'\",key,value];\n                }else{\n                    [updateValues appendFormat:@\"set %@ = '%@'\",key,value];\n                }\n            }\n        }else{\n            if (index != keyValues.count-1 && keyValues.count > 0) {\n                if ([key rangeOfString:@\"-\"].location != NSNotFound) {\n                    [keySort appendFormat:@\"\\\"%@\\\",\",key];\n                }else{\n                    [keySort appendFormat:@\"'%@',\",key];\n                }\n                [dataPart appendFormat:@\"'%@',\",value];\n            }else{\n                if ([key rangeOfString:@\"-\"].location != NSNotFound) {\n                    [keySort appendFormat:@\"\\\"%@\\\")\",key];\n                }else{\n                    [keySort appendFormat:@\"'%@')\",key];\n                }\n                [dataPart appendFormat:@\"'%@')\",value];\n            }\n        }\n    }\n    \n    NSString *action = isUpdate? @\"update\":@\"insert into\";\n    NSString *condition = isUpdate? [NSString stringWithFormat:@\"where sessionID = '%@'\",sessionID]:@\"\";\n    \n    NSString *sql = nil;\n    \n    if (isUpdate) {\n        sql = [NSString stringWithFormat:@\"%@ %@ %@ %@\",action,table,updateValues,condition];\n    }else{\n       sql = [NSString stringWithFormat:@\"%@ %@ %@ values %@ %@\",action,table,keySort,dataPart,condition];\n    }\n    \n   return [self execSql:sql];\n}\n\n- (NSDictionary *)queryAllKeysWithSessionID:(NSString *)sessionID\n{\n    return [self queryWithKeys:@[@\"sessionID\",@\"local_refresh\",@\"template-tag\",@\"sha1\",@\"Etag\",@\"cache-expire-time\"] withSessionID:sessionID table:@\"config\"];\n}\n\n- (NSDictionary *)queryWithKeys:(NSArray *)keys withSessionID:(NSString *)sessionID table:(NSString *)table\n{\n    NSMutableString *selectColumn = [NSMutableString string];\n    for (int index = 0; index < keys.count; index++) {\n        NSString *key = keys[index];\n        if ([key rangeOfString:@\"-\"].location != NSNotFound) {\n            key = [NSString stringWithFormat:@\"\\\"%@\\\"\",key];\n        }\n        if (index != keys.count - 1) {\n            [selectColumn appendFormat:@\"%@,\",key];\n        }else{\n            [selectColumn appendFormat:@\"%@\",key];\n        }\n    }\n    \n    NSString *sql = [NSString stringWithFormat:@\"select %@ from %@ where sessionID = '%@'\",selectColumn,table,sessionID];\n    \n    return [self querySql:sql withQueryResultKey:keys];\n}\n\n- (NSString *)queryKey:(NSString *)key withSessionID:(NSString *)sessionID\n{\n    NSDictionary *resultDict = [self queryWithKeys:@[key] withSessionID:sessionID table:@\"config\"];\n    \n    return resultDict[key];\n}\n\n- (BOOL)clearWithSessionID:(NSString *)sessionID\n{\n    NSString *sql = [NSString stringWithFormat:@\"delete from config where sessionID = '%@'\",sessionID];\n    \n    return [self execSql:sql];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Engine/SonicConfiguration.h",
    "content": "//\n//  SonicConfiguration.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@interface SonicConfiguration : NSObject\n\n/**\n * Sever default disable sonic time duration: 6 hours.\n */\n@property (nonatomic,assign)unsigned long long cacheOfflineDisableTime;\n\n/**\n * Root cache directory max size,default is 30MB\n */\n@property (nonatomic,assign)unsigned long long cacheMaxDirectorySize;\n\n/**\n * Clean up the cache if the current cache reaches the maximum cache of 0.8.\n */\n@property (nonatomic,assign)float cacheDirectorySizeWarningPercent;\n\n/**\n * Clean up the cache to the maximum cache of 0.2.\n */\n@property (nonatomic,assign)float cacheDirectorySizeSafePercent;\n\n/**\n * The memory cache maximum count.\n */\n@property (nonatomic,assign)NSInteger maxMemroyCacheItemCount;\n\n/**\n * The max cache time under strict-mode:false,default is 5 min.\n */\n@property (nonatomic,assign)unsigned long long maxUnStrictModeCacheSeconds;\n\n/**\n * The default time interval for clearing resource cache, default is 12 hours.\n */\n@property (nonatomic,assign)unsigned long long resourceCacheSizeCheckDuration;\n\n/**\n * The default time interval for clearing root cache, default is 12 hours.\n */\n@property (nonatomic,assign)unsigned long long rootCacheSizeCheckDuration;\n\n/**\n * Maximum resource cache directory size, default is 60MB.\n */\n@property (nonatomic,assign)unsigned long long resourcCacheMaxDirectorySize;\n\n/**\n * Return default configuration.\n */\n+ (SonicConfiguration *)defaultConfiguration;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Engine/SonicConfiguration.m",
    "content": "//\n//  SonicConfiguration.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicConfiguration.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n@implementation SonicConfiguration\n\n+ (SonicConfiguration *)defaultConfiguration\n{\n    SonicConfiguration *configuration = [[SonicConfiguration new]autorelease];\n    configuration.cacheOfflineDisableTime = 21600;\n    configuration.cacheMaxDirectorySize = 31457280;\n    configuration.cacheDirectorySizeWarningPercent = 0.8;\n    configuration.cacheDirectorySizeSafePercent = 0.25;\n    configuration.maxMemroyCacheItemCount = 3;\n    configuration.maxUnStrictModeCacheSeconds = 300;\n    configuration.resourceCacheSizeCheckDuration = 60 * 60 * 12;\n    configuration.resourcCacheMaxDirectorySize = 31457280 * 2;\n    configuration.rootCacheSizeCheckDuration = 60 * 60 * 12;\n    \n    return configuration;\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Engine/SonicEngine.h",
    "content": "//\n//  SonicEngine.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicSession.h\"\n#import \"SonicConstants.h\"\n#import \"SonicSessionConfiguration.h\"\n#import \"SonicConfiguration.h\"\n\n/**\n * Manage all sonic sessions.\n */\n@interface SonicEngine : NSObject\n\n/* Return the unique identifier for current user */\n@property (nonatomic,readonly)NSString *currentUserAccount;\n\n/* Return the global custom User-Agent */\n@property (nonatomic,readonly)NSString *userAgent;\n\n/* Return the configuration */\n@property (nonatomic,readonly)SonicConfiguration *configuration;\n\n/* Share the instance */\n+ (SonicEngine *)sharedEngine;\n\n/**\n * Client must run with the configuration,default use [SonicConfiguration defaultConfiguration]\n */\n- (void)runWithConfiguration:(SonicConfiguration *)aConfiguration;\n\n/**\n * Set an unique identifier for the user.\n * We can use the identifier to create different cache dir for different users.\n \n * @param userAccount the unique identifier for the special user\n */\n- (void)setCurrentUserAccount:(NSString *)userAccount;\n\n/**\n * @brief Clear all session memory and file caches.\n */\n- (void)clearAllCache;\n\n/**\n * Clear session memory and file caches with URL.\n */\n- (void)removeCacheByUrl:(NSString *)url;\n\n/**\n * Check if it is the first time to load this URL.\n */\n- (BOOL)isFirstLoad:(NSString *)url;\n\n/**\n * Use this API to add a domain-ip pair to connect server directly with ip in following requests.\n \n * @param domain host from url like www.qq.com\n * @param ipAddress e.g 8.8.8.8\n */\n- (void)addDomain:(NSString *)domain withIpAddress:(NSString *)ipAddress;\n\n/**\n * Set global custom User-Agent.\n \n * @param aUserAgent the custom User-Agent\n */\n- (void)setGlobalUserAgent:(NSString *)aUserAgent;\n\n/**\n * Get global custom User-Agent.\n \n * return the custom User-Agent\n */\n- (NSString *)getGlobalUserAgent;\n\n/**\n * Get the last update timestamp of this URL.\n */\n- (NSString *)localRefreshTimeByUrl:(NSString *)url;\n\n/**\n * Create a sonic session with URL.\n * All the same URLs share one single session. Duplicate calls will not create duplicate sessions.\n * use configuration to add custom request headers or custom response headers\n */\n- (void)createSessionWithUrl:(NSString *)url withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate withConfiguration:(SonicSessionConfiguration *)configuration;\n\n/**\n * Create a sonic session with URL.\n * All the same URLs share one single session. Duplicate calls will not create duplicate sessions.\n */\n- (void)createSessionWithUrl:(NSString *)url withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate;\n\n/**\n * Remove session by delegate, it will be little safer than removing by URL, cause URL is too easy to get.\n */\n- (void)removeSessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate;\n\n/**\n * Find session by sessionId\n */\n- (SonicSession *)sessionById:(NSString *)sessionId;\n\n/**\n * Find the session with webDelegate.\n */\n- (SonicSession *)sessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate;\n\n/**\n * Find the session with webDelegateId.\n */\n- (SonicSession *)sessionWithDelegateId:(NSString *)delegateId;\n\n/**\n * Reload session to update page content\n */\n- (BOOL)reloadSessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate completion:(SonicWebviewCallBack)resultBlock;\n\n/**\n * Get the patch between local data and server data.\n * Web page use this patch data to update itself.\n */\n- (void)sonicUpdateDiffDataByWebDelegate:(id<SonicSessionDelegate>)aWebDelegate completion:(SonicWebviewCallBack)resultBlock;\n\n/**\n * SonicURLProtocol will regist the callback to get network data from the sonic session\n */\n- (void)registerURLProtocolCallBackWithSessionID:(NSString *)sessionID completion:(SonicURLProtocolCallBack)protocolCallBack;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Engine/SonicEngine.m",
    "content": "//\n//  SonicEngine.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicEngine.h\"\n#import \"SonicCache.h\"\n#import \"SonicUtil.h\"\n#import \"SonicEventStatistics.h\"\n\n@interface SonicEngine ()\n\n@property (nonatomic,retain)NSLock *lock;\n@property (nonatomic,retain)NSMutableDictionary *tasks;\n@property (nonatomic,retain)NSMutableDictionary *ipDomains;\n@property (nonatomic,copy)NSString *userAgent;\n\n@end\n\n@implementation SonicEngine\n\n+ (SonicEngine *)sharedEngine\n{\n    static SonicEngine *_engine = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _engine = [[self alloc]init];\n    });\n    return _engine;\n}\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        [self setupEngine];\n    }\n    return self;\n}\n\n- (void)setGlobalUserAgent:(NSString *)aUserAgent\n{\n    if (aUserAgent.length == 0) {\n        return;\n    }\n    if (_userAgent) {\n        [_userAgent release];\n        _userAgent = nil;\n    }\n    _userAgent = [aUserAgent copy];\n}\n\n- (NSString *)getGlobalUserAgent\n{\n    if (_userAgent.length > 0) {\n        return _userAgent;\n    }\n    return SonicDefaultUserAgent;\n}\n\n- (void)runWithConfiguration:(SonicConfiguration *)aConfiguration\n{\n    [_configuration release];\n    _configuration = nil;\n    _configuration = [aConfiguration retain];\n}\n\n- (void)setCurrentUserAccount:(NSString *)userAccount\n{\n    if (userAccount.length == 0 || [_currentUserAccount isEqualToString:userAccount]) {\n        return;\n    }\n    if (_currentUserAccount) {\n        [_currentUserAccount release];\n        _currentUserAccount = nil;\n    }\n    _currentUserAccount = [userAccount copy];\n    \n    //create root cache path by user id\n    [[SonicCache shareCache] setupCacheDirectory];\n}\n\n- (void)addDomain:(NSString *)domain withIpAddress:(NSString *)ipAddress\n{\n    if (domain.length == 0 || ipAddress.length == 0) {\n        return;\n    }\n    [self.ipDomains setObject:ipAddress forKey:domain];\n}\n\n- (void)setupEngine\n{\n    _configuration = [[SonicConfiguration defaultConfiguration] retain];\n    self.lock = [NSLock new];\n    self.tasks = [NSMutableDictionary dictionary];\n    self.ipDomains = [NSMutableDictionary dictionary];\n}\n\n- (void)clearAllCache\n{\n    [[SonicCache shareCache] clearAllCache];\n}\n\n- (BOOL)isFirstLoad:(NSString *)url\n{\n    return [[SonicCache shareCache] isFirstLoad:sonicSessionID(url)];\n}\n\n- (NSString *)localRefreshTimeByUrl:(NSString *)url\n{\n    return [[SonicCache shareCache] localRefreshTimeBySessionID:sonicSessionID(url)];\n}\n\n- (void)removeCacheByUrl:(NSString *)url\n{\n    SonicSession *existSession = [self sessionById:sonicSessionID(url)];\n    if (!existSession) {\n        [[SonicCache shareCache] removeCacheBySessionID:sonicSessionID(url)];\n    }\n}\n\n- (void)registProtocolCallBack:(SonicURLProtocolCallBack)callBack withSessionID:(NSString *)sessionID\n{\n    SonicSession *existSession = [self sessionById:sessionID];\n    if (existSession) {\n        dispatchToSonicSessionQueue(^{\n            existSession.protocolCallBack = callBack;\n        });\n    }\n}\n\n- (void)registerURLProtocolCallBackWithSessionID:(NSString *)sessionID completion:(SonicURLProtocolCallBack)protocolCallBack\n{\n    dispatchToMain(^{\n        SonicSession *session = [self sessionById:sessionID];\n        if (session) {\n            [session preloadRequestActionsWithProtocolCallBack:protocolCallBack];\n        }\n    });\n}\n\n- (void)sonicUpdateDiffDataByWebDelegate:(id<SonicSessionDelegate>)aWebDelegate completion:(SonicWebviewCallBack)resultBlock\n{\n    if (!resultBlock) {\n        return;\n    }\n    \n    SonicSession *session = [self sessionWithWebDelegate:aWebDelegate];\n    [session getResultWithCallBack:^(NSDictionary *result) {\n        if (resultBlock) {\n            resultBlock(result);\n        }\n    }];\n}\n\n#pragma mark - Safe Session Manager\n\nstatic bool ValidateSessionDelegate(id<SonicSessionDelegate> aWebDelegate)\n{\n    return aWebDelegate && [aWebDelegate conformsToProtocol:@protocol(SonicSessionDelegate)];\n}\n\n- (void)createSessionWithUrl:(NSString *)url withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate\n{\n    [self createSessionWithUrl:url withWebDelegate:aWebDelegate withConfiguration:nil];\n}\n\n- (void)createSessionWithUrl:(NSString *)url withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate withConfiguration:(SonicSessionConfiguration *)configuration\n{\n    //If there is preload Sonic, the aWebDelegate may be nil, so we need't checkup aWebDelegate\n    if (url.length == 0 || ![NSURL URLWithString:url]) {\n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionCreateFaild withEventInfo:@{@\"msg\":@\"url not validate!\"}];\n        return;\n    }\n    \n    if ([[SonicCache shareCache] isServerDisableSonic:sonicSessionID(url)]) {\n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionCreateFaild withEventInfo:@{@\"msg\":@\"server disable!\"}];\n        return;\n    }\n    \n    [self.lock lock];\n    SonicSession *existSession = self.tasks[sonicSessionID(url)];\n    if (existSession && existSession.delegate != nil) {\n        //session can only owned by one delegate\n        [self.lock unlock];\n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionCreateFaild withEventInfo:@{@\"msg\":@\"same url session existed!\"}];\n        return;\n    }\n    \n    if (!existSession) {\n        existSession = [[SonicSession alloc] initWithUrl:url withWebDelegate:aWebDelegate Configuration:configuration];\n        \n        NSURL *cUrl = [NSURL URLWithString:url];\n        existSession.serverIP = [self.ipDomains objectForKey:cUrl.host];\n        \n        __weak typeof(self) weakSelf = self;\n        __weak typeof(existSession)weakSession = existSession;\n        [existSession setCompletionCallback:^(NSString *sessionID){\n            [weakSession cancel];\n            [weakSelf.tasks removeObjectForKey:sessionID];\n        }];\n        \n        [self.tasks setObject:existSession forKey:existSession.sessionID];\n        [existSession start];\n        [existSession release];\n\n    } else {\n        \n        if (existSession.delegate == nil) {\n            existSession.delegate = aWebDelegate;\n        }\n    }\n    \n    [self.lock unlock];\n}\n\n\n- (SonicSession *)sessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate\n{\n    if (!ValidateSessionDelegate(aWebDelegate)) {\n        return nil;\n    }\n    \n    SonicSession *findSession = nil;\n    \n    [self.lock lock];\n    for (SonicSession *session in self.tasks.allValues) {\n        if (session.delegate == aWebDelegate) {\n            findSession = session;\n            break;\n        }\n    }\n    [self.lock unlock];\n    \n    return findSession;\n}\n\n- (SonicSession *)sessionWithDelegateId:(NSString *)delegateId\n{\n    SonicSession *findSession = nil;\n    if (delegateId.length != 0) {\n        [self.lock lock];\n        for (SonicSession *session in self.tasks.allValues) {\n            if ([delegateId isEqualToString:session.delegateId]) {\n                findSession = session;\n                break;\n            }\n        }\n        [self.lock unlock];\n    }\n    return findSession;\n}\n\n- (BOOL)reloadSessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate completion:(SonicWebviewCallBack)resultBlock\n{\n    SonicSession *findSession = [self sessionWithWebDelegate:aWebDelegate];\n    if (!findSession) {\n        return NO;\n    }\n    findSession.updateCallBack = resultBlock;\n    [findSession update];\n    return YES;\n}\n\n- (SonicSession *)sessionById:(NSString *)sessionId\n{\n    SonicSession *session = nil;\n    [self.lock lock];\n    session = self.tasks[sessionId];\n    [self.lock unlock];\n    return session;\n}\n\n- (void)removeSessionWithWebDelegate:(id<SonicSessionDelegate>)aWebDelegate\n{\n    if (!ValidateSessionDelegate(aWebDelegate)) {\n        return;\n    }\n    \n    [self.lock lock];\n    SonicSession *findSession = nil;\n    for (SonicSession *session in self.tasks.allValues) {\n        if (session.delegate == aWebDelegate) {\n            findSession = session;\n            break;\n        }\n    }\n    \n    if (findSession) {\n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionDestroy withEventInfo:@{@\"url\":findSession.url,@\"sessionID\":findSession.sessionID}];\n        [findSession cancel];\n        [self.tasks removeObjectForKey:findSession.sessionID];\n    }\n    [self.lock unlock];\n    \n    //Auto check root cache size\n    [[SonicCache shareCache] checkAndTrimCache];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSPrincipalClass</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicConnection.h",
    "content": "//\n//  SonicConnection.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicProtocol.h\"\n#import \"SonicConnection.h\"\n\n/**\n * Subclass this class to request the network data from custom connection.\n */\n\n@interface SonicConnection : NSObject\n\n/** Current request. */\n@property (nonatomic,retain)NSURLRequest *request;\n\n/** Use this protocal to transfer data to sonic session. */\n@property (nonatomic,assign)id<SonicConnectionDelegate> delegate;\n\n/** Queue for connection delegate operation. */\n@property (nonatomic,retain) NSOperationQueue* delegateQueue;\n\n/** HTTPSession redirection support, Default is NO */\n@property (nonatomic,assign) BOOL supportHTTPRedirection;\n\n/**\n * Check if this request class can use SonicConnection to load\n \n * @param request the request passed by the SonicSession\n */\n+ (BOOL)canInitWithRequest:(NSURLRequest *)request;\n\n/**\n * SonicSession will pass the request to the connection\n \n * @param aRequest the request passed by the SonicSession\n* @param queue The queue which delegate operation will be called.\n */\n- (instancetype)initWithRequest:(NSURLRequest *)aRequest delegate:(id<SonicConnectionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;\n\n/**\n * Start request\n */\n- (void)startLoading;\n\n/** \n * Cancel request\n */\n- (void)stopLoading;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicConnection.m",
    "content": "//\n//  SonicConnection.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicConnection.h\"\n\n@interface SonicConnection ()<NSURLSessionDelegate, NSURLSessionDataDelegate>\n\n@property (nonatomic,retain)NSURLSession *dataSession;\n@property (nonatomic,retain)NSURLSessionDataTask *dataTask;\n\n@end\n\n@implementation SonicConnection\n\n+ (BOOL)canInitWithRequest:(NSURLRequest *)request\n{\n    return YES;\n}\n\n- (instancetype)initWithRequest:(NSURLRequest *)aRequest delegate:(id<SonicConnectionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue\n{\n    if (self == [super init]) {\n        self.request = aRequest;\n        self.delegate = delegate;\n        self.delegateQueue = queue;\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [self stopLoading];\n    \n    [_request release];\n    _request = nil;\n    \n    self.dataTask = nil;\n    self.dataSession = nil;\n    \n    [super dealloc];\n}\n\n- (void)startLoading\n{\n    NSURLSessionConfiguration *sessionCfg = [NSURLSessionConfiguration defaultSessionConfiguration];\n    sessionCfg.requestCachePolicy = NSURLRequestReloadIgnoringCacheData;\n    /**\n     * NSURLSession will retain it's delegate,so you must remember do cancel action to avoid memory leak\n     */\n    self.dataSession = [NSURLSession sessionWithConfiguration:sessionCfg delegate:self delegateQueue:self.delegateQueue];\n    self.dataTask = [self.dataSession dataTaskWithRequest:self.request];\n    [self.dataTask resume];\n}\n\n- (void)stopLoading\n{\n    self.delegate = nil;\n    //fix:https://github.com/Tencent/VasSonic/issues/253\n    for (NSOperation *operation in self.delegateQueue.operations) {\n        [operation cancel];\n    }\n    self.delegateQueue = nil;\n    \n    if (self.dataTask && self.dataTask.state == NSURLSessionTaskStateRunning) {\n        [self.dataTask cancel];\n        [self.dataSession finishTasksAndInvalidate];\n    }else{\n        [self.dataSession invalidateAndCancel];\n    }\n}\n\n#pragma mark - NSURLSessionDelegate\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error\n{\n    // Fix case:statusCode is 304 but [error] is not nil.\n    if (error) {\n        NSHTTPURLResponse *tmpResponse = (NSHTTPURLResponse *)task.response;\n        if (304 == tmpResponse.statusCode) {\n            error = nil;\n        }\n    }\n    \n    if (error) {\n        [self.delegate connection:self didCompleteWithError:error];\n    } else {\n        [self.delegate connectionDidCompleteWithoutError:self];\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task\ndidReceiveChallenge:(NSURLAuthenticationChallenge *)challenge\n completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler\n{\n    SecTrustRef trust = challenge.protectionSpace.serverTrust;\n    SecTrustResultType result;\n    NSString *host = [[task currentRequest] valueForHTTPHeaderField:@\"host\"];\n    \n    SecPolicyRef policyOverride = SecPolicyCreateSSL(true, (CFStringRef)host);\n    NSMutableArray *policies = [NSMutableArray array];\n    [policies addObject:(__bridge id)policyOverride];\n    SecTrustSetPolicies(trust, (__bridge CFArrayRef)policies);\n    CFRelease(policyOverride);\n    \n    OSStatus status = SecTrustEvaluate(trust, &result);\n    \n    if (status == errSecSuccess && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) {\n        NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];\n        completionHandler(NSURLSessionAuthChallengeUseCredential, cred);\n    } else {\n        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask\ndidReceiveResponse:(NSURLResponse *)response\n completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler\n{\n    completionHandler(NSURLSessionResponseAllow);\n    [self.delegate connection:self didReceiveResponse:(NSHTTPURLResponse *)response];\n}\n\n- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler\n{\n    if (!self.supportHTTPRedirection) {\n        completionHandler(nil);\n        // Since HTTPRedirection may preform middle-page, HTTPRedirection is not support in Sonic now.\n        NSError *redirectErr = [NSError errorWithDomain:@\"com.sonic.connection\" code:302 userInfo:@{@\"msg\":@\"sonic is not support HTTPRedirection!\"}];\n        [self.delegate connection:self didCompleteWithError:redirectErr];\n    }else{\n        completionHandler(request);\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask\n    didReceiveData:(NSData *)data\n{\n    [self.delegate connection:self didReceiveData:data];\n}\n\n- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error\n{\n    if (error) {\n        [self.delegate connection:self didCompleteWithError:error];\n    }\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicServer.h",
    "content": "//\n//  SonicServer.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n#import <Foundation/Foundation.h>\n#import \"SonicConnection.h\"\n#import \"SonicProtocol.h\"\n\n/**\n * SonicServer is a middle-layer or called proxy-layer which uses to pretreatment with connection request and response data,\n * SonicServer can be a local sonic-supported server if session enable local-server mode.\n */\n@interface SonicServer : NSObject\n\n@property (nonatomic,readonly)NSMutableURLRequest *request;\n\n@property (nonatomic,readonly)NSHTTPURLResponse *response;\n\n@property (nonatomic,readonly)NSMutableData *responseData;\n\n@property (nonatomic,readonly)NSError *error;\n\n@property (nonatomic,readonly)BOOL isInLocalServerMode;\n\n@property (nonatomic,readonly)BOOL isRuning;\n\n/**\n * Register a SonicConnection Class to provide network data.\n */\n+ (BOOL)registerSonicConnection:(Class)connectionClass;\n\n/**\n * Unregister the SonicConnection.\n */\n+ (void)unregisterSonicConnection:(Class)connectionClass;\n\n/**\n * Which connection class can intercept the request.\n */\n+ (Class)connectionClassForRequest:(NSURLRequest *)aRequest;\n\n/**\n * SonicServer init with params\n * @param url The target url which will request\n * @param delegate The delegate which will receiver server operation notifies\n * @param queue The queue which delegate operation will be called.\n */\n- (instancetype)initWithUrl:(NSString *)url delegate:(id<SonicServerDelegate>) delegate delegateQueue:(NSOperationQueue *) queue;\n\n/**\n * Set the specified field to the request header.\n */\n- (void)setRequestHeaderFields:(NSDictionary *)headers;\n\n/**\n * Add the specified field to the request header.\n */\n- (void)addRequestHeaderFields:(NSDictionary *)headers;\n\n/**\n * Set the specified field to the response header.\n */\n- (void)setResponseHeaderFields:(NSDictionary *)headers;\n\n/**\n * Get response header specified field for key.\n */\n- (NSString *)responseHeaderForKey:(NSString *)aKey;\n\n/**\n * Returns whether the Sonic response is currently valid.\n */\n- (BOOL)isSonicResponse;\n\n/**\n * Enable the local server mode.\n */\n- (void)enableLocalServer:(BOOL)enable;\n\n/**\n * Request data over the network.\n */\n- (void)start;\n\n/**\n * Cancel the request.\n */\n- (void)stop;\n\n/**\n * Get the sonic cache from the item\n */\n- (NSDictionary *)sonicItemForCache;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicServer.m",
    "content": "//\n//  SonicServer.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicServer.h\"\n#import \"SonicProtocol.h\"\n#import \"SonicSession.h\"\n#import \"SonicUtil.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\nstatic NSMutableArray *sonicRequestClassArray = nil;\nstatic NSLock *sonicRequestClassLock;\n\n@interface SonicServer()<SonicConnectionDelegate>\n\n/** Connection instance which uses to connect web-server. */\n@property (nonatomic,retain)SonicConnection *connection;\n\n/** Use this delegate to communicate with sonic session. */\n@property (nonatomic,assign)id<SonicServerDelegate> delegate;\n\n/** Queue for connection delegate operation. */\n@property (nonatomic,retain)NSOperationQueue* delegateQueue;\n\n@property (nonatomic,assign)BOOL enableLocalSever;\n\n@property (nonatomic,retain)NSDictionary *customResponseHeaders;\n\n@property (nonatomic,assign)BOOL isCompletion;\n\n/** htmlString -> templateString + data. */\n@property (nonatomic,retain)NSString *htmlString;\n\n@property (nonatomic,retain)NSString *templateString;\n\n@property (nonatomic,retain)NSDictionary *data;\n\n/**\n * Use to hold all block operation in sonic session queue\n * We need to cancel before the SonicSession dealloc\n */\n@property (nonatomic,retain)NSMutableArray *sonicQueueOperationIdentifiers;\n\n@end\n\n@implementation SonicServer\n\n- (instancetype)initWithUrl:(NSString *)url delegate:(id<SonicServerDelegate>) delegate delegateQueue:(NSOperationQueue *) queue\n{\n    if (self == [super init]) {\n        self.delegate = delegate;\n        self.delegateQueue = queue;\n        self.sonicQueueOperationIdentifiers = [NSMutableArray array];\n        _request = [[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]] retain];\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    self.delegate = nil;\n    \n    if (nil != self.connection) {\n        [self.connection stopLoading];\n        self.connection = nil;\n    }\n    \n    //remove operation relation this session in SonicSessionQueue and mainQueue\n    NSMutableArray *opNeedCancel = [NSMutableArray array];\n    \n    //cancel operation from sonic session queue\n    for (NSString *opIdentifier in self.sonicQueueOperationIdentifiers) {\n        for (NSOperation *op in [SonicSession sonicSessionQueue].operations) {\n            if (op.hash == [opIdentifier integerValue]) {\n                [opNeedCancel addObject:op];\n            }\n        }\n    }\n    \n    //cancel op now\n    [opNeedCancel enumerateObjectsUsingBlock:^(NSOperation *op, NSUInteger idx, BOOL * _Nonnull stop) {\n        [op cancel];\n    }];\n    self.sonicQueueOperationIdentifiers = nil;\n    \n    if (nil != _request) {\n        [_request release];\n        _request = nil;\n    }\n    \n    if (nil != _response) {\n        [_response release];\n        _request = nil;\n    }\n    \n    if (nil != _error) {\n        [_error release];\n        _error = nil;\n    }\n    \n    self.delegateQueue = nil;\n    self.customResponseHeaders = nil;\n    self.htmlString = nil;\n    self.templateString = nil;\n    self.data = nil;\n    \n    [super dealloc];\n}\n\n- (void)enableLocalServer:(BOOL)enable\n{\n    self.enableLocalSever = enable;\n}\n\n+ (Class)canCustomRequest:(NSURLRequest *)aRequest\n{\n    Class findDestClass = nil;\n    \n    for (NSInteger index = sonicRequestClassArray.count - 1; index >= 0; index--) {\n        \n        Class itemClass = sonicRequestClassArray[index];\n        \n        NSMethodSignature *sign = [itemClass methodSignatureForSelector:@selector(canInitWithRequest:)];\n        NSInvocation *invoke = [NSInvocation invocationWithMethodSignature:sign];\n        invoke.target = itemClass;\n        NSURLRequest *argRequest = aRequest;\n        [invoke setArgument:&argRequest atIndex:2];\n        invoke.selector = @selector(canInitWithRequest:);\n        [invoke invoke];\n        \n        BOOL canCustomRequest;\n        [invoke getReturnValue:&canCustomRequest];\n        \n        if (canCustomRequest) {\n            findDestClass = itemClass;\n            break;\n        }\n    }\n    \n    return findDestClass;\n}\n\n+ (Class)connectionClassForRequest:(NSURLRequest *)aRequest\n{\n    Class customRequest = [SonicServer canCustomRequest:aRequest];\n    if (!customRequest) {\n        // If there no custom request ,then use the default\n        customRequest = [SonicConnection class];\n    }\n    return customRequest;\n}\n\n- (void)start\n{\n    _isRuning = YES;\n    if (nil != self.connection) {\n        [self.connection stopLoading];\n        self.connection = nil;\n    }\n    Class customRequest = [SonicServer connectionClassForRequest:self.request];\n    SonicConnection *tConnect = [[customRequest alloc]initWithRequest:self.request delegate: self delegateQueue:self.delegateQueue];\n    tConnect.supportHTTPRedirection = YES;\n    self.connection = tConnect;\n    [tConnect release];\n    [self.connection startLoading];\n}\n\n- (void)stop\n{\n    self.delegateQueue = nil;\n    self.delegate = nil;\n    \n    if (self.connection) {\n       [self.connection stopLoading];\n    }\n}\n\n+ (BOOL)registerSonicConnection:(Class)connectionClass\n{\n    if (![connectionClass isSubclassOfClass:[SonicConnection class]]) {\n        return NO;\n    }\n    \n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        if (!sonicRequestClassArray) {\n            sonicRequestClassArray = [[NSMutableArray alloc]init];\n            sonicRequestClassLock = [NSLock new];\n        }\n    });\n    \n    [sonicRequestClassLock lock];\n    if ([sonicRequestClassArray containsObject:connectionClass]) {\n        if (sonicRequestClassArray.lastObject != connectionClass) {\n            [sonicRequestClassArray removeObject:connectionClass]; // remove old object\n            [sonicRequestClassArray addObject:connectionClass]; // add to last position\n        }\n    } else {\n        [sonicRequestClassArray addObject:connectionClass]; // add to last position\n    }\n    [sonicRequestClassLock unlock];\n    return YES;\n}\n\n+ (void)unregisterSonicConnection:(Class)connectionClass\n{\n    [sonicRequestClassLock lock];\n    if ([sonicRequestClassArray containsObject:connectionClass]) {\n        [sonicRequestClassArray removeObject:connectionClass];\n    }\n    [sonicRequestClassLock unlock];\n}\n\n- (void)setRequestHeaderFields:(NSDictionary *)headers\n{\n    NSMutableDictionary *requestHeaderFileds = [NSMutableDictionary dictionaryWithDictionary:self.request.allHTTPHeaderFields];\n    [requestHeaderFileds setObject:@\"true\" forKey:@\"accept-diff\"];\n    [requestHeaderFileds setObject:@\"GET\" forKey:@\"method\"];\n    [requestHeaderFileds setObject:@\"utf-8\" forKey:@\"accept-Encoding\"];\n    [requestHeaderFileds setObject:@\"zh-CN,zh;\" forKey:@\"accept-Language\"];\n    [requestHeaderFileds setObject:@\"gzip\" forKey:@\"accept-Encoding\"];\n    [requestHeaderFileds setObject:SonicHeaderValueSDKVersion  forKey:SonicHeaderKeySDKVersion];\n    [requestHeaderFileds setObject:SonicHeaderValueSonicLoad forKey:SonicHeaderKeyLoadType];\n    [requestHeaderFileds addEntriesFromDictionary:headers];\n    [self.request setAllHTTPHeaderFields:requestHeaderFileds];\n}\n\n- (void)setResponseHeaderFields:(NSDictionary *)headers\n{\n    self.customResponseHeaders = headers;\n}\n\n- (NSStringEncoding)encodingFromHeaders\n{\n    //content-type: text/html; charset=utf-8\n    NSString *contentType = [[self responseHeaderForKey:[HTTPHeaderKeyContentType lowercaseString]] lowercaseString];\n    if ([contentType containsString:@\"charset=\"]) {\n        NSRange charsetRange = [contentType rangeOfString:@\"charset=\"];\n        NSString *charsetString = [contentType substringFromIndex: charsetRange.location + charsetRange.length];\n        if ([charsetString containsString:@\";\"] || [charsetString containsString:@\" \"]) {\n            charsetString = [charsetString substringToIndex:charsetString.length - 1];\n        }\n        NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef) charsetString));\n        if (kCFStringEncodingInvalidId != encoding) {\n            return encoding;\n        }\n    }\n    return NSUTF8StringEncoding;\n}\n\n- (void)addRequestHeaderFields:(NSDictionary *)headers\n{\n    NSMutableDictionary *requestHeaderFileds = [NSMutableDictionary dictionaryWithDictionary:self.request.allHTTPHeaderFields];\n    [requestHeaderFileds addEntriesFromDictionary:headers];\n    [self.request setAllHTTPHeaderFields:requestHeaderFileds];\n}\n\n- (NSString *)responseHeaderForKey:(NSString *)aKey\n{\n    NSString *header = nil;\n    if (_response) {\n        header = [_response.allHeaderFields objectForKey:[aKey lowercaseString]];\n    }\n    return header;\n}\n\n- (NSString *)getSonicHeaderETagWithHeaders:(NSDictionary *)headers\n{\n    NSString *keyETag = [headers objectForKey:[SonicHeaderKeyCustomeETag lowercaseString]];\n    if (keyETag && [keyETag isKindOfClass:[NSString class]] && keyETag.length > 0) {\n        // do nothing\n    } else {\n        keyETag = [SonicHeaderKeyETag lowercaseString];\n    }\n    \n    return [headers objectForKey:keyETag];\n}\n\n- (NSDictionary *)sonicItemForCache\n{\n    if (self.isCompletion) {\n        if (nil == _error) {\n            NSMutableDictionary *sonicItemDict = [NSMutableDictionary dictionary];\n            if (0 == self.htmlString.length) { // not split yet\n                self.htmlString = [[[NSString alloc]initWithData:self.responseData encoding:[self encodingFromHeaders]] autorelease];\n                NSDictionary *splitResult = [SonicUtil splitTemplateAndDataFromHtmlData:self.htmlString];\n                self.templateString = splitResult[kSonicTemplateFieldName];\n                self.data = splitResult[kSonicDataFieldName];\n                \n                NSMutableDictionary *headers = [[_response.allHeaderFields mutableCopy]autorelease];\n                NSString *responseEtag = [self getSonicHeaderETagWithHeaders:headers];\n                if (!responseEtag) {\n                    responseEtag = getDataSha1([self.htmlString dataUsingEncoding:NSUTF8StringEncoding]);\n                    [headers setObject:responseEtag forKey:[SonicHeaderKeyETag lowercaseString]];\n                }\n                \n                NSString *responseTemplateTag = [headers objectForKey:[SonicHeaderKeyTemplate lowercaseString]];\n                if (!responseTemplateTag) {\n                    responseTemplateTag = getDataSha1([self.templateString dataUsingEncoding:NSUTF8StringEncoding]);\n                    [headers setValue:responseTemplateTag forKey:[SonicHeaderKeyTemplate lowercaseString]];\n                }\n                \n                [headers setValue:false forKey:[SonicHeaderKeyTemplateChange lowercaseString]];\n                \n                [sonicItemDict addEntriesFromDictionary:splitResult];\n                [sonicItemDict setValue:self.htmlString forKey:kSonicHtmlFieldName];\n                \n                NSHTTPURLResponse *newResponse = [[[NSHTTPURLResponse alloc]initWithURL:_response.URL statusCode:200 HTTPVersion:nil headerFields:headers]autorelease];\n                [_response release];\n                _response = nil;\n                _response = [newResponse retain];\n            } else {\n                [sonicItemDict setValue:self.htmlString forKey:kSonicHtmlFieldName];\n                [sonicItemDict setValue:self.templateString forKey:kSonicTemplateFieldName];\n                [sonicItemDict setValue:self.data forKey:kSonicDataFieldName];\n            }\n            return sonicItemDict;\n        }\n        return nil;\n    }\n    SonicLogEvent(@\"sonicItemForCache warning:Should never call this function before connection did completion!\");\n    return nil;\n}\n\n#pragma Help functions\n\n- (BOOL)isValidateSonicResponse:(NSHTTPURLResponse *)response\n{\n    if ([response.allHeaderFields[SonicHeaderKeyCacheOffline] length] == 0) {\n        return NO;\n    }\n    \n    if ([[self getSonicHeaderETagWithHeaders:response.allHeaderFields] length] == 0) {\n        return NO;\n    }\n    \n    if ([response.allHeaderFields[SonicHeaderKeyTemplateChange] length] == 0) {\n        return NO;\n    }\n    \n    if ([response.allHeaderFields[SonicHeaderKeyTemplate] length] == 0) {\n        return NO;\n    }\n    \n    return YES;\n}\n\n- (BOOL)isFirstLoadRequest\n{\n    return [self.request.allHTTPHeaderFields objectForKey:@\"If-None-Match\"].length == 0;\n}\n\n- (BOOL)isSonicResponse\n{\n    return [self isValidateSonicResponse:self.response];\n}\n\n#pragma Sonic Connection Delegate\n\n/**\n * @brief Notify when the network connection did recieve response.\n */\n- (void)connection:(SonicConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response\n{\n    dispatch_block_t opBlock = ^{\n        // Make field names to lowercase string as Field names are case-insensitive.[https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2]\n        NSMutableDictionary *headers = [[[NSMutableDictionary alloc] init] autorelease];\n        if (self.customResponseHeaders.count > 0) {\n            for (NSString *key in self.customResponseHeaders.allKeys) {\n                [headers setValue:[self.customResponseHeaders objectForKey:key] forKey:[key lowercaseString]];\n            }\n        }\n        for (NSString *key in response.allHeaderFields.allKeys) {\n            [headers setObject:[response.allHeaderFields objectForKey:key] forKey:[key lowercaseString]];\n        }\n        \n        // fix Weak-Etag case like -> etag: W/\"66f0-m2UmCBEh78dNYPv+boO5ETXk4FU\".[https://github.com/Tencent/VasSonic/issues/128]\n        NSString *eTag = [self getSonicHeaderETagWithHeaders:headers];\n        if ([eTag hasPrefix:@\"W/\"] && eTag.length > 3) {\n            // fix Weak-Etag get value length error\n            NSString *eTagValue = [eTag substringFromIndex:2];\n            if ([eTagValue hasPrefix:@\"\\\"\"] && [eTagValue hasSuffix:@\"\\\"\"] && eTagValue.length > 3) {\n                eTagValue = [eTagValue substringWithRange:NSMakeRange(1, eTagValue.length - 2)];\n            }\n            [headers setValue:eTagValue forKey:[SonicHeaderKeyETag lowercaseString]];\n        }\n        \n        NSHTTPURLResponse *newResponse = [[[NSHTTPURLResponse alloc]initWithURL:response.URL statusCode:response.statusCode HTTPVersion:nil headerFields:headers]autorelease];\n        \n        _response = [newResponse retain];\n        \n        // Not sonic response and enabel local-server\n        if ((response.statusCode == 304 || ![self isValidateSonicResponse:response]) && self.enableLocalSever) {\n            _isInLocalServerMode = true;\n            if (![self isFirstLoadRequest]) {\n                return; // not first load request just return util all data are received.\n            }\n        }\n        \n        [self.delegate server:self didRecieveResponse:newResponse];\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n/**\n * @brief Notify when the network connection did recieve data.\n */\n- (void)connection:(SonicConnection *)connection didReceiveData:(NSData *)data\n{\n    dispatch_block_t opBlock = ^{\n        if (data) {\n            \n            if (nil == _responseData) {\n                _responseData = [[NSMutableData data] retain];\n            }\n            NSData *copyData = [data copy];\n            [_responseData appendData:copyData];\n            [copyData release];\n            \n            if ([self isFirstLoadRequest] || !self.isInLocalServerMode) {\n                [self.delegate server:self didReceiveData:data];\n            }\n        }\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n/**\n * @brief Call when the network connection did success.\n */\n- (void)connectionDidCompleteWithoutError:(SonicConnection *)connection\n{\n    dispatch_block_t opBlock = ^{\n        self.isCompletion = YES;\n        if (self.isInLocalServerMode) {\n            \n            do {\n                \n                //if http status is 304, there is nothing changed\n                if (self.response.statusCode == 304) {\n                    SonicLogEvent(@\"Response status 304!\");\n                    break;\n                }\n                \n                self.htmlString = [[[NSString alloc]initWithData:self.responseData encoding:[self encodingFromHeaders]] autorelease];\n                NSDictionary *splitResult = [SonicUtil splitTemplateAndDataFromHtmlData:self.htmlString];\n                if (splitResult) {\n                    self.templateString = splitResult[kSonicTemplateFieldName];\n                    self.data = splitResult[kSonicDataFieldName];\n                }\n                \n                NSMutableDictionary *headers = [[_response.allHeaderFields mutableCopy]autorelease];\n                \n                if (![headers objectForKey:SonicHeaderKeyCacheOffline]) { // refresh this time\n                    [headers setValue:@\"true\" forKey:[SonicHeaderKeyCacheOffline lowercaseString]];\n                }\n                NSString *htmlSha1 = nil;\n                NSString *responseEtag = [self getSonicHeaderETagWithHeaders:headers];\n                if (!responseEtag) {\n                    responseEtag = htmlSha1 = getDataSha1([self.htmlString dataUsingEncoding:NSUTF8StringEncoding]);\n                    [headers setObject:responseEtag forKey:[SonicHeaderKeyETag lowercaseString]];\n                }\n                NSString *requestEtag = [self.request.allHTTPHeaderFields objectForKey:HTTPHeaderKeyIfNoneMatch];\n                if ([responseEtag isEqualToString:requestEtag]) { // Case:hit 304\n                    [headers setValue:@\"false\" forKey:[SonicHeaderKeyTemplateChange lowercaseString]];\n                    NSHTTPURLResponse *newResponse = [[[NSHTTPURLResponse alloc]initWithURL:_response.URL statusCode:304 HTTPVersion:nil headerFields:headers]autorelease];\n                    // Update response data\n                    [_response release];\n                    _response = nil;\n                    _response = [newResponse retain];\n                    [_responseData release];\n                    _responseData = nil;\n                    break;\n                }\n                \n                NSString *responseTemplateTag = [headers objectForKey:[SonicHeaderKeyTemplate lowercaseString]];\n                if (!responseTemplateTag) {\n                    responseTemplateTag = getDataSha1([self.templateString dataUsingEncoding:NSUTF8StringEncoding]);\n                    [headers setValue:responseTemplateTag forKey:[SonicHeaderKeyTemplate lowercaseString]];\n                }\n                NSString *requestTemplateTag = [self.request.allHTTPHeaderFields objectForKey:SonicHeaderKeyTemplate];\n                if ([responseTemplateTag isEqualToString:requestTemplateTag]) { // Case:data update\n                    NSError *jsonError = nil;\n                    NSMutableDictionary *jsonDict = [NSMutableDictionary dictionaryWithDictionary:self.data];\n                    if (!htmlSha1) {\n                        htmlSha1 = getDataSha1([self.htmlString dataUsingEncoding:NSUTF8StringEncoding]);\n                    }\n                    [jsonDict setObject:htmlSha1 forKey:SonicHeaderKeyHtmlSha1];\n                    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:NSJSONWritingPrettyPrinted error:&jsonError];\n                    if (!jsonError) {\n                        [headers setValue:@\"false\" forKey:[SonicHeaderKeyTemplateChange lowercaseString]];\n                        NSHTTPURLResponse *newResponse = [[[NSHTTPURLResponse alloc]initWithURL:_response.URL statusCode:200 HTTPVersion:nil headerFields:headers]autorelease];\n                        // Update response data\n                        [_response release];\n                        _response = nil;\n                        _response = [newResponse retain];\n                        [_responseData release];\n                        _responseData = nil;\n                        NSMutableData *mJsonData = [jsonData mutableCopy];\n                        _responseData = [mJsonData retain];\n                        [mJsonData release];\n                        break;\n                    }\n                }\n                \n                // Case:template-change\n                [headers setValue:@\"true\" forKey:[SonicHeaderKeyTemplateChange lowercaseString]];\n                NSHTTPURLResponse *newResponse = [[[NSHTTPURLResponse alloc]initWithURL:_response.URL statusCode:200 HTTPVersion:nil headerFields:headers]autorelease];\n                [_response release];\n                _response = nil;\n                _response = [newResponse retain];\n                break;\n                \n            } while (true);\n            \n            //First request need't to load again\n            if (![self isFirstLoadRequest]) {\n                [self.delegate server:self didRecieveResponse:self.response];\n                [self.delegate server:self didReceiveData:self.responseData];\n            }\n        }\n        [self.delegate serverDidCompleteWithoutError:self];\n        _isRuning = NO;\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n/**\n * @brief Call when the network connection did fail.\n */\n- (void)connection:(SonicConnection *)connection didCompleteWithError:(NSError *)error\n{\n    dispatch_block_t opBlock = ^{\n        _error = [error retain]; // update error\n        self.isCompletion = YES;\n        if (self.isInLocalServerMode && ![self isFirstLoadRequest]) {\n            [self.delegate server:self didRecieveResponse:self.response];\n            [self.delegate server:self didReceiveData:self.responseData];\n        }\n        [self.delegate server:self didCompleteWithError:error];\n        _isRuning = NO;\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicURLProtocol.h",
    "content": "//\n//  SonicURLProtocol.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/** SubClass NSURLProtocol to intercept the webView request */\n@interface SonicURLProtocol : NSURLProtocol\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Network/SonicURLProtocol.m",
    "content": "//\n//  SonicURLProtocol.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicURLProtocol.h\"\n#import \"SonicConstants.h\"\n#import \"SonicEngine.h\"\n#import \"SonicUtil.h\"\n#import \"SonicResourceLoader.h\"\n\n@implementation SonicURLProtocol\n\n+ (BOOL)canInitWithRequest:(NSURLRequest *)request\n{\n    NSString *value = [request.allHTTPHeaderFields objectForKey:SonicHeaderKeyLoadType];\n    if (value.length != 0 && [value isEqualToString:SonicHeaderValueWebviewLoad]) {\n        NSString * delegateId = [request.allHTTPHeaderFields objectForKey:SonicHeaderKeyDelegateId];\n        if (delegateId.length != 0) {\n            NSString * sessionID = sonicSessionID(request.URL.absoluteString);\n            SonicSession *session = [[SonicEngine sharedEngine] sessionWithDelegateId:delegateId];\n            if (session && [sessionID isEqualToString:session.sessionID]) {\n                return YES;\n            }\n            SonicLogEvent(@\"SonicURLProtocol.canInitWithRequest error:Cannot find sonic session!\");\n        }\n    }\n    \n    //Sub resource intercept\n    NSString * sessionID = sonicSessionID(request.mainDocumentURL.absoluteString);\n    SonicSession *session = [[SonicEngine sharedEngine] sessionById:sessionID];\n    if (session.resourceLoader && [session.resourceLoader canInterceptResourceWithUrl:request.URL.absoluteString]) {\n        SonicLogEvent(@\"SonicURLProtocol resource should intercept:%@\",request.debugDescription);\n        return YES;\n    }\n    \n    return NO;\n}\n\n+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request\n{\n    return request;\n}\n\n- (void)startLoading\n{    \n    NSThread *currentThread = [NSThread currentThread];\n    \n    __weak typeof(self) weakSelf = self;\n    \n    NSString * sessionID = sonicSessionID(self.request.mainDocumentURL.absoluteString);\n    SonicSession *session = [[SonicEngine sharedEngine] sessionById:sessionID];\n    \n    if ([session.resourceLoader canInterceptResourceWithUrl:self.request.URL.absoluteString]) {\n        \n        SonicLogEvent(@\"protocol resource did start loading :%@\",self.request.debugDescription);\n\n        SonicSession *session = [[SonicEngine sharedEngine] sessionById:sessionID];\n        \n        [session.resourceLoader preloadResourceWithUrl:self.request.URL.absoluteString withProtocolCallBack:^(NSDictionary *param) {\n            [weakSelf performSelector:@selector(callClientActionWithParams:) onThread:currentThread withObject:param waitUntilDone:NO];\n        }];\n        \n    }else{\n       \n        NSString *sessionID = [self.request valueForHTTPHeaderField:SonicHeaderKeySessionID];\n\n        [[SonicEngine sharedEngine] registerURLProtocolCallBackWithSessionID:sessionID completion:^(NSDictionary *param) {\n            \n            [weakSelf performSelector:@selector(callClientActionWithParams:) onThread:currentThread withObject:param waitUntilDone:NO];\n            \n        }];\n        \n    }\n}\n\n- (void)stopLoading\n{\n    \n}\n\n- (void)dealloc\n{\n    [super dealloc];\n}\n\n#pragma mark - Client Action\n- (void)callClientActionWithParams:(NSDictionary *)params\n{\n    SonicURLProtocolAction action = [params[kSonicProtocolAction]integerValue];\n    switch (action) {\n        case SonicURLProtocolActionRecvResponse:\n        {\n            NSHTTPURLResponse *resp = params[kSonicProtocolData];\n            [self.client URLProtocol:self didReceiveResponse:resp cacheStoragePolicy:NSURLCacheStorageNotAllowed];\n        }\n            break;\n        case SonicURLProtocolActionLoadData:\n        {\n            NSData *recvData = params[kSonicProtocolData];\n            if (recvData.length > 0) {\n                [self.client URLProtocol:self didLoadData:recvData];\n                SonicLogEvent(@\"protocol did load data length:%ld\",recvData.length);\n            }\n        }\n            break;\n        case SonicURLProtocolActionDidSuccess:\n        {\n            [self.client URLProtocolDidFinishLoading:self];\n            SonicLogEvent(@\"protocol did finish loading request:%@\",self.request.debugDescription);\n        }\n            break;\n        case SonicURLProtocolActionDidFaild:\n        {\n            NSError *err = params[kSonicProtocolData];\n            [self.client URLProtocol:self didFailWithError:err];\n        }\n            break;\n    }\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/ResourceLoader/SonicResourceLoadOperation.h",
    "content": "//\n//  SonicResourceLoadOperation.h\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicSession.h\"\n\n@interface SonicResourceLoadOperation : NSOperation\n\n/**\n * Resource sessionID\n * It is the MD5 string with the url.\n */\n@property (nonatomic,readonly)NSString *sessionID;\n\n/**\n * The resource url.\n */\n@property (nonatomic,readonly)NSString *url;\n\n/**\n * NSURLProtocol layer use this call back to get the resource data.\n */\n@property (nonatomic,copy)SonicURLProtocolCallBack protocolCallBack;\n\n/**\n * Init an operation with the resource url.\n */\n- (instancetype)initWithUrl:(NSString *)aUrl;\n\n/**\n * NSURLProtocol layer call this function to get the resource data.\n */\n- (void)preloadDataWithProtocolCallBack:(SonicURLProtocolCallBack)callBack;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/ResourceLoader/SonicResourceLoadOperation.m",
    "content": "//\n//  SonicResourceLoadOperation.m\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicResourceLoadOperation.h\"\n#import \"SonicServer.h\"\n#import \"SonicResourceLoader.h\"\n#import \"SonicCache.h\"\n#import \"SonicUtil.h\"\n#import \"SonicConfiguration.h\"\n#import \"SonicEventStatistics.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n@interface SonicResourceLoadOperation()<SonicConnectionDelegate>\n\n@property (nonatomic,retain)SonicConnection *connection;\n\n@property (nonatomic,retain)NSData *cacheFileData;\n\n@property (nonatomic,retain)NSDictionary *cacheResponseHeaders;\n\n@property (nonatomic,retain)NSDictionary *config;\n\n@property (nonatomic,retain)NSMutableData *responseData;\n\n@property (nonatomic,retain)NSHTTPURLResponse *originResponse;\n\n@property (nonatomic,assign)BOOL isComplete;\n\n@property (nonatomic,retain)NSRecursiveLock *lock;\n\n\n@end\n\n@implementation SonicResourceLoadOperation\n\n- (instancetype)initWithUrl:(NSString *)aUrl\n{\n    if (self = [super init]) {\n        _url = [aUrl copy];\n        self.responseData = [NSMutableData data];\n        _sessionID = [resourceSessionID(_url) copy];\n        NSRecursiveLock *tmpLock = [NSRecursiveLock new];\n        self.lock = tmpLock;\n        [tmpLock release];\n    \n        self.config = [[SonicCache shareCache] resourceConfigWithSessionID:self.sessionID];\n        if (self.config) {\n            long long cacheExpire = [self.config[@\"cache-expire-time\"] longLongValue];\n            BOOL isCacheExpire = NO;\n            if (cacheExpire > 0) {\n                long long now = (long long)[[NSDate date] timeIntervalSince1970];\n                isCacheExpire = cacheExpire <= now;\n            }\n            if (isCacheExpire) {\n                self.config = nil;\n                SonicLogEvent(@\"resource expire:%@\",self.url);\n            }else{\n                self.cacheFileData = [[SonicCache shareCache] resourceCacheWithSessionID:self.sessionID];\n                NSString *cacheFileSha1 = getDataSha1(self.cacheFileData);\n                NSString *sha1 = self.config[@\"sha1\"];\n                if ([cacheFileSha1 isEqualToString:sha1]) {\n                    self.cacheResponseHeaders = [[SonicCache shareCache] responseHeadersWithSessionID:self.sessionID];\n                    //event\n                    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SubResourceLoadLocalCache withEventInfo:@{\n                                                                                                                                    @\"url\":self.url,\n                                                                                                                        @\"dataLength\":@(self.cacheFileData.length)\n                                                                                                                                    }];\n                }else{\n                    self.cacheFileData = nil;\n                    self.config = nil;\n                    SonicLogEvent(@\"resource sha1 wrong:%@\",self.url);\n                }\n            }\n        }\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [self cancel];\n    self.lock = nil;\n    [_url release];\n    _url = nil;\n    [_sessionID release];\n    _sessionID = nil;\n    self.responseData = nil;\n    self.cacheFileData = nil;\n    self.originResponse = nil;\n    self.protocolCallBack = nil;\n    self.cacheResponseHeaders = nil;\n    [super dealloc];\n}\n\n- (void)preloadDataWithProtocolCallBack:(SonicURLProtocolCallBack)callBack\n{\n    if (!callBack) {\n        return;\n    }\n    NSDictionary *rspItem = nil;\n    NSDictionary *dataItem = nil;\n    NSDictionary *finishItem = nil;\n    NSMutableArray *actions = [NSMutableArray array];\n    if (self.cacheFileData && self.cacheFileData.length > 0 && self.cacheResponseHeaders.count > 0) {\n        NSHTTPURLResponse *resp = [[[NSHTTPURLResponse alloc]initWithURL:[NSURL URLWithString:self.url] statusCode:200 HTTPVersion:@\"HTTP/1.1\" headerFields:self.cacheResponseHeaders]autorelease];\n        rspItem = [SonicUtil protocolActionItem:SonicURLProtocolActionRecvResponse param:resp];\n        [self.lock lock];\n        dataItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:self.cacheFileData];\n        [self.lock unlock];\n        finishItem = [SonicUtil protocolActionItem:SonicURLProtocolActionDidSuccess param:nil];\n        SonicLogEvent(@\"resource read from cache:%@\",self.url);\n        [actions addObjectsFromArray:@[rspItem,dataItem,finishItem]];\n    }else{\n        if (self.isComplete) {\n            [self.lock lock];\n            rspItem = [SonicUtil protocolActionItem:SonicURLProtocolActionRecvResponse param:self.originResponse];\n            dataItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:self.responseData];\n            [self.lock unlock];\n            finishItem = [SonicUtil protocolActionItem:SonicURLProtocolActionDidSuccess param:nil];\n            SonicLogEvent(@\"resource read from network:%@\",self.url);\n            [actions addObjectsFromArray:@[rspItem,dataItem,finishItem]];\n        }else{\n            [self.lock lock];\n            if (self.originResponse) {\n                rspItem = [SonicUtil protocolActionItem:SonicURLProtocolActionRecvResponse param:self.originResponse];\n                [actions addObject:rspItem];\n            }\n            if (self.responseData.length> 0) {\n                dataItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:self.responseData];\n                [actions addObject:dataItem];\n            }\n            [self.lock unlock];\n            SonicLogEvent(@\"resource read from network preload:%@\",self.url);\n        }\n    }\n    self.protocolCallBack = callBack;\n    for (NSInteger index = 0; index < actions.count; index ++){\n        NSDictionary *item = actions[index];\n        self.protocolCallBack(item);\n    }\n}\n\n\n\n- (void)cancel\n{\n    self.lock = nil;\n    if (self.connection) {\n        self.connection.delegate = nil;\n        [self.connection stopLoading];\n        self.connection = nil;\n    }\n    [super cancel];\n}\n\n- (void)main\n{\n    if (!self.cacheFileData || self.cacheFileData.length == 0) {\n        [self startRequest];\n    }\n}\n\n- (void)startRequest\n{\n    if (_url.length == 0) {\n        return;\n    }\n    \n    //build request\n    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:self.url]];\n    \n    //sync cookie\n    dispatch_async(dispatch_get_main_queue(), ^{\n        NSURL *cUrl = [NSURL URLWithString:self.url];\n        NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];\n        NSArray *cookies = [sharedHTTPCookieStorage cookiesForURL:cUrl];\n        NSDictionary *cookieHeader = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];\n        if (nil != cookies) {\n            NSMutableDictionary *requestHeader = [NSMutableDictionary dictionaryWithDictionary:request.allHTTPHeaderFields];\n            [requestHeader addEntriesFromDictionary:cookieHeader];\n            request.allHTTPHeaderFields = requestHeader;\n        }\n    });\n    \n    //Allow custom class to intercept the request\n    Class connectionClass = [SonicServer connectionClassForRequest:request];\n    SonicConnection *tmpConnection = [[connectionClass alloc] initWithRequest:request delegate:self delegateQueue:[NSOperationQueue currentQueue]];\n    self.connection = tmpConnection;\n    [tmpConnection release];\n    self.connection.supportHTTPRedirection = YES;\n    [self.connection startLoading];\n    [request release];\n}\n\n- (void)appendData:(NSData *)data\n{\n    [self.lock lock];\n    [self.responseData appendData:data];\n    [self.lock unlock];\n}\n\n#pragma mark - connection delegate\n\n- (void)connection:(SonicConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response\n{\n    [self.lock lock];\n    self.originResponse = response;\n    [self.lock unlock];\n    [self disaptchProtocolAction:SonicURLProtocolActionRecvResponse withParam:response];\n}\n\n- (void)connection:(SonicConnection *)connection didReceiveData:(NSData *)data\n{\n    [self disaptchProtocolAction:SonicURLProtocolActionLoadData withParam:data];\n    [self appendData:data];\n}\n\n- (void)connection:(SonicConnection *)connection didCompleteWithError:(NSError *)error\n{\n    SonicLogEvent(@\"resource recieve error:%@\",error.debugDescription);\n\n    [self disaptchProtocolAction:SonicURLProtocolActionDidFaild withParam:error];\n    self.isComplete = YES;\n    \n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SubResourceDidFail withEventInfo:@{\n                                                                                                             @\"msg\":@\"config create fail to save resource!\",\n                                                                                                             @\"url\":self.url,\n                                                                                                             @\"error\":error.debugDescription\n                                                                                                             }];\n}\n\n- (void)connectionDidCompleteWithoutError:(SonicConnection *)connection\n{\n    [self disaptchProtocolAction:SonicURLProtocolActionDidSuccess withParam:nil];\n    \n    //save resource data\n    NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{\n        NSDictionary *config = [self createConfig];\n        if (config) {\n           [[SonicCache shareCache] saveSubResourceData:self.responseData withConfig:config withResponseHeaders:self.originResponse.allHeaderFields withSessionID:self.sessionID];\n            \n            NSDictionary *headersLog = self.originResponse.allHeaderFields? self.originResponse.allHeaderFields:[NSDictionary dictionary];\n            [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SubResourceDidSave withEventInfo:@{\n                                                                                                                     @\"url\":self.url,\n                                                                                                                     @\"resourceID\":self.sessionID,\n                                                                                                                     @\"dataLength\":@(self.responseData.length),\n                                                                                                                     @\"reseponse\":headersLog\n                                                                                                                     }];\n        }else{\n            SonicLogEvent(@\"config create fail to save resource:%@\",self.url);\n        }\n    }];\n    [[SonicCache subResourceQueue] addOperation:block];\n    \n    self.isComplete = YES;\n}\n\n- (void)disaptchProtocolAction:(SonicURLProtocolAction)action withParam:(NSObject *)param\n{\n    if (self.protocolCallBack) {\n        NSDictionary *item = [SonicUtil protocolActionItem:action param:param];\n        self.protocolCallBack(item);\n    }\n}\n\n- (NSDictionary *)createConfig\n{\n    NSDictionary *query = queryComponents(self.url);\n    NSString *maxAge = nil;\n    for (NSString *key in query.allKeys) {\n        NSString *lowcase = [key lowercaseString];\n        if ([lowcase isEqualToString:@\"max-age\"]) {\n            maxAge = query[key];\n            break;\n        }\n    }\n    //default resource expire time\n    unsigned long long maxAgeTime = maxAge.length > 0? [maxAge longLongValue]:0;\n    unsigned long long cacheExpireTime = maxAgeTime == 0? 0:currentTimeStamp() + maxAgeTime;\n    NSString *tmpSha1 = getDataSha1(self.responseData);\n    if (tmpSha1.length == 0) {\n        return nil;\n    }\n    return @{@\"sha1\":tmpSha1,@\"cache-expire-time\":[@(cacheExpireTime) stringValue]};\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/ResourceLoader/SonicResourceLoader.h",
    "content": "//\n//  SonicResourceLoader.h\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicSession.h\"\n\n#define kSonicResourceVersion @\"sonic_ts\"\n\n@interface SonicResourceLoader : NSObject\n\n/**\n * Quit all requests.\n */\n- (void)cancelAll;\n\n/**\n * Is it possible to block specific resource links by url.\n */\n- (BOOL)canInterceptResourceWithUrl:(NSString *)url;\n\n/**\n * Load the specified resource link from array.\n */\n- (void)loadResourceLinks:(NSArray *)links;\n\n/**\n * NSURLProtocol layer to read the resource link data.\n */\n- (void)preloadResourceWithUrl:(NSString *)url withProtocolCallBack:(SonicURLProtocolCallBack)callback;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/ResourceLoader/SonicResourceLoader.m",
    "content": "//\n//  SonicResourceLoader.m\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicResourceLoader.h\"\n#import \"SonicResourceLoadOperation.h\"\n#import \"SonicUtil.h\"\n#import \"SonicCache.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n@interface SonicResourceLoader()\n\n@property (nonatomic,retain)NSOperationQueue *operationQueue;\n\n@property (nonatomic,retain)NSMutableArray *preloadLinks;\n\n@property (nonatomic,retain)NSMutableArray *connections;\n\n@end\n\n@implementation SonicResourceLoader\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        self.preloadLinks = [NSMutableArray array];\n        self.connections = [NSMutableArray array];\n        NSOperationQueue *tmpQueue = [[NSOperationQueue alloc]init];\n        self.operationQueue = tmpQueue;\n        [tmpQueue release];\n        self.operationQueue.maxConcurrentOperationCount = 3;\n    }\n    return self;\n}\n\n- (void)cancelAll\n{\n    for (NSOperation *operation in self.operationQueue.operations) {\n        [operation cancel];\n    }\n    [self.connections removeAllObjects];\n}\n\n- (void)dealloc\n{\n    self.operationQueue = nil;\n    self.preloadLinks = nil;\n    self.connections = nil;\n    [super dealloc];\n}\n\n- (void)loadResourceLinks:(NSArray *)links\n{\n    for (NSString *url in links) {\n        [self loadResourceWithUrl:url];\n    }\n}\n\n- (BOOL)canInterceptResourceWithUrl:(NSString *)url\n{\n   if (url.length == 0) {\n        return NO;\n   }\n   return [_preloadLinks containsObject:url];\n}\n\n- (void)loadResourceWithUrl:(NSString *)url\n{\n    if (url.length == 0) {\n        return;\n    }\n    if (![_preloadLinks containsObject:url]) {\n        [_preloadLinks addObject:url];\n    }else{\n        return;\n    }\n    SonicResourceLoadOperation *operation = [[SonicResourceLoadOperation alloc] initWithUrl:url];\n    [self.connections addObject:operation];\n    [operation release];\n    [self.operationQueue addOperation:operation];\n}\n\n- (void)preloadResourceWithUrl:(NSString *)url withProtocolCallBack:(SonicURLProtocolCallBack)callback\n{\n    SonicResourceLoadOperation *findOperation = nil;\n    for (SonicResourceLoadOperation *item in self.connections) {\n        if([item.url isEqualToString:url]){\n            findOperation = item;\n            break;\n        }\n    }\n    if (!findOperation) {\n        return;\n    }\n    [findOperation preloadDataWithProtocolCallBack:callback];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Session/SonicSession.h",
    "content": "//\n//  SonicSession.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicProtocol.h\"\n#import \"SonicConstants.h\"\n#import \"SonicSessionConfiguration.h\"\n\n@class SonicResourceLoader;\n\n/**\n * SonicSession use this callback to transfer network data to SonicURLProtocol.\n * The parameters of the dictionary is:\n * @{\n *    kSonicProtocolAction:@(SonicURLProtocolActionRecvResponse),\n *    kSonicProtocolData:NSHTTPURLResponse\n *  }\n */\ntypedef void(^SonicURLProtocolCallBack) (NSDictionary *param);\n\n/**\n * SonicSession use this callback to transfer status data to webview.\n * @{\n *   code:304,\n *   srcCode:200,\n *   result:{},\n *   local_refresh_time:,\n *  }\n */\ntypedef void(^SonicWebviewCallBack)  (NSDictionary *result);\n\n/**\n * SonicSession use this callback to notify SonicEngine when it finished.\n */\ntypedef void(^SonicSessionCompleteCallback) (NSString *sessionID);\n\n/**\n * SonicEngine will create one SonicSession for each URL request.\n * SonicSession will get network data from SonicConnection and split HTML data to template and dynamic data.\n */\n@interface SonicSession : NSObject<SonicServerDelegate>\n\n/** If there is no memory cache and file cache exist */\n@property (nonatomic,assign)BOOL isFirstLoad;\n\n/** Url for current session */\n@property (nonatomic ,copy)NSString *url;\n\n/** Generated from MD5 of URL. */\n@property (nonatomic,readonly)NSString *sessionID;\n\n/** Generated from local dynamic data and sever dynamic data. */\n@property (nonatomic,readonly)NSDictionary *diffData;\n\n/** SonicSession use this callback to transfer network data to SonicURLProtocol. */\n@property (nonatomic,copy)SonicURLProtocolCallBack protocolCallBack;\n\n/** Notify the webView holder what happened during the connection.*/\n@property (nonatomic,assign)id<SonicSessionDelegate> delegate;\n\n/** A NSString value to identify SonicSessionDelegate*/\n@property (nonatomic,copy)NSString *delegateId;\n\n/** SonicSession use this callback to notify SonicEngine when it finished. */\n@property (nonatomic,copy)SonicSessionCompleteCallback completionCallback;\n\n/** SonicSession use this callback to transfer status data to webview. */\n@property (nonatomic,copy)SonicWebviewCallBack updateCallBack;\n\n/** Check if all data did finish updated*/\n@property (nonatomic,assign)BOOL isDataFetchFinished;\n\n/** Sonic status code. */\n@property (nonatomic,assign)SonicStatusCode sonicStatusCode;\n\n/** SonicSession use this callback to transfer status data to webview. */\n@property (nonatomic,copy)SonicWebviewCallBack webviewCallBack;\n\n/** Set this property to connect server directly with ip. Without this property sonic will connect to server with domain normally. */\n@property (nonatomic,copy)NSString *serverIP;\n\n/** Return the session configuration */\n@property (nonatomic,readonly)SonicSessionConfiguration *configuration;\n\n@property (nonatomic,readonly)SonicResourceLoader *resourceLoader;\n\n/**\n * Register a SonicConnection Class to provide network data.\n */\n+ (BOOL)registerSonicConnection:(Class)connectionClass;\n\n/**\n * Unregister the SonicConnection.\n */\n+ (void)unregisterSonicConnection:(Class)connectionClass;\n\n/**\n * Queue to handle network data.\n */\n+ (NSOperationQueue *)sonicSessionQueue;\n\n/**\n * Execute block in sonic session queue.\n * Return block operation hash string\n */\nNSString * dispatchToSonicSessionQueue(dispatch_block_t block);\n\n/**\n * Use an url and webDelegate to create an session\n * The webDelegate can be nil value\n */\n- (instancetype)initWithUrl:(NSString *)aUrl withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate Configuration:(SonicSessionConfiguration *)aConfiguration;\n\n/**\n * Start request.\n */\n- (void)start;\n\n/**\n * Cancel request\n * You must invoke this method before dealloc the session,\n * beacause it has been retained by the NSURLSession, or it will be leaked.\n */\n- (void)cancel;\n\n/**\n * update current session by send request\n */\n- (BOOL)update;\n\n/**\n * It provide the network data by the protocolCallBack block\n */\n- (void)preloadRequestActionsWithProtocolCallBack:(SonicURLProtocolCallBack)protocolCallBack;\n\n/**\n * It provide the session state result by the resultBlock\n */\n- (void)getResultWithCallBack:(SonicWebviewCallBack)webviewCallback;\n\n/**\n * cached html string\n */\n- (NSString *)cachedHTMLString;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Session/SonicSession.m",
    "content": "\n//\n//  SonicSession.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicSession.h\"\n#import <objc/runtime.h>\n#import \"SonicServer.h\"\n#import \"SonicConnection.h\"\n#import \"SonicCache.h\"\n#import \"SonicUtil.h\"\n#import \"SonicEngine.h\"\n#import \"SonicResourceLoader.h\"\n#import \"SonicEventStatistics.h\"\n\n@interface SonicSession ()\n\n@property (nonatomic,retain)NSDictionary  *cacheConfigHeaders;\n\n@property (nonatomic,assign)BOOL isCompletion;\n@property (nonatomic,retain)SonicServer *sonicServer;\n\n@property (nonatomic,copy)  NSString *localRefreshTime;\n@property (nonatomic,assign)SonicStatusCode sonicStatusFinalCode;\n\n@property (nonatomic,retain)NSData *cacheFileData;\n@property (nonatomic,retain)NSDictionary  *cacheResponseHeaders;\n@property (nonatomic,assign)BOOL didFinishCacheRead;\n@property (nonatomic,assign)BOOL isUpdate;\n\n/**\n * Use to hold all block operation in sonic session queue\n * We need to cancel before the SonicSession dealloc\n */\n@property (nonatomic,retain)NSMutableArray *sonicQueueOperationIdentifiers;\n\n/**\n * Use to hold all block operation in main queue\n * We need to cancel before the SonicSession dealloc\n */\n@property (nonatomic,retain)NSMutableArray *mainQueueOperationIdentifiers;\n\n@end\n\n@implementation SonicSession\n\n#pragma mark - Custom Request\n\n+ (BOOL)registerSonicConnection:(Class)connectionClass\n{\n    return [SonicServer registerSonicConnection:connectionClass];\n}\n\n+ (void)unregisterSonicConnection:(Class)connectionClass\n{\n    return [SonicServer unregisterSonicConnection:connectionClass];\n}\n\n+ (NSOperationQueue *)sonicSessionQueue\n{\n    static NSOperationQueue *_sonicSessionQueue = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _sonicSessionQueue = [[NSOperationQueue alloc]init];\n        _sonicSessionQueue.name = @\"SonicSessionQueue\";\n        _sonicSessionQueue.maxConcurrentOperationCount = 1;\n        _sonicSessionQueue.qualityOfService = NSQualityOfServiceUserInitiated;\n    });\n    \n    return _sonicSessionQueue;\n}\n\n#pragma mark - Lify Cycle\n\n- (instancetype)init NS_UNAVAILABLE\n{\n    return nil;\n}\n\n- (instancetype)initWithUrl:(NSString *)aUrl withWebDelegate:(id<SonicSessionDelegate>)aWebDelegate Configuration:(SonicSessionConfiguration *)aConfiguration\n{\n    if (self = [super init]) {\n        self.delegate = aWebDelegate;\n        self.delegateId = [NSString stringWithFormat:@\"%ld\", (long)aWebDelegate.hash];\n        self.url = aUrl;\n        _configuration = [aConfiguration retain];\n        _sessionID = [sonicSessionID(aUrl) copy];\n        [self setupSonicServer];\n        [self setupData];\n    }\n    return self;\n}\n\n- (void)setupData\n{\n    SonicCacheItem *cacheItem = [[SonicCache shareCache] cacheForSession:_sessionID];\n    self.isFirstLoad = cacheItem.hasLocalCache? NO:YES;\n    \n    if (cacheItem.hasLocalCache) {\n        self.cacheFileData = cacheItem.htmlData;\n        self.cacheConfigHeaders = cacheItem.config;\n        self.cacheResponseHeaders = cacheItem.cacheResponseHeaders;\n        self.localRefreshTime = cacheItem.lastRefreshTime;\n        \n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionDidLoadLocalCache withEventInfo:@{@\"sessionID\":self.sessionID,@\"url\":self.url,@\"dataLength\":@(self.cacheFileData.length)}];\n        \n        //load sub resource if need\n        [self preloadSubResourceWithResponseHeaders:self.cacheResponseHeaders];\n    }\n    \n    [self setupRequestHeaders];\n}\n\n- (void)dealloc\n{\n    [_resourceLoader cancelAll];\n    [_resourceLoader release];\n    _resourceLoader = nil;\n    \n    if (self.sonicServer) {\n        [self.sonicServer stop];\n        self.sonicServer = nil;\n    }\n    \n    if (_configuration) {\n        [_configuration release];\n        _configuration = nil;\n    }\n    \n    self.cacheConfigHeaders = nil;\n    self.cacheResponseHeaders = nil;\n    self.cacheFileData = nil;\n    \n    if (self.delegate) {\n        self.delegate = nil;\n    }\n    \n    if (self.completionCallback) {\n        self.completionCallback = nil;\n    }\n    \n    if (self.protocolCallBack) {\n        self.protocolCallBack = nil;\n    }\n    \n    if (self.updateCallBack) {\n        self.updateCallBack = nil;\n    }\n    \n    [self cancel];\n    \n    self.url = nil;\n    \n    [_sessionID release];\n    _sessionID = nil;\n\n    [super dealloc];\n}\n\n#pragma mark - Open Interface\n\n- (void)start\n{\n    //Check if cache expired\n    if (self.configuration.supportCacheControl) {\n        SonicCacheItem *cacheItem = [[SonicCache shareCache] cacheForSession:self.sessionID];\n        if (![cacheItem isCacheExpired]) {\n            SonicLogEvent(@\"SonicSession.start finish:session(%@) is under cache expired.\", self.sessionID);\n            return;\n        }\n    }\n    \n    //dispatch to main , make sure syncCookies before start\n    dispatch_block_t blk = ^{\n        if (self.delegate && [self.delegate respondsToSelector:@selector(sessionWillRequest:)]) {\n            [self.delegate sessionWillRequest:self];\n        }\n        [self syncCookies];\n    };\n    \n    if ([NSThread mainThread]) {\n        blk();\n    }else{\n        dispatch_async(dispatch_get_main_queue(), blk);\n    }\n\n    [self.sonicServer start];\n}\n\n- (void)cancel\n{\n    self.delegate = nil;\n    \n    //remove operation relation this session in SonicSessionQueue and mainQueue\n    NSMutableArray *opNeedCancel = [NSMutableArray array];\n    for (NSString *opIdentifier in self.mainQueueOperationIdentifiers) {\n        for (NSOperation *op in [NSOperationQueue mainQueue].operations) {\n            if (op.hash == [opIdentifier integerValue]) {\n                [opNeedCancel addObject:op];\n            }\n        }\n    }\n    \n    //cancel operation from sonic session queue\n    for (NSString *opIdentifier in self.sonicQueueOperationIdentifiers) {\n        for (NSOperation *op in [SonicSession sonicSessionQueue].operations) {\n            if (op.hash == [opIdentifier integerValue]) {\n                [opNeedCancel addObject:op];\n            }\n        }\n    }\n    \n    //cancel op now\n    [opNeedCancel enumerateObjectsUsingBlock:^(NSOperation *op, NSUInteger idx, BOOL * _Nonnull stop) {\n        [op cancel];\n    }];\n    \n    if (self.sonicServer) {\n        [self.sonicServer stop];\n    }\n}\n\n- (void)setupSonicServer\n{\n    if (self.sonicServer) {\n        self.sonicServer = nil;\n    }\n    SonicServer *tServer = [[SonicServer alloc] initWithUrl:self.url delegate:self delegateQueue:[SonicSession sonicSessionQueue]];\n    self.sonicServer = tServer;\n    [tServer release];\n    [self.sonicServer enableLocalServer:_configuration.enableLocalServer];\n}\n\n- (BOOL)update\n{\n    if (self.sonicServer.isRuning) {\n        return NO;\n    }\n    [self setupSonicServer];\n    self.isFirstLoad = self.cacheConfigHeaders.count > 0 ? NO:YES;\n    [self setupRequestHeaders];\n    [self start];\n    \n    //event\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionRefresh withEventInfo:@{@\"url\":self.url,@\"sessionID\":self.sessionID}];\n    \n    return YES;\n}\n\n- (NSString *)cachedHTMLString\n{\n    if (!self.cacheFileData) {\n        return @\"\";\n    }\n    \n    return [[[NSString alloc]initWithData:self.cacheFileData encoding:NSUTF8StringEncoding] autorelease];\n}\n\n\n- (void)syncCookies\n{\n    NSURL *cUrl = [NSURL URLWithString:self.url];\n    NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];\n    NSArray *cookies = [sharedHTTPCookieStorage cookiesForURL:cUrl];\n    NSDictionary *cookieHeader = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];\n    if (nil != cookies) {\n        [self.sonicServer addRequestHeaderFields:cookieHeader];\n    }\n}\n\n- (NSString *)getSonicHeaderETagWithHeaders:(NSDictionary *)headers\n{\n    NSString *keyETag = [headers objectForKey:[SonicHeaderKeyCustomeETag lowercaseString]];\n    if (keyETag && [keyETag isKindOfClass:[NSString class]] && keyETag.length > 0) {\n        // do nothing\n    } else {\n        keyETag = [SonicHeaderKeyETag lowercaseString];\n    }\n    \n    return [headers objectForKey:keyETag];\n}\n\n- (NSDictionary *)buildRequestHeaderFields\n{\n    NSDictionary *cacheHeaders = self.cacheConfigHeaders;\n    NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionary];\n    \n    if (cacheHeaders) {\n        NSString *eTag = [self getSonicHeaderETagWithHeaders:cacheHeaders];\n        if (eTag.length > 0) {\n            [requestHeaders setObject:eTag forKey:HTTPHeaderKeyIfNoneMatch];\n        }\n        NSString *tempTag = cacheHeaders[SonicHeaderKeyTemplate];\n        if (tempTag.length > 0 ) {\n            [requestHeaders setObject:tempTag forKey:SonicHeaderKeyTemplate];\n        }\n    }else{\n        [requestHeaders setObject:@\"\" forKey:HTTPHeaderKeyIfNoneMatch];\n        [requestHeaders setObject:@\"\" forKey:SonicHeaderKeyTemplate];\n    }\n    \n    [requestHeaders setObject:[[SonicEngine sharedEngine] getGlobalUserAgent] forKey:HTTPHeaderKeyUserAgent];\n    \n    NSURL *cUrl = [NSURL URLWithString:self.url];\n    if (self.serverIP.length > 0) {\n        NSString *host = [cUrl.scheme isEqualToString:@\"https\"]? [NSString stringWithFormat:@\"%@:443\",self.serverIP]:[NSString stringWithFormat:@\"%@:80\",self.serverIP];\n        NSString *newUrl = [self.url stringByReplacingOccurrencesOfString:cUrl.host withString:host];\n        cUrl = [NSURL URLWithString:newUrl];\n        [requestHeaders setObject:cUrl.host forKey:HTTPHeaderKeyHost];\n    }\n    \n    [requestHeaders addEntriesFromDictionary:self.configuration.customRequestHeaders];\n    \n    return requestHeaders;\n}\n\n- (void)setupRequestHeaders\n{\n    // setup headers\n    NSDictionary *requestHeaderFields = [self buildRequestHeaderFields];\n    [self.sonicServer setRequestHeaderFields:requestHeaderFields];\n    [self.sonicServer setResponseHeaderFields:self.configuration.customResponseHeaders];\n}\n\nNSString * dispatchToSonicSessionQueue(dispatch_block_t block)\n{\n    NSBlockOperation *blkOp = [NSBlockOperation blockOperationWithBlock:block];\n    [[SonicSession sonicSessionQueue] addOperation:blkOp];\n    return [NSString stringWithFormat:@\"%ld\",(unsigned long)blkOp.hash];\n}\n\n#pragma mark - SonicServerDelegate\n- (void)server:(SonicServer *)server didRecieveResponse:(NSHTTPURLResponse *)response\n{\n  [self preloadSubResourceWithResponseHeaders:response.allHeaderFields];\n  dispatch_block_t opBlock = ^{\n      \n      NSInteger resposneCode = response.statusCode;\n      [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionRecvResponse withEventInfo:@{@\"statusCode\":@(resposneCode),@\"headers\":response.allHeaderFields,@\"url\":self.url,@\"sessionID\":self.sessionID}];\n      \n        //sync cookie to NSHTTPCookieStorage\n        dispatchToMain(^{\n            NSArray *cookiesFromResp = [NSHTTPCookie cookiesWithResponseHeaderFields:response.allHeaderFields forURL:response.URL];\n            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookiesFromResp forURL:response.URL mainDocumentURL:self.sonicServer.request.mainDocumentURL];\n        });\n        if (self.isFirstLoad) {\n            [self firstLoadRecieveResponse:response];\n        }else{\n            if ([self.sonicServer isSonicResponse] && !self.configuration.enableLocalServer) {\n                self.cacheResponseHeaders = response.allHeaderFields;\n            }\n            if (self.configuration.enableLocalServer) {\n                self.cacheResponseHeaders = response.allHeaderFields;\n            }\n        }\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (void)server:(SonicServer *)server didReceiveData:(NSData *)data\n{\n    dispatch_block_t opBlock = ^{\n        if (self.isFirstLoad) {\n            [self firstLoadDidLoadData:data];\n        }\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (void)server:(SonicServer *)server didCompleteWithError:(NSError *)error\n{\n    dispatch_block_t opBlock = ^{\n        \n        //event\n        NSInteger errorCode = error.code;\n        [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionHttpError withEventInfo:@{@\"code\":@(errorCode),@\"msg\":error.debugDescription,@\"url\":self.url,@\"sessionID\":self.sessionID}];\n        \n        self.isCompletion = YES;\n        if (self.isFirstLoad) {\n            [self firstLoadDidFaild:error];\n        } else {\n            [self updateDidFaild];\n        }\n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (void)serverDidCompleteWithoutError:(SonicServer *)server\n{\n    dispatch_block_t opBlock = ^{\n        \n        self.isCompletion = YES;\n        \n        if (self.isFirstLoad) {\n            [self firstLoadDidSuccess];\n        } else {\n            [self updateDidSuccess];\n        }\n        \n        //update cache expire time\n        if (self.configuration.supportCacheControl) {\n            \n            [[SonicCache shareCache] updateCacheExpireTimeWithResponseHeaders:self.sonicServer.response.allHeaderFields withSessionID:self.sessionID];\n\n        }\n        \n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n#pragma mark - 首次加载\n\n- (void)firstLoadRecieveResponse:(NSHTTPURLResponse *)response\n{\n    [self dispatchProtocolAction:SonicURLProtocolActionRecvResponse param:response];\n}\n\n- (void)firstLoadDidLoadData:(NSData *)data\n{\n    [self dispatchProtocolAction:SonicURLProtocolActionLoadData param:data];\n}\n\n- (void)firstLoadDidFaild:(NSError *)error\n{\n    [self dispatchProtocolAction:SonicURLProtocolActionDidFaild param:error];\n    \n    [self checkAutoCompletionAction];\n}\n\n- (void)firstLoadDidSuccess\n{\n    [self dispatchProtocolAction:SonicURLProtocolActionDidSuccess param:nil];\n    \n    if (200 == self.sonicServer.response.statusCode) {\n        [self dealWithFirstLoad];\n    } else {\n        SonicLogEvent(@\"firstLoadDidSuccess warning:statusCode[%ld] miss!\", (long)self.sonicServer.response.statusCode);\n    }\n    \n    [self checkAutoCompletionAction];\n}\n\n- (void)dealWithFirstLoad\n{\n    if ([self.sonicServer isSonicResponse]) {\n        \n        NSString *policy = [self.sonicServer responseHeaderForKey:SonicHeaderKeyCacheOffline];\n        \n        self.cacheFileData = self.sonicServer.responseData;\n        \n        if ([policy isEqualToString:SonicHeaderValueCacheOfflineDisable]) {\n            \n            [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionUnavilable withEventInfo:@{@\"msg\":@\"Cache-Offline:Http\",@\"url\":self.url,@\"sessionID\":self.sessionID}];\n            \n            [[SonicCache shareCache] saveServerDisableSonicTimeNow:self.sessionID];\n            \n            self.isDataFetchFinished = YES;\n            \n            return;\n        }\n        \n        //cache-control\n        if (self.configuration.supportCacheControl) {\n            NSString *cacheControl = [self.sonicServer responseHeaderForKey:SonicHeaderValueCacheControl];\n            if ([cacheControl isEqualToString:@\"no-cache\"] || [cacheControl isEqualToString:@\"no-store\"] || [cacheControl isEqualToString:@\"must-revalidate\"]) {\n                SonicLogEvent(@\"cache control need't cache!\");\n                return;\n            }\n        }\n        \n        if ([policy isEqualToString:SonicHeaderValueCacheOfflineStoreRefresh] || [policy isEqualToString:SonicHeaderValueCacheOfflineStore] || [policy isEqualToString:SonicHeaderValueCacheOfflineRefresh]) {\n            \n            NSDictionary *serverResult = [self.sonicServer sonicItemForCache];\n            if (!serverResult) {\n                SonicLogEvent(@\"Sonic first load item for cache nil\");\n                return;\n            }\n            \n            NSString *htmlString = [serverResult[kSonicHtmlFieldName] length]> 0? serverResult[kSonicHtmlFieldName]:@\"\";\n            [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionFirstLoad withEventInfo:@{@\"htmlString\":htmlString,@\"url\":self.url,@\"sessionID\":self.sessionID}];\n            \n            SonicCacheItem *cacheItem = [[SonicCache shareCache] saveHtmlString:serverResult[kSonicHtmlFieldName] templateString:serverResult[kSonicTemplateFieldName] dynamicData:serverResult[kSonicDataFieldName] responseHeaders:self.sonicServer.response.allHeaderFields withUrl:self.url];\n            \n            if (cacheItem) {\n                \n                self.localRefreshTime = cacheItem.lastRefreshTime;\n                self.sonicStatusCode = SonicStatusCodeFirstLoad;\n                self.sonicStatusFinalCode = SonicStatusCodeFirstLoad;\n                self.cacheConfigHeaders = cacheItem.config;\n            }\n            \n            if ([policy isEqualToString:SonicHeaderValueCacheOfflineRefresh]) {\n                [[SonicCache shareCache] removeCacheBySessionID:self.sessionID];\n            }\n            \n            [[SonicCache shareCache] removeServerDisableSonic:self.sessionID];\n        }\n        \n    }else{\n        \n        self.cacheFileData = self.sonicServer.responseData;\n        \n    }\n    \n    self.isDataFetchFinished = YES;\n    \n    //use the call back to tell web page which mode used\n    [self dispatchUpdateCallBack];\n}\n\n- (void)dispatchProtocolAction:(SonicURLProtocolAction)action param:(NSObject *)param\n{\n    NSDictionary *actionParam = [SonicUtil protocolActionItem:action param:param];\n    if (self.protocolCallBack) {\n        self.protocolCallBack(actionParam);\n    }\n}\n\n- (void)dispatchProtocolActions:(NSArray *)actions\n{\n    for (NSDictionary *actionItem in actions) {\n        if (self.protocolCallBack) {\n            self.protocolCallBack(actionItem);\n        }\n    }\n}\n\n#pragma mark - 公开接口\n\n- (void)preloadRequestActionsWithProtocolCallBack:(SonicURLProtocolCallBack)protocolCallBack\n{\n    dispatch_block_t opBlock = ^{\n        \n        self.protocolCallBack = protocolCallBack;\n        \n        if (self.isDataFetchFinished || !self.isFirstLoad) {\n                        \n            if (protocolCallBack) {\n                [self dispatchProtocolActions:[self cacheFileActions]];\n            }\n            \n            if (self.isDataFetchFinished) {\n                self.sonicStatusFinalCode = SonicStatusCodeAllCached;\n            }\n            \n        } else { // self.isFirstLoad must be TRUE\n            [self dispatchProtocolActions:[self preloadRequestActions]];\n        }\n        \n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (NSArray *)preloadRequestActions\n{\n    NSMutableArray *actionItems = [NSMutableArray array];\n    if (self.sonicServer.response) {\n        NSDictionary *respItem = [SonicUtil protocolActionItem:SonicURLProtocolActionRecvResponse param:self.sonicServer.response];\n        [actionItems addObject:respItem];\n    }\n    \n    if (self.isCompletion) {\n        if (self.sonicServer.error) {\n            NSDictionary *failItem = [SonicUtil protocolActionItem:SonicURLProtocolActionDidFaild param:self.sonicServer.error];\n            [actionItems addObject:failItem];\n        }else{\n            if (self.sonicServer.responseData.length > 0) {\n                NSData *recvCopyData = [[self.sonicServer.responseData copy]autorelease];\n                NSDictionary *recvItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:recvCopyData];\n                [actionItems addObject:recvItem];\n            }\n            NSDictionary *finishItem = [SonicUtil protocolActionItem:SonicURLProtocolActionDidSuccess param:nil];\n            [actionItems addObject:finishItem];\n        }\n    }else{\n        if (self.sonicServer.responseData.length > 0) {\n            NSData *recvCopyData = [[self.sonicServer.responseData copy]autorelease];\n            NSDictionary *recvItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:recvCopyData];\n            [actionItems addObject:recvItem];\n        }\n    }\n    \n    return actionItems;\n}\n\n- (NSArray *)cacheFileActions\n{\n    NSMutableArray *actionItems = [NSMutableArray array];\n    \n    NSHTTPURLResponse *response = nil;\n    if (self.sonicServer.response && self.isDataFetchFinished) {\n        response = self.sonicServer.response;\n    }else{\n        NSDictionary *respHeader = self.cacheResponseHeaders;\n        response = [[[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:self.url] statusCode:200 HTTPVersion:@\"1.1\" headerFields:respHeader]autorelease];\n    }\n    \n    NSMutableData *cacheData = [[self.cacheFileData mutableCopy] autorelease];\n    NSDictionary *respItem = [SonicUtil protocolActionItem:SonicURLProtocolActionRecvResponse param:response];\n    NSDictionary *dataItem = [SonicUtil protocolActionItem:SonicURLProtocolActionLoadData param:cacheData];\n    NSDictionary *finishItem = [SonicUtil protocolActionItem:SonicURLProtocolActionDidSuccess param:nil];\n    \n    [actionItems addObject:respItem];\n    [actionItems addObject:dataItem];\n    [actionItems addObject:finishItem];\n    \n    self.didFinishCacheRead = YES;\n\n    return actionItems;\n}\n\n- (void)getResultWithCallBack:(SonicWebviewCallBack)resultBlock\n{\n    dispatch_block_t opBlock = ^{\n        \n        self.webviewCallBack = resultBlock;\n        \n        NSDictionary *resultDict = [self sonicDiffResult];\n        if (resultDict && resultBlock) {\n            resultBlock(resultDict);\n        }\n        \n    };\n    NSString *opIdentifier = dispatchToSonicSessionQueue(opBlock);\n    [self.sonicQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (NSDictionary *)sonicDiffResult\n{\n    if (self.sonicStatusCode == 0) {\n        return nil;\n    }\n    \n    NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];\n\n    [resultDict setObject:[@(self.sonicStatusFinalCode) stringValue] forKey:@\"code\"];\n    \n    BOOL isCacheOfflineRefresh = NO;\n    NSString *policy = [self.sonicServer responseHeaderForKey:SonicHeaderKeyCacheOffline];\n    if ([policy isEqualToString:SonicHeaderValueCacheOfflineStore]) {\n        [resultDict setObject:[@(SonicStatusCodeAllCached) stringValue] forKey:@\"code\"];\n    }else{\n        isCacheOfflineRefresh = YES;\n    }\n    \n    if (self.sonicStatusFinalCode == SonicStatusCodeDataUpdate && self.diffData && isCacheOfflineRefresh) {\n        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.diffData options:NSJSONWritingPrettyPrinted error:nil];\n        NSString *jsonString = [[[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding]autorelease];\n        if (jsonString.length > 0) {\n            [resultDict setObject:jsonString forKey:@\"result\"];\n        }\n    }\n    \n    [resultDict setObject:[@(self.sonicStatusCode) stringValue] forKey:@\"srcCode\"];\n    self.localRefreshTime = self.localRefreshTime.length > 0? self.localRefreshTime:@\"\";\n    [resultDict setObject:self.localRefreshTime forKey:@\"local_refresh_time\"];\n    \n    //Add extra info\n    NSString *templateTag = self.cacheConfigHeaders[@\"template-tag\"];\n    templateTag = templateTag.length > 0? templateTag:@\"\";\n    NSString *etag = self.cacheConfigHeaders[@\"etag\"];\n    etag = etag.length > 0? etag:@\"\";\n    NSString *isRefresh = self.isUpdate? @\"true\":@\"false\";\n    NSString *cacheOffline = [self.sonicServer responseHeaderForKey:@\"cache-offline\"];\n    cacheOffline = cacheOffline.length > 0? cacheOffline:@\"\";\n    NSDictionary *extra = @{@\"template-tag\":templateTag,@\"eTag\":etag,@\"isReload\":isRefresh,@\"cache-offline\":cacheOffline};\n    [resultDict setObject:extra forKey:@\"extra\"];\n\n    SonicLogEvent(@\"sonic diff result :%@\",resultDict);\n    \n    return resultDict;\n}\n\n#pragma mark - 数据更新\n\n- (void)updateDidSuccess\n{\n    switch (self.sonicServer.response.statusCode) {\n        case 304:\n        {\n            [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionHitCache withEventInfo:@{@\"msg\":@\"Server 304!\",@\"url\":self.url,@\"sessionID\":self.sessionID}];\n            \n            self.sonicStatusCode = SonicStatusCodeAllCached;\n            self.sonicStatusFinalCode = SonicStatusCodeAllCached;\n            //update headers\n            [[SonicCache shareCache] saveResponseHeaders:self.sonicServer.response.allHeaderFields withSessionID:self.sessionID];\n        }\n            break;\n        case 200:\n        {\n            if (![self.sonicServer isSonicResponse]) {\n                [[SonicCache shareCache] removeCacheBySessionID:self.sessionID];\n                SonicLogEvent(@\"Clear cache because while not sonic repsonse!\");\n                break;\n            }\n            \n            if ([self isTemplateChange]) {\n                \n                [self dealWithTemplateChange];\n                \n            }else{\n                \n                [self dealWithDataUpdate];\n            }\n            \n            NSString *policy = [self.sonicServer responseHeaderForKey:SonicHeaderKeyCacheOffline];\n            if ([policy isEqualToString:SonicHeaderValueCacheOfflineStore] || [policy isEqualToString:SonicHeaderValueCacheOfflineStoreRefresh] || [policy isEqualToString:SonicHeaderValueCacheOfflineRefresh]) {\n                [[SonicCache shareCache] removeServerDisableSonic:self.sessionID];\n            }\n            \n            if ([policy isEqualToString:SonicHeaderValueCacheOfflineRefresh] || [policy isEqualToString:SonicHeaderValueCacheOfflineDisable]) {\n                \n                if ([policy isEqualToString:SonicHeaderValueCacheOfflineRefresh]) {\n                    \n                    [[SonicCache shareCache]removeCacheBySessionID:self.sessionID];\n                }\n                \n                if ([policy isEqualToString:SonicHeaderValueCacheOfflineDisable]) {\n                    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionUnavilable withEventInfo:@{@\"msg\":@\"Cache-Offline:Http\",@\"url\":self.url,@\"sessionID\":self.sessionID}];\n                    [[SonicCache shareCache] saveServerDisableSonicTimeNow:self.sessionID];\n                }\n            }\n            \n        }\n            break;\n        default:\n        {\n            \n        }\n            break;\n    }\n    \n    //use the call back to tell web page which mode used\n    if (self.isUpdate) {\n        [self dispatchUpdateCallBack];\n    }else{\n        if (self.webviewCallBack) {\n            NSDictionary *resultDict = [self sonicDiffResult];\n            if (resultDict) {\n                self.webviewCallBack(resultDict);\n            }\n        }else{\n            SonicLogEvent(@\"There is no webViewCallBack!\");\n        }\n    }\n    \n    [self checkAutoCompletionAction];\n}\n\n- (void)dispatchUpdateCallBack\n{\n    if (self.isUpdate) {\n        if (self.updateCallBack) {\n            NSDictionary *resultDict = [self sonicDiffResult];\n            if (resultDict) {\n                self.updateCallBack(resultDict);\n            }\n        }else{\n            SonicLogEvent(@\"There is no updateCallBack!\");\n        }\n    }\n}\n\n- (void)dealWithTemplateChange\n{\n    NSDictionary *serverResult = [self.sonicServer sonicItemForCache];\n    SonicCacheItem *cacheItem = [[SonicCache shareCache] saveHtmlString:serverResult[kSonicHtmlFieldName] templateString:serverResult[kSonicTemplateFieldName] dynamicData:serverResult[kSonicDataFieldName] responseHeaders:self.sonicServer.response.allHeaderFields withUrl:self.url];\n    \n    \n    //statistics\n    NSString  *htmlString = @\"\";\n    htmlString = htmlString.length > 0? htmlString:[[[NSString alloc]initWithData:self.sonicServer.responseData encoding:NSUTF8StringEncoding]autorelease];\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionTemplateChanged withEventInfo:@{@\"htmlString\":htmlString,@\"url\":self.url,@\"sessionID\":self.sessionID}];\n    \n    if (cacheItem) {\n        \n        self.sonicStatusCode = SonicStatusCodeTemplateUpdate;\n        self.sonicStatusFinalCode = SonicStatusCodeTemplateUpdate;\n        self.localRefreshTime = cacheItem.lastRefreshTime;\n        self.cacheFileData = self.sonicServer.responseData;\n        self.cacheResponseHeaders = cacheItem.cacheResponseHeaders;\n        \n        self.isDataFetchFinished = YES;\n        \n        if (!self.didFinishCacheRead) {\n            return;\n        }\n        \n        NSString *opIdentifier  =  dispatchToMain(^{\n            NSString *policy = [self.sonicServer responseHeaderForKey:SonicHeaderKeyCacheOffline];\n            if ([policy isEqualToString:SonicHeaderValueCacheOfflineStoreRefresh] || [policy isEqualToString:SonicHeaderValueCacheOfflineRefresh]) {\n                if (self.delegate && [self.delegate respondsToSelector:@selector(session:requireWebViewReload:)]) {\n                    NSURLRequest *sonicRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url]];\n                    [self.delegate session:self requireWebViewReload:[SonicUtil sonicWebRequestWithSession:self withOrigin:sonicRequest]];\n                }\n            }\n        });\n        [self.mainQueueOperationIdentifiers addObject:opIdentifier];\n    }\n}\n\n- (void)dealWithDataUpdate\n{\n    NSString *htmlString = nil;\n    if (self.sonicServer.isInLocalServerMode) {\n        NSDictionary *serverResult = [self.sonicServer sonicItemForCache];\n        htmlString = serverResult[kSonicHtmlFieldName];\n    }\n    \n    //statistics\n    NSString *htmlLog = @\"\";\n    htmlLog = htmlString.length > 0? htmlString:[[[NSString alloc]initWithData:self.sonicServer.responseData encoding:NSUTF8StringEncoding]autorelease];\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_SessionDataUpdated withEventInfo:@{@\"htmlString\":htmlLog,@\"url\":self.url,@\"sessionID\":self.sessionID}];\n    \n    SonicCacheItem *cacheItem = [[SonicCache shareCache] updateWithJsonData:self.sonicServer.responseData withHtmlString:htmlString withResponseHeaders:self.sonicServer.response.allHeaderFields withUrl:self.url];\n    \n    if (cacheItem) {\n        \n        self.sonicStatusCode = SonicStatusCodeDataUpdate;\n        self.sonicStatusFinalCode = SonicStatusCodeDataUpdate;\n        self.localRefreshTime = cacheItem.lastRefreshTime;\n        self.cacheFileData = cacheItem.htmlData;\n        self.cacheResponseHeaders = cacheItem.cacheResponseHeaders;\n        \n        if (_diffData) {\n            [_diffData release];\n            _diffData = nil;\n        }\n        _diffData = [cacheItem.diffData copy];\n        \n        self.isDataFetchFinished = YES;\n    }\n}\n\n- (void)updateDidFaild\n{    \n    [self checkAutoCompletionAction];\n}\n\n#pragma mark - Resource Loader\n\n- (void)preloadSubResourceWithResponseHeaders:(NSDictionary *)responseHeaders\n{\n    NSString *linkValue = responseHeaders[SonicHeaderKeyLink];\n    if (linkValue.length == 0) {\n        SonicLogEvent(@\"no preload link exist!\");\n        return;\n    }\n    NSArray *linkArray = [linkValue componentsSeparatedByString:@\";\"];\n    if (linkArray.count > 0) {\n        if (!_resourceLoader) {\n            _resourceLoader = [SonicResourceLoader new];\n        }\n        [_resourceLoader loadResourceLinks:linkArray];\n    }\n}\n\n#pragma mark - 公共处理\n\n- (void)checkAutoCompletionAction\n{\n    NSString *opIdentifier = dispatchToMain(^{\n        if (!self.delegate) {\n            if (self.completionCallback) {\n                self.completionCallback(self.sessionID);\n            }\n        }\n    });\n    [self.mainQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (void)webViewRequireloadNormalRequest\n{\n    NSString *opIdentifier = dispatchToMain(^{\n        if (self.delegate || [self.delegate respondsToSelector:@selector(session:requireWebViewReload:)]) {\n            NSURLRequest *normalRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url]];\n            [self.delegate session:self requireWebViewReload:normalRequest];\n        }\n    });\n    [self.mainQueueOperationIdentifiers addObject:opIdentifier];\n}\n\n- (BOOL)isTemplateChange\n{\n    if (![self.sonicServer isSonicResponse]) {\n        return NO;\n    }\n    NSString *tempChangeTag = [self.sonicServer responseHeaderForKey:SonicHeaderKeyTemplateChange];\n    return [tempChangeTag boolValue];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Session/SonicSessionConfiguration.h",
    "content": "//\n//  SonicSessionConfiguration.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@interface SonicSessionConfiguration : NSObject\n\n/**\n * Pass custom request headers\n */\n@property (nonatomic,retain)NSDictionary *customRequestHeaders;\n\n/**\n * Pass custom response headers\n */\n@property (nonatomic,retain)NSDictionary *customResponseHeaders;\n\n/**\n * Support Cache-Control or not\n */\n@property (nonatomic,assign)BOOL supportCacheControl;\n\n/**\n * Enable Local-Server mode which will simulate response as a standar sonic server.\n */\n@property (nonatomic,assign)BOOL enableLocalServer;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Session/SonicSessionConfiguration.m",
    "content": "//\n//  SonicSessionConfiguration.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicSessionConfiguration.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n@implementation SonicSessionConfiguration\n\n- (void)dealloc\n{\n    self.customRequestHeaders = nil;\n    self.customResponseHeaders = nil;\n    [super dealloc];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Sonic.h",
    "content": "//\n//  Sonic.h\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n//! Project version number for Sonic.\nFOUNDATION_EXPORT double SonicVersionNumber;\n\n//! Project version string for Sonic.\nFOUNDATION_EXPORT const unsigned char SonicVersionString[];\n\n// In this header, you should import all the public headers of your framework using statements like #import <Sonic/PublicHeader.h>\n\n#import <Foundation/Foundation.h>\n\n#import \"SonicConfiguration.h\"\n#import \"SonicSessionConfiguration.h\"\n#import \"SonicProtocol.h\"\n#import \"SonicConstants.h\"\n#import \"SonicSession.h\"\n#import \"SonicEngine.h\"\n#import \"SonicUtil.h\"\n#import \"SonicConnection.h\"\n#import \"SonicURLProtocol.h\"\n#import \"SonicCache.h\"\n#import \"SonicCacheItem.h\"\n#import \"SonicEventStatistics.h\"\n"
  },
  {
    "path": "sonic-iOS/Sonic/SonicConstants.h",
    "content": "//\n//  SonicConstants.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n#define SonicDefaultUserAgent @\"Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2 like Mac OS X;\\\nen-us) AppleWebKit/525.181 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20\"\n\n/**\n* Sonic status code.\n*/\ntypedef NS_ENUM(NSUInteger, SonicStatusCode) {\n    \n    /**\n     * No dynamic data will be updated.\n     */\n    SonicStatusCodeAllCached = 304,\n    \n    /**\n     * The template need to update.\n     */\n    SonicStatusCodeTemplateUpdate = 2000,\n    \n    /**\n     * There is no local cache, need to request all data from server.\n     */\n    SonicStatusCodeFirstLoad = 1000,\n    \n    /**\n     * Only need to request dynamic data.\n     */\n    SonicStatusCodeDataUpdate = 200,\n    \n};\n\n/** NSURLProtocol client action */\ntypedef NS_ENUM(NSUInteger, SonicURLProtocolAction) {\n    \n    SonicURLProtocolActionLoadData,\n    \n    SonicURLProtocolActionRecvResponse,\n    \n    SonicURLProtocolActionDidSuccess,\n    \n    SonicURLProtocolActionDidFaild,\n};\n\n/* Sonic error code */\ntypedef NS_ENUM(NSInteger, SonicErrorType) {\n    \n    /* File i/o faild */\n    SonicErrorType_IOE = -901,\n    \n    /* Time out */\n    SonicErrorType_TOE = -902,\n    \n    /* HTML file verify faild */\n    SonicErrorType_HTML_VERIFY_FAIL = -1001,\n    \n    /* Setup up the cache directory faild */\n    SonicErrorType_MAKE_DIR_ERROR = -1003,\n    \n    /* Save file faild */\n    SonicErrorType_WRITE_FILE_FAIL = -1004,\n    \n    /* Split the HTML to template and dynamic data faild */\n    SonicErrorType_SPLIT_HTML_FAIL = -1005,\n    \n    /* Merge the server data and local dynamic data faild */\n    SonicErrorType_MERGE_DIFF_DATA_FAIL = -1006,\n    \n    /* Server response data can not verify */\n    SonicErrorType_SERVER_DATA_EXCEPTION = -1007,\n    \n    /* Merge the template and dynamic data to build HTML faild */\n    SonicErrorType_BUILD_HTML_ERROR = -1008,\n    \n    /* NSURLProtocol recieve action faild */\n    SonicErrorType_URLPROTOCOL_ERROR = -1009,\n    \n};\n\n/**\n * Identify the source where started this request: webview or SonicSession.\n */\n#define SonicHeaderKeyLoadType        @\"sonic-load-type\"\n\n/**\n * The request is started by webview.\n */\n#define SonicHeaderValueWebviewLoad   @\"__SONIC_HEADER_VALUE_WEBVIEW_LOAD__\"\n\n/**\n * The hash of Delegate which uses to identify wether it's owner of a SonicSession.\n */\n#define SonicHeaderKeyDelegateId    @\"sonic-delegate-id\"\n\n/**\n * The request is started by SonicSession.\n */\n#define SonicHeaderValueSonicLoad @\"__SONIC_HEADER_VALUE_SONIC_LOAD__\"\n\n/**\n * Pass session id to SonicURLProtocol through this header field.\n */\n#define SonicHeaderKeySessionID  @\"sonic-sessionId\"\n\n/**\n * Pass sonic sdk version through this field.\n */\n#define SonicHeaderKeySDKVersion @\"sonic-sdk-version\"\n\n/**\n * Current sonic version: Sonic/2.0.0\n */\n#define SonicHeaderValueSDKVersion @\"Sonic/2.0.0\"\n\n/**\n * Pass template tag through this field.\n */\n#define SonicHeaderKeyTemplate @\"template-tag\"\n\n#define SonicHeaderKeyHtmlSha1 @\"html-sha1\"\n\n/**\n * Pass true/false to decide if template-change\n */\n#define SonicHeaderKeyTemplateChange @\"template-change\"\n\n#define SonicHeaderKeyLink @\"sonic-link\"\n\n/**\n * Pass Etag through this field.\n */\n#define SonicHeaderKeyETag     @\"etag\"\n\n/**\n * Pass Etag through this field.\n * This header represents that the \"eTag\" key can be modified by service.\n */\n#define SonicHeaderKeyCustomeETag     @\"sonic-etag-key\"\n\n/**\n * Content-Security-Policy key for header.\n */\n#define SonicHeaderKeyCSPHeader       @\"content-security-policy\"\n\n/**\n * Pass cache policy through this field: SonicHeaderValueCacheOfflineStore, SonicHeaderValueCacheOfflineStoreRefresh, SonicHeaderValueCacheOfflineRefresh, SonicHeaderValueCacheOfflineDisable.\n */\n#define SonicHeaderKeyCacheOffline       @\"cache-offline\"\n\n/**\n * Http header cache control policy\n */\n#define SonicHeaderValueCacheControl  @\"cache-control\"\n\n/**\n * Store the new data and don't refresh web content.\n */\n#define SonicHeaderValueCacheOfflineStore  @\"store\"\n\n/**\n * Store new data and refresh web content.\n */\n#define SonicHeaderValueCacheOfflineStoreRefresh   @\"true\"\n\n/**\n * Don't store the new data , only use the new data to refresh web content.\n */\n#define SonicHeaderValueCacheOfflineRefresh  @\"false\"\n\n/**\n * Sonic is diabled, don't use sonic in the following 6 hours.\n */\n#define SonicHeaderValueCacheOfflineDisable   @\"http\"\n\n\n/**\n * Content-Security-Policy key for cache.\n */\n#define kSonicCSP             @\"csp\"\n\n/**\n * The last time to refresh the cache.\n */\n#define kSonicLocalRefreshTime  @\"local_refresh\"\n\n/**\n * The timestamp when the local cache expire\n */\n#define kSonicLocalCacheExpireTime @\"cache-expire-time\"\n\n/**\n * The http response header key Max-Age\n */\n#define SonicHeaderMaxAge @\"max-age\"\n\n/**\n * The http response header key Expires\n */\n#define SonicHeaderExpire @\"expires\"\n\n/**\n * Html-SHA1\n */\n#define kSonicSha1          @\"sha1\"\n\n/**\n * Key for SonicURLProtocolCallBack's dictionary: action type.\n */\n#define kSonicProtocolAction            @\"protocol-action\"\n\n/**\n * Key for SonicURLProtocolCallBack's dictionary: data.\n */\n#define kSonicProtocolData              @\"protocol-data\"\n\n/**\n * The file name to record Sonic disable list for each URL.\n */\n#define SonicCacheOfflineDisableList       @\"cache-offline-disable.cfg\"\n\n#define SonicCacheDatabase @\"sonic.db\"\n\n/**\n * Quick way to get file manager.\n */\n#define SonicFileManager    [NSFileManager defaultManager]\n\n/**\n * Sonic item field name\n */\n#define kSonicHtmlFieldName                 @\"html\"\n#define kSonicTemplateFieldName             @\"template\"\n#define kSonicDataFieldName                 @\"data\"\n#define kSonicDiffFieldName                 @\"diff\"\n\n/**\n * HTTP Header:If-None-Match\n */\n#define HTTPHeaderKeyIfNoneMatch @\"If-None-Match\"\n\n/**\n * HTTP Header:User-Agent\n */\n#define HTTPHeaderKeyUserAgent @\"User-Agent\"\n\n/**\n * HTTP Header:Host\n */\n#define HTTPHeaderKeyHost @\"Host\"\n\n/**\n * HTTP Header:Content-Type\n */\n#define HTTPHeaderKeyContentType @\"Content-Type\"\n\n"
  },
  {
    "path": "sonic-iOS/Sonic/SonicProtocol.h",
    "content": "//\n//  SonicProtocol.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n * @brief Use this protocal to trasfer data to sonic session, when you provide custom SonicConnection.\n */\n\n@class SonicConnection;\n\n@protocol SonicConnectionDelegate <NSObject>\n\n@required\n\n/**\n * @brief Notify when the network connection did recieve response.\n */\n- (void)connection:(SonicConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response;\n\n/**\n * @brief Notify when the network connection did recieve data.\n */\n- (void)connection:(SonicConnection *)connection didReceiveData:(NSData *)data;\n\n/**\n * @brief Call when the network connection did fail.\n */\n- (void)connection:(SonicConnection *)connection didCompleteWithError:(NSError *)error;\n\n/**\n * @brief Call when the network connection did success.\n */\n- (void)connectionDidCompleteWithoutError:(SonicConnection *)connection;\n\n\n@end\n\n@class SonicServer;\n\n@protocol SonicServerDelegate <NSObject>\n\n@required\n\n/**\n * @brief Call when the server did recieve response.\n */\n- (void)server:(SonicServer *)server didRecieveResponse:(NSHTTPURLResponse *)response;\n\n/**\n * @brief Call when the server did receive data.\n */\n- (void)server:(SonicServer *)server didReceiveData:(NSData *)data;\n\n/**\n * @brief Call when the server did fail.\n */\n- (void)server:(SonicServer *)server didCompleteWithError:(NSError *)error;\n\n/**\n * @brief Call when the the server did success.\n */\n- (void)serverDidCompleteWithoutError:(SonicServer *)server;\n\n@end\n\n@class SonicSession;\n\n/**\n * @brief Notify the webView holder what happened during the connection.\n */\n@protocol SonicSessionDelegate <NSObject>\n\n@required\n\n/**\n * @brief Sonic session call the delegate to reload request\n */\n- (void)session:(SonicSession *)session requireWebViewReload:(NSURLRequest *)request;\n\n@optional\n\n/**\n * @brief Sonic request will be sent, you can do some custom actions, e.g. add custom header fields, set cookie etc.\n */\n- (void)sessionWillRequest:(SonicSession *)session;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Statistics/SonicEventConstants.h",
    "content": "//\n//  SonicEventConstants.h\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\n/**\n *  Sonic Event Type\n */\ntypedef NS_ENUM(NSUInteger, SonicStatisticsEvent) {\n    \n    //Throw all step log \n    SonicStatisticsEvent_EventLog,\n\n    //Session create faild\n    SonicStatisticsEvent_SessionCreateFaild,\n    \n    //Session did finish read cache from local file\n    SonicStatisticsEvent_SessionDidLoadLocalCache,\n    \n    //Session data updated\n    SonicStatisticsEvent_SessionDataUpdated,\n    \n    //Session first load and data did fetched\n    SonicStatisticsEvent_SessionFirstLoad,\n    \n    //Session did recieve server response\n    SonicStatisticsEvent_SessionRecvResponse,\n    \n    //Session did faild with error\n    SonicStatisticsEvent_SessionHttpError,\n    \n    //Session did recieve server 304 response\n    SonicStatisticsEvent_SessionHitCache,\n    \n    //Session did recieve server custom header cache-offline:http\n    SonicStatisticsEvent_SessionUnavilable,\n    \n    //Session request result is template changed\n    SonicStatisticsEvent_SessionTemplateChanged,\n    \n    //Session did finish save server data to cache layer\n    SonicStatisticsEvent_SessionDidSaveCache,\n    \n    //Session will remove from engine\n    SonicStatisticsEvent_SessionDestroy,\n    \n    //Session require to refresh current state by send new request\n    SonicStatisticsEvent_SessionRefresh,\n    \n    //Sub resource did write to file\n    SonicStatisticsEvent_SubResourceDidSave,\n    \n    //Sub resource did request faild\n    SonicStatisticsEvent_SubResourceDidFail,\n    \n    //Sub resource did load cache from file\n    SonicStatisticsEvent_SubResourceLoadLocalCache,\n    \n    //Sonic cache did reach the maximun limit size of cache directory\n    SonicStatisticsEvent_TrimCache,\n};\n"
  },
  {
    "path": "sonic-iOS/Sonic/Statistics/SonicEventStatistics.h",
    "content": "//\n//  SonicEventStatistics.h\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicEventConstants.h\"\n\n#define SonicLogEvent(format,...) [[SonicEventStatistics shareStatistics]addLog:format,##__VA_ARGS__]\n\n@protocol SonicEventStatisticsObserver <NSObject>\n\n- (void)handleEvent:(SonicStatisticsEvent)event withEventInfo:(NSDictionary *)info;\n\n@end\n\n@interface SonicEventStatistics : NSObject\n\n+ (SonicEventStatistics *)shareStatistics;\n\n- (void)addLog:(NSString *)format, ...;\n\n/**\n * Add an observer to handle the events\n */\n- (void)addEventObserver:(id<SonicEventStatisticsObserver>)eventObserver;\n\n/**\n * remove the observer\n */\n- (void)removeEventObserver:(id<SonicEventStatisticsObserver>)eventObserver;\n\n/**\n * add an event with info\n */\n- (void)addEvent:(SonicStatisticsEvent)event withEventInfo:(NSDictionary *)info;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Statistics/SonicEventStatistics.m",
    "content": "//\n//  SonicEventStatistics.m\n//  Sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicEventStatistics.h\"\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n@interface SonicEventStatistics()\n\n@property (nonatomic,retain)NSOperationQueue *statisticsQueue;\n\n@property (nonatomic,retain)NSMutableArray *observers;\n\n@end\n\n\n@implementation SonicEventStatistics\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        self.statisticsQueue = [NSOperationQueue new];\n        self.statisticsQueue.name = @\"com.sonic.statistics\";\n        self.statisticsQueue.maxConcurrentOperationCount = 1;\n        self.observers = [NSMutableArray array];\n    }\n    return self;\n}\n\n+ (SonicEventStatistics *)shareStatistics\n{\n    static SonicEventStatistics *_statistcs = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _statistcs = [[self alloc]init];\n    });\n    return _statistcs;\n}\n\n- (void)dealloc\n{\n    [self.statisticsQueue cancelAllOperations];\n    self.statisticsQueue = nil;\n    self.observers = nil;\n    [super dealloc];\n}\n\n- (void)addLog:(NSString *)format, ...\n{\n    va_list args;\n    va_start(args,format);\n    NSString *logString = [[[NSString alloc]initWithFormat:format arguments:args]autorelease];\n    va_end(args);\n    logString = [NSString stringWithFormat:@\"#SonicEventLog# %@\",logString];\n    [[SonicEventStatistics shareStatistics] addEvent:SonicStatisticsEvent_EventLog withEventInfo:@{@\"logMsg\":logString}];\n}\n\n- (void)addEventObserver:(id<SonicEventStatisticsObserver>)eventObserver\n{\n    if (![eventObserver conformsToProtocol:@protocol(SonicEventStatisticsObserver)]) {\n        return;\n    }\n    if ([self.observers containsObject:eventObserver]) {\n        return;\n    }\n    [self.observers addObject:eventObserver];\n}\n\n- (void)removeEventObserver:(id<SonicEventStatisticsObserver>)eventObserver\n{\n    if (!eventObserver) {\n        return;\n    }\n    [self.observers removeObject:eventObserver];\n}\n\n- (void)addEvent:(SonicStatisticsEvent)event withEventInfo:(NSDictionary *)info\n{\n    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{\n        for (id<SonicEventStatisticsObserver> observer in self.observers) {\n            [observer handleEvent:event withEventInfo:info];\n        }\n    }];\n    [self.statisticsQueue addOperation:blockOp];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Util/SonicUtil.h",
    "content": "//\n//  SonicUtil.h\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"SonicConnection.h\"\n#import \"SonicConstants.h\"\n#import \"SonicSession.h\"\n#import \"SonicEventStatistics.h\"\n\n@interface SonicUtil : NSObject\n\n/**\n * Set sonic tag header into originRequest headers\n */\n+ (NSURLRequest *)sonicWebRequestWithSession:(SonicSession* )session withOrigin:(NSURLRequest *)originRequest;\n\n/**\n * Using MD5 to encode the URL to session ID;\n */\nNSString *sonicSessionID(NSString *url);\n\n/**\n * Using MD5 to encode the URL to session ID;\n */\nNSString *resourceSessionID(NSString *url);\n\n/**\n * Create sonic path with URL\n */\n+ (NSString *)sonicUrl:(NSString *)url;\n\n/**\n * Dispatch block to main thread.\n * Return block operation hash string\n */\nNSString * dispatchToMain (dispatch_block_t block);\n\n/**\n * Get SHA1 value from data.\n */\nNSString * getDataSha1(NSData *data);\n\n/**\n * @brief Split the HTML to dynamic data and template string.\n \n * @param html the HTML document downloaded by sonic session.\n */\n+(NSDictionary *)splitTemplateAndDataFromHtmlData:(NSString *)html;\n\n/**\n * @brief Merge the server data and local dynamic data to create new HTML and the difference data.\n * Get the difference between the \"updateDict\" and \"existData\"\n\n * @result Return the difference data\n */\n+ (NSDictionary *)mergeDynamicData:(NSDictionary *)updateDict withOriginData:(NSMutableDictionary *)existData;\n\n/**\n * Create an item by specifying the action type and parameters to return to the NSURLProtocol.\n */\n+ (NSDictionary *)protocolActionItem:(SonicURLProtocolAction)action param:(NSObject *)param;\n\n/**\n * Translate the URL's query into a dictionary.\n */\nNSMutableDictionary * queryComponents(NSString *aUrlStr);\n\n/**\n * Get the current timestamp.\n */\nunsigned long long currentTimeStamp(void);\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic/Util/SonicUtil.m",
    "content": "//\n//  SonicUtil.m\n//  sonic\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#if  __has_feature(objc_arc)\n#error This file must be compiled without ARC. Use -fno-objc-arc flag.\n#endif\n\n#import \"SonicUtil.h\"\n#import \"SonicEngine.h\"\n#import <Foundation/Foundation.h>\n#import <CommonCrypto/CommonDigest.h>\n\n@implementation SonicUtil\n\nNSString *sonicSessionID(NSString *url)\n{\n    NSString* userAccount = [SonicEngine sharedEngine].currentUserAccount;\n    if ([userAccount length] > 0) {\n        return stringFromMD5([NSString stringWithFormat:@\"%@_%@\",userAccount,[SonicUtil sonicUrl:url]]);\n    }else{\n        return stringFromMD5([NSString stringWithFormat:@\"%@\",[SonicUtil sonicUrl:url]]);\n    }\n}\n\nNSString *resourceSessionID(NSString *url)\n{\n    if (url.length == 0) {\n        return @\"\";\n    }\n    return stringFromMD5(url);\n}\n\nNSString *stringFromMD5(NSString *url)\n{\n    \n    if(url == nil || [url length] == 0)\n        return nil;\n    \n    const char *value = [url UTF8String];\n    \n    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];\n    CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);\n    \n    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];\n    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){\n        [outputString appendFormat:@\"%02x\",outputBuffer[count]];\n    }\n    \n    return [outputString autorelease];\n}\n\n+ (NSString *)sonicUrl:(NSString *)aUrlStr\n{\n    NSURL *url = [NSURL URLWithString:aUrlStr];\n    if (!url) {\n        return aUrlStr;\n    }\n    \n    if([aUrlStr rangeOfString:@\"sonic_\"].location == NSNotFound){\n        return [NSString stringWithFormat:@\"%@://%@%@\",url.scheme,url.host,url.path];\n    }\n    \n    NSMutableDictionary *queryParams = queryComponents(aUrlStr);\n    \n    NSMutableString *sonicParamString = [NSMutableString string];\n    NSMutableArray *sonicChangeParamKeys = [NSMutableArray array];\n    \n    NSString *remainParams = queryParams[@\"sonic_remain_params\"];\n    if (remainParams.length > 0) {\n        [sonicChangeParamKeys addObjectsFromArray:[remainParams componentsSeparatedByString:@\";\"]];\n        [queryParams removeObjectForKey:@\"sonic_remain_params\"];\n    }\n    \n    for (NSString *key in queryParams.allKeys) {\n        if ([key hasPrefix:@\"sonic_\"]) {\n            [sonicParamString appendFormat:@\"%@=%@&\",key,queryParams[key]];\n        }\n        for(NSString *sonicChangeItem in sonicChangeParamKeys){\n            if ([sonicChangeItem isEqualToString:key]) {\n                [sonicParamString appendFormat:@\"%@=%@&\",sonicChangeItem,queryParams[sonicChangeItem]];\n            }\n        }\n    }\n    \n    if (sonicParamString.length > 0) {\n        return [NSString stringWithFormat:@\"%@://%@%@/%@\",url.scheme,url.host,url.path,sonicParamString];\n    }else{\n        return [NSString stringWithFormat:@\"%@://%@%@\",url.scheme,url.host,url.path];\n    }\n}\n\nNSMutableDictionary * queryComponents(NSString *aUrlStr)\n{\n    NSMutableDictionary *results = [NSMutableDictionary dictionary];\n    \n    NSURL *url = [NSURL URLWithString:aUrlStr];\n    if (!url) {\n        return results;\n    }\n    \n    NSString *queryStr = url.query;\n    if (queryStr && queryStr.length) {\n        NSArray *components = [queryStr componentsSeparatedByString:@\"&\"];\n        for (NSString *component in components) {\n            NSRange range = [component rangeOfString:@\"=\"];\n            NSString *key, *value;\n            if (range.location == NSNotFound) {\n                key = component;\n                value = @\"\";\n            }\n            else {\n                key = [component substringToIndex:range.location];\n                value = [component substringFromIndex:range.location + 1];\n            }\n            if (value == nil) value = @\"\";\n            if (key && key.length && value) {\n                [results setObject:value forKey:key];\n            }\n        }\n    }\n    \n    return results;\n}\n\nNSString * dispatchToMain (dispatch_block_t block)\n{\n    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:block];\n    [[NSOperationQueue mainQueue] addOperation:blockOp];\n    return [NSString stringWithFormat:@\"%ld\",(unsigned long)blockOp.hash];\n}\n\nNSString * getDataSha1(NSData *data)\n{\n    if (!data) {\n        return nil;\n    }\n    uint8_t digest[CC_SHA1_DIGEST_LENGTH];\n    CC_SHA1(data.bytes, (CC_LONG)data.length, digest);\n    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];\n    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)\n    {\n        [output appendFormat:@\"%02x\", digest[i]];\n    }\n    \n    return output;\n}\n\n+ (NSURLRequest *)sonicWebRequestWithSession:(SonicSession* )session withOrigin:(NSURLRequest *)originRequest\n{\n    NSMutableURLRequest *request = [[originRequest mutableCopy]autorelease];\n    [request setValue:SonicHeaderValueWebviewLoad forHTTPHeaderField:SonicHeaderKeyLoadType];\n    if (session) {\n        [request setValue:session.sessionID forHTTPHeaderField:SonicHeaderKeySessionID];\n        if (session.delegateId.length != 0) {\n            [request setValue:session.delegateId forHTTPHeaderField:SonicHeaderKeyDelegateId];\n        }\n    }\n    return request;\n}\n\n+ (NSDictionary *)splitTemplateAndDataFromHtmlData:(NSString *)html\n{\n    if (html.length == 0) {\n        return [NSDictionary dictionary];\n    }\n    \n    //using sonicdiff tag to split the HTML to template and dynamic data.\n    NSError *error = nil;\n    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@\"<!--sonicdiff-?(\\\\w*)-->([\\\\s\\\\S]+?)<!--sonicdiff-?(\\\\w*)-end-->\" options:NSRegularExpressionCaseInsensitive error:&error];\n    if (!error) {\n        NSMutableString *templateString = nil;\n        NSMutableDictionary *data = [NSMutableDictionary dictionary];\n        //create dynamic data\n        NSArray *metchs = [reg matchesInString:html options:NSMatchingReportCompletion range:NSMakeRange(0, html.length)];\n        [metchs enumerateObjectsUsingBlock:^(NSTextCheckingResult *obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            NSString *matchStr = [html substringWithRange:obj.range];\n            NSArray *seprateArr = [matchStr componentsSeparatedByString:@\"<!--sonicdiff-\"];\n            NSString *itemName = [[[seprateArr lastObject]componentsSeparatedByString:@\"-end-->\"]firstObject];\n            NSString *formatKey = [NSString stringWithFormat:@\"{%@}\",itemName];\n            [data setObject:matchStr forKey:formatKey];\n        }];\n        \n        //create template\n        templateString = [NSMutableString stringWithString:html];\n        [data enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL * _Nonnull stop) {\n            [templateString replaceOccurrencesOfString:value withString:key options:NSCaseInsensitiveSearch range:NSMakeRange(0, templateString.length)];\n        }];\n        \n       return @{kSonicDataFieldName:data,kSonicTemplateFieldName:templateString};\n    }\n    return @{kSonicDataFieldName:[NSDictionary dictionary],kSonicTemplateFieldName:html};\n}\n\n+ (NSDictionary *)mergeDynamicData:(NSDictionary *)updateDict withOriginData:(NSMutableDictionary *)existData\n{\n    NSMutableDictionary *diffData = [NSMutableDictionary dictionary];\n    \n    //get the diff data between server updateDict and local existData\n    for (NSString *key in updateDict.allKeys) {\n        NSString *updateValue = [updateDict objectForKey:key];\n        if ([existData.allKeys containsObject:key]) {\n            NSString *existValue = [existData objectForKey:key];\n            \n            if (![updateValue isEqualToString:existValue]) {\n                [diffData setObject:updateValue forKey:key];\n                [existData setObject:updateValue forKey:key];\n            }\n        }\n    }\n    \n    return @{kSonicDiffFieldName:diffData};\n}\n\n+ (NSDictionary *)protocolActionItem:(SonicURLProtocolAction)action param:(NSObject *)param\n{\n    if (param == nil) {\n        param = @\"\";\n    }\n    return @{kSonicProtocolAction:@(action),kSonicProtocolData:param};\n}\n\nunsigned long long currentTimeStamp(void)\n{\n    return (unsigned long long)([[NSDate date] timeIntervalSince1970]);\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/Sonic.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXAggregateTarget section */\n\t\t541AD0351F151C0E00E2BDEC /* SonicDoc */ = {\n\t\t\tisa = PBXAggregateTarget;\n\t\t\tbuildConfigurationList = 541AD0381F151C0E00E2BDEC /* Build configuration list for PBXAggregateTarget \"SonicDoc\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t541AD0391F151C7800E2BDEC /* ShellScript */,\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = SonicDoc;\n\t\t\tproductName = SonicDoc;\n\t\t};\n/* End PBXAggregateTarget section */\n\n/* Begin PBXBuildFile section */\n\t\t542F99F51FE769A000598258 /* SonicResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 542F99F31FE769A000598258 /* SonicResourceLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t542F99F61FE769A000598258 /* SonicResourceLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 542F99F41FE769A000598258 /* SonicResourceLoader.m */; };\n\t\t542F99F91FE7701B00598258 /* SonicResourceLoadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 542F99F71FE7701B00598258 /* SonicResourceLoadOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t542F99FA1FE7701B00598258 /* SonicResourceLoadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 542F99F81FE7701B00598258 /* SonicResourceLoadOperation.m */; };\n\t\t545D61C61F623BED00DA8F3A /* SonicConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 545D61C41F623BED00DA8F3A /* SonicConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t545D61C71F623BED00DA8F3A /* SonicConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D61C51F623BED00DA8F3A /* SonicConfiguration.m */; };\n\t\t546B78121F0105AA003F08AE /* Sonic.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B78101F0105AA003F08AE /* Sonic.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B78281F0105F6003F08AE /* SonicCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B78181F0105F6003F08AE /* SonicCache.m */; };\n\t\t546B78291F0105F6003F08AE /* SonicCacheItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B78191F0105F6003F08AE /* SonicCacheItem.m */; };\n\t\t546B782A1F0105F6003F08AE /* SonicEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B781A1F0105F6003F08AE /* SonicEngine.m */; };\n\t\t546B782B1F0105F6003F08AE /* SonicConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B781B1F0105F6003F08AE /* SonicConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B782C1F0105F6003F08AE /* SonicProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B781C1F0105F6003F08AE /* SonicProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B782D1F0105F6003F08AE /* SonicSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B781D1F0105F6003F08AE /* SonicSession.m */; };\n\t\t546B782E1F0105F6003F08AE /* SonicUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B781E1F0105F6003F08AE /* SonicUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B782F1F0105F6003F08AE /* SonicUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B781F1F0105F6003F08AE /* SonicUtil.m */; };\n\t\t546B78311F0105F6003F08AE /* SonicCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B78211F0105F6003F08AE /* SonicCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B78321F0105F6003F08AE /* SonicCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B78221F0105F6003F08AE /* SonicCacheItem.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B78331F0105F6003F08AE /* SonicEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B78231F0105F6003F08AE /* SonicEngine.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B78361F0105F6003F08AE /* SonicSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 546B78261F0105F6003F08AE /* SonicSession.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t546B78801F01F91D003F08AE /* Sonic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 546B780D1F0105AA003F08AE /* Sonic.framework */; };\n\t\t54BF62E7200858B6007129D5 /* SonicEventStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BF62E5200858B6007129D5 /* SonicEventStatistics.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54BF62E8200858B6007129D5 /* SonicEventStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = 54BF62E6200858B6007129D5 /* SonicEventStatistics.m */; };\n\t\t54BF62EB20085918007129D5 /* SonicEventConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BF62E920085918007129D5 /* SonicEventConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54BF62F42008E252007129D5 /* SonicConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BF62EE2008E251007129D5 /* SonicConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54BF62F52008E252007129D5 /* SonicConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 54BF62EF2008E251007129D5 /* SonicConnection.m */; };\n\t\t54BF62F62008E252007129D5 /* SonicServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BF62F02008E251007129D5 /* SonicServer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54BF62F72008E252007129D5 /* SonicServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 54BF62F12008E251007129D5 /* SonicServer.m */; };\n\t\t54BF62F82008E252007129D5 /* SonicURLProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BF62F22008E251007129D5 /* SonicURLProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54BF62F92008E252007129D5 /* SonicURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 54BF62F32008E251007129D5 /* SonicURLProtocol.m */; };\n\t\t54C2E2D21F6B79CF003EC647 /* SonicDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 54C2E2D01F6B79CF003EC647 /* SonicDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t54C2E2D31F6B79CF003EC647 /* SonicDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 54C2E2D11F6B79CF003EC647 /* SonicDatabase.m */; };\n\t\tE43E03461F618182000F30ED /* SonicSessionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = E43E03441F618182000F30ED /* SonicSessionConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tE43E03471F618182000F30ED /* SonicSessionConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = E43E03451F618182000F30ED /* SonicSessionConfiguration.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t546B78811F01F91D003F08AE /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 546B78041F0105AA003F08AE /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 546B780C1F0105AA003F08AE;\n\t\t\tremoteInfo = Sonic;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t542F99F31FE769A000598258 /* SonicResourceLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicResourceLoader.h; sourceTree = \"<group>\"; };\n\t\t542F99F41FE769A000598258 /* SonicResourceLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicResourceLoader.m; sourceTree = \"<group>\"; };\n\t\t542F99F71FE7701B00598258 /* SonicResourceLoadOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicResourceLoadOperation.h; sourceTree = \"<group>\"; };\n\t\t542F99F81FE7701B00598258 /* SonicResourceLoadOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicResourceLoadOperation.m; sourceTree = \"<group>\"; };\n\t\t545D61C41F623BED00DA8F3A /* SonicConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicConfiguration.h; sourceTree = \"<group>\"; };\n\t\t545D61C51F623BED00DA8F3A /* SonicConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicConfiguration.m; sourceTree = \"<group>\"; };\n\t\t546B780D1F0105AA003F08AE /* Sonic.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sonic.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t546B78101F0105AA003F08AE /* Sonic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sonic.h; sourceTree = \"<group>\"; };\n\t\t546B78111F0105AA003F08AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Sonic/Info.plist; sourceTree = \"<group>\"; };\n\t\t546B78181F0105F6003F08AE /* SonicCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicCache.m; sourceTree = \"<group>\"; };\n\t\t546B78191F0105F6003F08AE /* SonicCacheItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicCacheItem.m; sourceTree = \"<group>\"; };\n\t\t546B781A1F0105F6003F08AE /* SonicEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicEngine.m; sourceTree = \"<group>\"; };\n\t\t546B781B1F0105F6003F08AE /* SonicConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicConstants.h; sourceTree = \"<group>\"; };\n\t\t546B781C1F0105F6003F08AE /* SonicProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicProtocol.h; sourceTree = \"<group>\"; };\n\t\t546B781D1F0105F6003F08AE /* SonicSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicSession.m; sourceTree = \"<group>\"; };\n\t\t546B781E1F0105F6003F08AE /* SonicUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicUtil.h; sourceTree = \"<group>\"; };\n\t\t546B781F1F0105F6003F08AE /* SonicUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicUtil.m; sourceTree = \"<group>\"; };\n\t\t546B78211F0105F6003F08AE /* SonicCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicCache.h; sourceTree = \"<group>\"; };\n\t\t546B78221F0105F6003F08AE /* SonicCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicCacheItem.h; sourceTree = \"<group>\"; };\n\t\t546B78231F0105F6003F08AE /* SonicEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicEngine.h; sourceTree = \"<group>\"; };\n\t\t546B78261F0105F6003F08AE /* SonicSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicSession.h; sourceTree = \"<group>\"; };\n\t\t546B787B1F01F91D003F08AE /* SonicTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SonicTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t54BF62E5200858B6007129D5 /* SonicEventStatistics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicEventStatistics.h; sourceTree = \"<group>\"; };\n\t\t54BF62E6200858B6007129D5 /* SonicEventStatistics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicEventStatistics.m; sourceTree = \"<group>\"; };\n\t\t54BF62E920085918007129D5 /* SonicEventConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicEventConstants.h; sourceTree = \"<group>\"; };\n\t\t54BF62EE2008E251007129D5 /* SonicConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicConnection.h; sourceTree = \"<group>\"; };\n\t\t54BF62EF2008E251007129D5 /* SonicConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicConnection.m; sourceTree = \"<group>\"; };\n\t\t54BF62F02008E251007129D5 /* SonicServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicServer.h; sourceTree = \"<group>\"; };\n\t\t54BF62F12008E251007129D5 /* SonicServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicServer.m; sourceTree = \"<group>\"; };\n\t\t54BF62F22008E251007129D5 /* SonicURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicURLProtocol.h; sourceTree = \"<group>\"; };\n\t\t54BF62F32008E251007129D5 /* SonicURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicURLProtocol.m; sourceTree = \"<group>\"; };\n\t\t54C2E2D01F6B79CF003EC647 /* SonicDatabase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicDatabase.h; sourceTree = \"<group>\"; };\n\t\t54C2E2D11F6B79CF003EC647 /* SonicDatabase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicDatabase.m; sourceTree = \"<group>\"; };\n\t\t54E535A11F694A3A00A98AFE /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };\n\t\t54E535A31F69523500A98AFE /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };\n\t\tE43E03441F618182000F30ED /* SonicSessionConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicSessionConfiguration.h; sourceTree = \"<group>\"; };\n\t\tE43E03451F618182000F30ED /* SonicSessionConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicSessionConfiguration.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t546B78091F0105AA003F08AE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78781F01F91D003F08AE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t546B78801F01F91D003F08AE /* Sonic.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t542F99EE1FE768B400598258 /* Session */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE43E03441F618182000F30ED /* SonicSessionConfiguration.h */,\n\t\t\t\tE43E03451F618182000F30ED /* SonicSessionConfiguration.m */,\n\t\t\t\t546B781D1F0105F6003F08AE /* SonicSession.m */,\n\t\t\t\t546B78261F0105F6003F08AE /* SonicSession.h */,\n\t\t\t);\n\t\t\tpath = Session;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t542F99EF1FE768BB00598258 /* Cache */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t54C2E2D01F6B79CF003EC647 /* SonicDatabase.h */,\n\t\t\t\t54C2E2D11F6B79CF003EC647 /* SonicDatabase.m */,\n\t\t\t\t546B78181F0105F6003F08AE /* SonicCache.m */,\n\t\t\t\t546B78211F0105F6003F08AE /* SonicCache.h */,\n\t\t\t\t546B78191F0105F6003F08AE /* SonicCacheItem.m */,\n\t\t\t\t546B78221F0105F6003F08AE /* SonicCacheItem.h */,\n\t\t\t);\n\t\t\tpath = Cache;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t542F99F01FE768C200598258 /* Engine */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B781A1F0105F6003F08AE /* SonicEngine.m */,\n\t\t\t\t546B78231F0105F6003F08AE /* SonicEngine.h */,\n\t\t\t\t545D61C41F623BED00DA8F3A /* SonicConfiguration.h */,\n\t\t\t\t545D61C51F623BED00DA8F3A /* SonicConfiguration.m */,\n\t\t\t);\n\t\t\tpath = Engine;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t542F99F11FE768F900598258 /* Util */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B781E1F0105F6003F08AE /* SonicUtil.h */,\n\t\t\t\t546B781F1F0105F6003F08AE /* SonicUtil.m */,\n\t\t\t);\n\t\t\tpath = Util;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t542F99F21FE7695E00598258 /* ResourceLoader */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t542F99F31FE769A000598258 /* SonicResourceLoader.h */,\n\t\t\t\t542F99F41FE769A000598258 /* SonicResourceLoader.m */,\n\t\t\t\t542F99F71FE7701B00598258 /* SonicResourceLoadOperation.h */,\n\t\t\t\t542F99F81FE7701B00598258 /* SonicResourceLoadOperation.m */,\n\t\t\t);\n\t\t\tpath = ResourceLoader;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78031F0105AA003F08AE = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B780F1F0105AA003F08AE /* Sonic */,\n\t\t\t\t546B780E1F0105AA003F08AE /* Products */,\n\t\t\t\t546B78111F0105AA003F08AE /* Info.plist */,\n\t\t\t\t54E535A01F694A3A00A98AFE /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B780E1F0105AA003F08AE /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B780D1F0105AA003F08AE /* Sonic.framework */,\n\t\t\t\t546B787B1F01F91D003F08AE /* SonicTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B780F1F0105AA003F08AE /* Sonic */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t54BF62ED2008E251007129D5 /* Network */,\n\t\t\t\t54BF62E0200857DE007129D5 /* Statistics */,\n\t\t\t\t542F99F21FE7695E00598258 /* ResourceLoader */,\n\t\t\t\t542F99F11FE768F900598258 /* Util */,\n\t\t\t\t542F99F01FE768C200598258 /* Engine */,\n\t\t\t\t542F99EF1FE768BB00598258 /* Cache */,\n\t\t\t\t542F99EE1FE768B400598258 /* Session */,\n\t\t\t\t546B78101F0105AA003F08AE /* Sonic.h */,\n\t\t\t\t546B781B1F0105F6003F08AE /* SonicConstants.h */,\n\t\t\t\t546B781C1F0105F6003F08AE /* SonicProtocol.h */,\n\t\t\t);\n\t\t\tpath = Sonic;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t54BF62E0200857DE007129D5 /* Statistics */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t54BF62E5200858B6007129D5 /* SonicEventStatistics.h */,\n\t\t\t\t54BF62E6200858B6007129D5 /* SonicEventStatistics.m */,\n\t\t\t\t54BF62E920085918007129D5 /* SonicEventConstants.h */,\n\t\t\t);\n\t\t\tpath = Statistics;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t54BF62ED2008E251007129D5 /* Network */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t54BF62EE2008E251007129D5 /* SonicConnection.h */,\n\t\t\t\t54BF62EF2008E251007129D5 /* SonicConnection.m */,\n\t\t\t\t54BF62F02008E251007129D5 /* SonicServer.h */,\n\t\t\t\t54BF62F12008E251007129D5 /* SonicServer.m */,\n\t\t\t\t54BF62F22008E251007129D5 /* SonicURLProtocol.h */,\n\t\t\t\t54BF62F32008E251007129D5 /* SonicURLProtocol.m */,\n\t\t\t);\n\t\t\tpath = Network;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t54E535A01F694A3A00A98AFE /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t54E535A31F69523500A98AFE /* libsqlite3.0.tbd */,\n\t\t\t\t54E535A11F694A3A00A98AFE /* libsqlite3.tbd */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\t546B780A1F0105AA003F08AE /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t546B782B1F0105F6003F08AE /* SonicConstants.h in Headers */,\n\t\t\t\t546B782E1F0105F6003F08AE /* SonicUtil.h in Headers */,\n\t\t\t\t546B78361F0105F6003F08AE /* SonicSession.h in Headers */,\n\t\t\t\t546B782C1F0105F6003F08AE /* SonicProtocol.h in Headers */,\n\t\t\t\t546B78331F0105F6003F08AE /* SonicEngine.h in Headers */,\n\t\t\t\t546B78321F0105F6003F08AE /* SonicCacheItem.h in Headers */,\n\t\t\t\t54BF62F42008E252007129D5 /* SonicConnection.h in Headers */,\n\t\t\t\t54BF62EB20085918007129D5 /* SonicEventConstants.h in Headers */,\n\t\t\t\t542F99F91FE7701B00598258 /* SonicResourceLoadOperation.h in Headers */,\n\t\t\t\t54BF62E7200858B6007129D5 /* SonicEventStatistics.h in Headers */,\n\t\t\t\t54BF62F82008E252007129D5 /* SonicURLProtocol.h in Headers */,\n\t\t\t\t54BF62F62008E252007129D5 /* SonicServer.h in Headers */,\n\t\t\t\t542F99F51FE769A000598258 /* SonicResourceLoader.h in Headers */,\n\t\t\t\t546B78311F0105F6003F08AE /* SonicCache.h in Headers */,\n\t\t\t\tE43E03461F618182000F30ED /* SonicSessionConfiguration.h in Headers */,\n\t\t\t\t54C2E2D21F6B79CF003EC647 /* SonicDatabase.h in Headers */,\n\t\t\t\t545D61C61F623BED00DA8F3A /* SonicConfiguration.h in Headers */,\n\t\t\t\t546B78121F0105AA003F08AE /* Sonic.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\t546B780C1F0105AA003F08AE /* Sonic */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 546B78151F0105AA003F08AE /* Build configuration list for PBXNativeTarget \"Sonic\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t546B78081F0105AA003F08AE /* Sources */,\n\t\t\t\t546B78091F0105AA003F08AE /* Frameworks */,\n\t\t\t\t546B780A1F0105AA003F08AE /* Headers */,\n\t\t\t\t546B780B1F0105AA003F08AE /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Sonic;\n\t\t\tproductName = Sonic;\n\t\t\tproductReference = 546B780D1F0105AA003F08AE /* Sonic.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t546B787A1F01F91D003F08AE /* SonicTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 546B78831F01F91D003F08AE /* Build configuration list for PBXNativeTarget \"SonicTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t546B78771F01F91D003F08AE /* Sources */,\n\t\t\t\t546B78781F01F91D003F08AE /* Frameworks */,\n\t\t\t\t546B78791F01F91D003F08AE /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t546B78821F01F91D003F08AE /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = SonicTests;\n\t\t\tproductName = SonicTests;\n\t\t\tproductReference = 546B787B1F01F91D003F08AE /* SonicTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t546B78041F0105AA003F08AE /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0920;\n\t\t\t\tORGANIZATIONNAME = Tencent;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t541AD0351F151C0E00E2BDEC = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\t546B780C1F0105AA003F08AE = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\t546B787A1F01F91D003F08AE = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 546B78071F0105AA003F08AE /* Build configuration list for PBXProject \"Sonic\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = 546B78031F0105AA003F08AE;\n\t\t\tproductRefGroup = 546B780E1F0105AA003F08AE /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t546B780C1F0105AA003F08AE /* Sonic */,\n\t\t\t\t546B787A1F01F91D003F08AE /* SonicTests */,\n\t\t\t\t541AD0351F151C0E00E2BDEC /* SonicDoc */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t546B780B1F0105AA003F08AE /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78791F01F91D003F08AE /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t541AD0391F151C7800E2BDEC /* ShellScript */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 12;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"#appledoc Xcode script\\n# Start constants\\ncompany=\\\"Tencent\\\";\\ncompanyID=\\\"com.tencent\\\";\\ncompanyURL=\\\"http://www.qq.com\\\";\\ntarget=\\\"iphoneos\\\";\\n#target=\\\"macosx\\\";\\noutputPath=\\\"${SRCROOT}/docs/docset\\\";\\n# End constants\\n/usr/local/bin/appledoc \\\\\\n--project-name \\\"${PROJECT_NAME}\\\" \\\\\\n--project-company \\\"${company}\\\" \\\\\\n--company-id \\\"${companyID}\\\" \\\\\\n--docset-atom-filename \\\"${company}.atom\\\" \\\\\\n--docset-feed-url \\\"${companyURL}/${company}/%DOCSETATOMFILENAME\\\" \\\\\\n--docset-package-url \\\"${companyURL}/${company}/%DOCSETPACKAGEFILENAME\\\" \\\\\\n--docset-fallback-url \\\"${companyURL}/${company}\\\" \\\\\\n--output \\\"${outputPath}\\\" \\\\\\n--publish-docset \\\\\\n--docset-platform-family \\\"${target}\\\" \\\\\\n--logformat xcode \\\\\\n--keep-intermediate-files \\\\\\n--no-repeat-first-par \\\\\\n--no-warn-invalid-crossref \\\\\\n--exit-threshold 2 \\\\\\n\\\"${PROJECT_DIR}\\\"\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t546B78081F0105AA003F08AE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t546B782F1F0105F6003F08AE /* SonicUtil.m in Sources */,\n\t\t\t\t54BF62F92008E252007129D5 /* SonicURLProtocol.m in Sources */,\n\t\t\t\t54C2E2D31F6B79CF003EC647 /* SonicDatabase.m in Sources */,\n\t\t\t\t545D61C71F623BED00DA8F3A /* SonicConfiguration.m in Sources */,\n\t\t\t\t542F99FA1FE7701B00598258 /* SonicResourceLoadOperation.m in Sources */,\n\t\t\t\t546B782A1F0105F6003F08AE /* SonicEngine.m in Sources */,\n\t\t\t\t54BF62E8200858B6007129D5 /* SonicEventStatistics.m in Sources */,\n\t\t\t\t546B782D1F0105F6003F08AE /* SonicSession.m in Sources */,\n\t\t\t\t546B78291F0105F6003F08AE /* SonicCacheItem.m in Sources */,\n\t\t\t\t54BF62F52008E252007129D5 /* SonicConnection.m in Sources */,\n\t\t\t\t542F99F61FE769A000598258 /* SonicResourceLoader.m in Sources */,\n\t\t\t\t54BF62F72008E252007129D5 /* SonicServer.m in Sources */,\n\t\t\t\t546B78281F0105F6003F08AE /* SonicCache.m in Sources */,\n\t\t\t\tE43E03471F618182000F30ED /* SonicSessionConfiguration.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78771F01F91D003F08AE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t546B78821F01F91D003F08AE /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 546B780C1F0105AA003F08AE /* Sonic */;\n\t\t\ttargetProxy = 546B78811F01F91D003F08AE /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t541AD0361F151C0E00E2BDEC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t541AD0371F151C0E00E2BDEC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t546B78131F0105AA003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78141F0105AA003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t546B78161F0105AA003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\tCONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\";\n\t\t\t\tCONFIGURATION_TEMP_DIR = \"$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\";\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = Sonic/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tOTHER_CFLAGS = \"-fembed-bitcode\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-l\",\n\t\t\t\t\tsqlite3,\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.Sonic.Sonic;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"708a394e-c58f-44b5-af84-8daba31e4d18\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78171F0105AA003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\tCONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\";\n\t\t\t\tCONFIGURATION_TEMP_DIR = \"$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\";\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = Sonic/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tOTHER_CFLAGS = \"-fembed-bitcode\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-l\",\n\t\t\t\t\tsqlite3,\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.Sonic.Sonic;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"708a394e-c58f-44b5-af84-8daba31e4d18\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t546B78841F01F91D003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = SonicTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78851F01F91D003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = SonicTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t541AD0381F151C0E00E2BDEC /* Build configuration list for PBXAggregateTarget \"SonicDoc\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t541AD0361F151C0E00E2BDEC /* Debug */,\n\t\t\t\t541AD0371F151C0E00E2BDEC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t546B78071F0105AA003F08AE /* Build configuration list for PBXProject \"Sonic\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78131F0105AA003F08AE /* Debug */,\n\t\t\t\t546B78141F0105AA003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t546B78151F0105AA003F08AE /* Build configuration list for PBXNativeTarget \"Sonic\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78161F0105AA003F08AE /* Debug */,\n\t\t\t\t546B78171F0105AA003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t546B78831F01F91D003F08AE /* Build configuration list for PBXNativeTarget \"SonicTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78841F01F91D003F08AE /* Debug */,\n\t\t\t\t546B78851F01F91D003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 546B78041F0105AA003F08AE /* Project object */;\n}\n"
  },
  {
    "path": "sonic-iOS/Sonic.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:Sonic.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "sonic-iOS/Sonic.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:SonicSample/SonicSample.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Sonic.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/36f620dddab622727b270e6b79b20a98/main.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <script type=\"application/javascript\">\n        var _pageTime = {};\n        _pageTime.startTime = new Date;\n    </script>\n    <title>SONIC</title>\n    <style>\n        body {\n            margin: 0;\n            padding: 0;\n            font-size: 14px;\n            color: #777;\n            margin-top: 20px;\n        }\n        .sonic-wrapper {\n            padding: 0 12px;\n        }\n        .sonic-wrapper h1 {\n            font-size: 18px;\n            font-weight: 400;\n            color: #000;\n        }\n        .sonic-wrapper h2 {\n            font-size: 14px;\n            color: #000;\n        }\n        .sonic-wrapper p {\n            font-size: 14px;\n            color: #777;\n            line-height: 1.6em;\n        }\n        .sonic-wrapper img {\n            width: 100%;\n        }\n        .sonic-wrapper table {\n            width: 100%;\n        }\n        .sonic-wrapper table img {\n            width: 100%;\n        }\n        .sonic_des {display:none;}\n    </style>\n</head>\n<body>\n<div class=\"sonic-wrapper\">\n    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\n    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\n    <span id=\"data1Content\">\n    <!--sonicdiff-data1-->\n    <p>示例：</p>\n    <img src=\"//mc.vip.qq.com/img/img-1.png?max_age=2592000\" alt=\"\">\n    <!--sonicdiff-data1-end-->\n    </span>\n    <span id=\"des0\" class=\"sonic_des\">\n        <h2>非Sonic模式 点击到页面打开耗时:<span id=\"pageTime0\"></span></h2>\n        <p>普通直出的方式</p>\n    </span>\n    <span id=\"des1\" class=\"sonic_des\">\n        <h2>首次访问 点击到页面打开耗时:<span id=\"pageTime1\"></span></h2>\n        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\n    </span>\n    <span id=\"des2\" class=\"sonic_des\">\n        <h2>模版更新 点击到页面打开耗时:<span id=\"pageTime2\"></span></h2>\n        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\n    </span>\n    <span id=\"des3\" class=\"sonic_des\">\n        <h2>数据更新 点击到页面打开耗时:<span id=\"pageTime3\"></span></h2>\n        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\n    </span>\n    <span id=\"des4\" class=\"sonic_des\">\n        <h2>完全缓存 点击到页面打开耗时:<span id=\"pageTime4\"></span></h2>\n        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\n    </span>\n        <h2>页面打开速度效果对比</h2>\n    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\n\n    <table>\n        <tr>\n            <td>原有直出页面：</td>\n            <td>Sonic改造页面：</td>\n        </tr>\n        <tr>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\" alt=\"\"></td>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\" alt=\"\"></td>\n        </tr>\n    </table>\n        <h2>Sonic实现原理简介</h2>\n    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\n</div>\n<script>\n    _pageTime.jsendtTime = new Date();\n</script>\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\" id=\"seajsnode\"></script>\n<script>;var BJ_REPORT=function(r){if(r.BJ_REPORT)return r.BJ_REPORT;var e=[],n={},t={id:0,pid:0,uin:0,url:\"//badjs.vip.qq.com/badjs\",combo:1,ext:null,level:4,ignore:[],random:0,delay:100,submit:null,repeat:1,pvrandom:0,errrandom:0,furl:\"0\"},o=2,i=0,a=function(r,e){return Object.prototype.toString.call(r)===\"[object \"+(e||\"Object\")+\"]\"},u=function(r){var e=typeof r;return\"object\"===e&&!!r},c=function(r){return null===r?!0:a(r,\"Number\")?!1:!r},s=r.onerror;r.onerror=function(e,n,t,o,u){var c=e;i++,u&&u.stack&&(c=f(u)),a(c,\"Event\")&&(c+=c.type?\"--\"+c.type+\"--\"+(c.target?c.target.tagName+\"::\"+c.target.src:\"\"):\"\"),y.push({msg:c,target:n,rowNum:t,colNum:o}),j(),s&&s.apply(r,arguments)};var d=function(r){try{if(r.stack){var e=r.stack.match(\"https?://[^\\n]+\");e=e?e[0]:\"\";var n=e.match(\":(\\\\d+):(\\\\d+)\");n||(n=[0,0,0]);var t=f(r);return{msg:t,rowNum:n[1],colNum:n[2],target:e.replace(n[0],\"\")}}return r.name&&r.message&&r.description?{msg:JSON.stringify(r)}:r}catch(o){return r}},f=function(r){var e=r.stack.replace(/\\n/gi,\"\").split(/\\bat\\b/).slice(0,9).join(\"@\").replace(/\\?[^:]+/gi,\"\"),n=r.toString();return e.indexOf(n)<0&&(e=n+\"@\"+e),e},p=function(r,e){var n=[],o=[],i=[];if(u(r)){r.level=r.level||t.level;for(var a in r){var s=r[a];if(!c(s)){if(u(s))try{s=JSON.stringify(s)}catch(d){s=\"[BJ_REPORT detect value stringify error] \"+d.toString()}i.push(a+\":\"+s),n.push(a+\"=\"+encodeURIComponent(s)),o.push(a+\"[\"+e+\"]=\"+encodeURIComponent(s))}}}return[o.join(\"&\"),i.join(\",\"),n.join(\"&\")]},l=[],m=function(r){var e=new RegExp(\"badjspv\");if(e.test(r)||(r=g(r)),t.submit)t.submit(r);else{var n=new Image;l.push(n),n.src=r}},v=function(){var r=!1,e=new RegExp(\"debug=1\"),n=new RegExp(\"badjs=1\");n.test(document.cookie)&&(r=!0),(n.test(document.location.href)||e.test(document.location.href))&&(r=!0);var t=navigator.userAgent.toLowerCase();return/sq\\_[\\d\\.]+\\_\\d+\\_hdb/.test(t)&&(r=!0),r},g=function(r){return r+=\"&ic=\"+i,v()&&(r+=\"&ig=1\"),r},h=function(r){if(!u(r))return!0;var e=r.msg,o=n[e]=(parseInt(n[e],10)||0)+1;return o>t.repeat},R=[],b=0,j=function(r){if(t.report){for(;e.length;){var n=!1,o=e.shift();if(!h(o)){var i=p(o,R.length);if(a(t.ignore,\"Array\"))for(var u=0,c=t.ignore.length;c>u;u++){var s=t.ignore[u];if(a(s,\"RegExp\")&&s.test(i[1])||a(s,\"Function\")&&s(o,i[1])){n=!0;break}}n||(t.combo?R.push(i[0]):m(t.report+i[2]+\"&_t=\"+ +new Date),t.onReport&&t.onReport(t.id,o))}}var d=R.length;if(d){var f=function(){clearTimeout(b),m(t.report+R.join(\"&\")+\"&count=\"+R.length+\"&_t=\"+ +new Date),b=0,R=[]};r?f():b||(b=setTimeout(f,t.delay))}}},y={push:function(r){if(1===t.random||v());else{var n=Math.round(9*Math.random()+1);if(0===t.errrandom){if(9!=n)return y}else{var o=10*t.errrandom/10;if(o>=1||t.errrandom<.1);else{for(var i=10*t.errrandom,a=[],c=1;i>=c;c++)a.push(c);if(!_(n,a))return y}}}var s=u(r)?d(r):{msg:r};return t.ext&&!s.ext&&(s.ext=t.ext),e.push(s),j(),y},report:function(r){return r&&y.push(r),j(!0),y},info:function(r){return r?(u(r)?r.level=2:r={msg:r,level:2},y.push(r),y):y},debug:function(r){return r?(u(r)?r.level=1:r={msg:r,level:1},y.push(r),y):y},init:function(r){if(u(r))for(var n in r)t[n]=r[n];var i=parseInt(t.id,10);return i&&(w(),/qq\\.com$/gi.test(location.hostname)&&(t.url||(t.url=\"//badjs.vip.qq.com/badjs\"),t.uin||(t.uin=parseInt((document.cookie.match(/\\buin=\\D+(\\d+)/)||[])[1],10))),t.report=(t.url||\"/badjs\")+\"?id=\"+i+\"&pid=\"+t.pid+\"&uin=\"+t.uin+\"&v=\"+o+\"&from=\"+encodeURIComponent(y.referrer())+\"&furl=\"+encodeURIComponent(t.furl)+\"&\"),e.length&&j(),y},referrer:function(){var r=\"\";try{r=window.top.document.referrer}catch(e){if(window.parent)try{r=window.parent.document.referrer}catch(n){r=\"\"}}return\"\"===r&&(r=document.referrer),r},__onerror__:r.onerror},_=function(r,e){for(var n in e)if(r==e[n])return!0},w=function(){var r=\"//badjs.vip.qq.com/badjspv?id=\"+t.id+\"&pid=\"+t.pid+\"&v=\"+o+\"&furl=\"+encodeURIComponent(t.furl);if(1==t.random||v())m(r);else{var e=Math.round(99*Math.random()+1);if(0===t.pvrandom)9==e&&m(r);else{var n=100*t.pvrandom/100;if(n>=1||t.pvrandom<.01)m(r);else{for(var i=100*t.pvrandom,a=[],u=1;i>=u;u++)a.push(u);_(e,a)&&m(r)}}}};return\"undefined\"!=typeof console&&console.error&&setTimeout(function(){var r=((location.hash||\"\").match(/([#&])BJ_ERROR=([^&$]+)/)||[])[2];r&&console.error(\"BJ_ERROR\",decodeURIComponent(r).replace(/(:\\d+:\\d+)\\s*/g,\"$1\\n\"))},0),y}(window);\"undefined\"!=typeof exports&&(\"undefined\"!=typeof module&&module.exports&&(exports=module.exports=BJ_REPORT),exports.BJ_REPORT=BJ_REPORT);</script>\n<script>\n    if(window.BJ_REPORT) {\n        (function(){\n            var bjParam = {id:38,pvrandom:0.1,errrandom:1,furl:'h5.vip.qq.com/p/sonic/mc/vipcenterv5', ignore:[/(QzoneApp|publicTube|load failed|DCReport|qw is not defined|object Event|XMLHttpRequest)/i]};\n                        BJ_REPORT.init(bjParam);\n        })();\n    }\n    seajs.config({\n        base: 'http://imgcache.gtimg.cn/club/platform/examples/',\n        localcache:{\n            //浏览器缓存时间\n            maxAge: 2592000,\n            openLocalStorageCache: 0\n        },\n        maxFile : {\n\n        },\n        debug:1,\n        //别名\n        alias:{\n            'zepto': 'lib/zepto/zepto'\n        },\n        paths:{\n            'lib' : 'http://imgcache.gtimg.cn/club/platform/lib'\n        },\n        manifest:{\n            \"lib/zepto/zepto\": \"1.1.3\",\n            \"lib/sonic/sonic\": \"3-1\"\n        }\n    });\n\n    seajs.use([\"zepto\", \"lib/sonic/sonic\"],function($, sonic){\n        /**\n         * 后置函数 sonic或普通模式 执行页面初始化等操作\n         */\n        function afterInit(sonicStatus){\n            $('.sonic_des').css('display', 'none');\n            $('#des'+sonicStatus).css('display', 'block');\n            //耗时分析(上报)\n            var performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\n            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\n            $(\"#pageTime\"+sonicStatus).text(pageTime+'ms');\n        }\n                /**\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\n         * @param sonicStatus\n         * @param reportSonicStatus\n         * @param sonicUpdateData\n         */\n        window.sonicStartTime = new Date;\n        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\n            if(sonicStatus == 1){\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\n            }else if(sonicStatus == 2){\n\n            }else if(sonicStatus == 3){\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\n                var html = '';\n                var id = '';\n                var elementObj = '';\n                for(var key in sonicUpdateData){\n                    id = key.substring(1,key.length-1);\n                    html = sonicUpdateData[key];\n                    elementObj = document.getElementById(id+'Content');\n                    elementObj.innerHTML = html;\n                }\n\n            }else if(sonicStatus == 4){\n\n            }\n            afterInit(reportSonicStatus);\n        });\n            });\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n\n@end\n\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n#import \"RootViewController.h\"\n@import Sonic;\n\n@interface AppDelegate ()\n\n@end\n\n@implementation AppDelegate\n\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    // Override point for customization after application launch.\n    \n    //NSURLProtocol\n    [NSURLProtocol registerClass:[SonicURLProtocol class]];\n    \n    RootViewController *rootVC = [[RootViewController alloc]init];\n    UINavigationController *rootNav = [[UINavigationController alloc]initWithRootViewController:rootVC];\n    \n    //start web thread\n    UIWebView *webPool = [[UIWebView alloc]initWithFrame:CGRectZero];\n    [webPool loadHTMLString:@\"\" baseURL:nil];\n    \n    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];\n    self.window.rootViewController = rootNav;\n    self.window.backgroundColor = [UIColor whiteColor];\n    [self.window makeKeyAndVisible];\n    \n    return YES;\n}\n\n\n- (void)applicationWillResignActive:(UIApplication *)application {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n}\n\n\n- (void)applicationDidEnterBackground:(UIApplication *)application {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n}\n\n\n- (void)applicationWillEnterForeground:(UIApplication *)application {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n}\n\n\n- (void)applicationDidBecomeActive:(UIApplication *)application {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n}\n\n\n- (void)applicationWillTerminate:(UIApplication *)application {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n}\n\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIconFile</key>\n\t<string>logo.jpg</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UIRequiresFullScreen</key>\n\t<false/>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"11134\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"11106\"/>\n        <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Llm-lL-Icb\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xb3-aO-Qok\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"  Copyright © 2017年 Tencent. All rights reserved.\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"obG-Y5-kRd\">\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"SonicSample\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GJd-Yh-RWb\">\n                                <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"centerX\" id=\"5cz-MP-9tL\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"GJd-Yh-RWb\" secondAttribute=\"centerX\" id=\"Q3B-4B-g5h\"/>\n                            <constraint firstItem=\"obG-Y5-kRd\" firstAttribute=\"leading\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"SfN-ll-jLj\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"bottom\" constant=\"20\" id=\"Y44-ml-fuU\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"moa-c2-u7t\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"leading\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"x7j-FC-K8j\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/RootViewController.h",
    "content": "//\n//  RootViewController.h\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface RootViewController : UIViewController\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/RootViewController.m",
    "content": "//\n//  RootViewController.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"RootViewController.h\"\n#import \"SonicWebViewController.h\"\n#import \"SonicOfflineCacheConnection.h\"\n#import \"SonicEventObserver.h\"\n\n@import Sonic;\n\n@interface RootViewController ()\n\n@property (nonatomic,strong)NSString *url;\n\n@end\n\n@implementation RootViewController\n\n- (instancetype)init\n{\n    if (self = [super init]) {\n        \n        self.title = @\"Sonic\";\n        \n        self.url = @\"http://mc.vip.qq.com/demo/indexv3\";\n\n    }\n    return self;\n}\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    \n    //Subclass the SonicConnection to return offline cache\n    [SonicSession registerSonicConnection:[SonicOfflineCacheConnection class]];\n    \n    //add event observer\n    SonicEventObserver *observer = [SonicEventObserver new];\n    [[SonicEventStatistics shareStatistics] addEventObserver:observer];\n\n    //header\n    UIImageView *header = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@\"header.png\"]];\n    header.frame = CGRectMake(0, SizeFitHeightPlus(65), SizeFitWidthPlus(214), SizeFitHeightPlus(59));\n    header.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, header.frame.origin.y+header.frame.size.height/2);\n    [self.view addSubview:header];\n    \n    [self setupSubViews];\n    \n    [self setupBottomLabel];\n}\n\n- (void)viewWillDisappear:(BOOL)animated\n{\n    [self.navigationController setNavigationBarHidden:NO animated:NO];\n    [super viewWillDisappear:animated];\n}\n\n- (void)viewWillAppear:(BOOL)animated\n{\n    [self.navigationController setNavigationBarHidden:YES animated:NO];\n    [super viewWillAppear:animated];\n}\n\n- (void)setupSubViews\n{\n    [self createButtonWithIndex:0 withTitle:@\"LOAD WITHOUT SONIC\" withAction:@selector(normalRequestAction)];\n    [self createButtonWithIndex:1 withTitle:@\"LOAD WITH SONIC\" withAction:@selector(sonicRequestAction)];\n    [self createButtonWithIndex:2 withTitle:@\"LOAD WITH UNSTRICT SONIC\" withAction:@selector(unstrictModeSonicRequestAction)];\n    [self createButtonWithIndex:3 withTitle:@\"LOAD WITH RESOURCE PRELOAD\" withAction:@selector(sonicResourcePreloadAction)];\n    [self createButtonWithIndex:4 withTitle:@\"LOAD SONIC WITH OFFLINE CACHE\" withAction:@selector(loadWithOfflineFileAction)];\n    [self createButtonWithIndex:5 withTitle:@\"DO SONIC PRELOAD\" withAction:@selector(sonicPreloadAction)];\n    [self createButtonWithIndex:6 withTitle:@\"CLEAN UP CACHE\" withAction:@selector(clearAllCacheAction)];\n}\n\n- (void)setupBottomLabel\n{\n    UILabel *bottomLabel = [[UILabel alloc]init];\n    bottomLabel.text = @\"腾讯增值技术团队出品\";\n    bottomLabel.textColor = [UIColor grayColor];\n    [bottomLabel sizeToFit];\n    bottomLabel.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height - SizeFitHeightPlus(30.f) - bottomLabel.frame.size.height/2);\n    \n    [self.view addSubview:bottomLabel];\n}\n\n- (void)createButtonWithIndex:(NSInteger)index withTitle:(NSString *)title withAction:(SEL)action\n{\n    CGFloat offsetX = SizeFitWidthPlus(12.f);\n    CGFloat rowMargin = SizeFitHeightPlus(13.f);\n    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;\n    CGFloat buttonWidth = screenWidth - 2*offsetX;\n    CGFloat buttonHeight = SizeFitHeightPlus(44.f);\n    \n    CGFloat offsetY = SizeFitHeightPlus(160) + (index+1) * rowMargin + index *buttonHeight;\n    \n    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];\n    button.frame = CGRectMake(offsetX, offsetY, buttonWidth, buttonHeight);\n    button.layer.cornerRadius = SizeFitHeightPlus(5);\n    button.layer.masksToBounds = YES;\n    UIColor *color = [self colorWithRGBHexString:@\"#049DFF\"];\n    UIImage *normalBack = [self imageFromColor:color];\n    [button setBackgroundImage:normalBack forState:UIControlStateNormal];\n    [button setTitle:title forState:UIControlStateNormal];\n    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];\n    [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];\n    \n    [self.view addSubview:button];\n}\n\nstatic CGFloat SizeFitWidthPlus(CGFloat value)\n{\n    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;\n    return screenWidth < 375? (value/375)*screenWidth:value;\n}\n\nstatic CGFloat SizeFitHeightPlus(CGFloat value)\n{\n    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;\n    return screenHeight < 667? (value/667)*screenHeight:value;\n}\n\n- (void)normalRequestAction\n{\n    SonicWebViewController *webVC = [[SonicWebViewController alloc]initWithUrl:self.url useSonicMode:NO unStrictMode:NO];\n    [self.navigationController pushViewController:webVC animated:YES];\n}\n\n- (void)sonicResourcePreloadAction\n{\n    SonicWebViewController *webVC = [[SonicWebViewController alloc]initWithUrl:@\"http://www.kgc.cn/zhuanti/bigca.shtml?jump=1\" useSonicMode:YES unStrictMode:YES];\n    [self.navigationController pushViewController:webVC animated:YES];\n}\n\n- (void)sonicPreloadAction\n{\n    [[SonicEngine sharedEngine] createSessionWithUrl:self.url withWebDelegate:nil];\n    [self alertMessage:@\"Preload Start!\"];\n}\n\n- (void)sonicRequestAction\n{\n    SonicWebViewController *webVC = [[SonicWebViewController alloc]initWithUrl:self.url useSonicMode:YES unStrictMode:NO];\n    [self.navigationController pushViewController:webVC animated:YES];\n}\n\n- (void)unstrictModeSonicRequestAction\n{\n    SonicWebViewController *webVC = [[SonicWebViewController alloc]initWithUrl:@\"http://www.kgc.cn/zhuanti/bigca.shtml?jump=1\" useSonicMode:YES unStrictMode:YES];\n    [self.navigationController pushViewController:webVC animated:YES];\n}\n\n- (void)loadWithOfflineFileAction\n{\n    SonicWebViewController *webVC = [[SonicWebViewController alloc]initWithUrl:@\"http://mc.vip.qq.com/demo/indexv3?offline=1\" useSonicMode:YES unStrictMode:NO];\n    [self.navigationController pushViewController:webVC animated:YES];\n}\n\n- (void)clearAllCacheAction\n{\n    [[SonicEngine sharedEngine] clearAllCache];\n    [self alertMessage:@\"Clear Success!\"];\n}\n\n- (void)alertMessage:(NSString *)message\n{\n    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@\"\" message:message delegate:nil cancelButtonTitle:@\"Done\" otherButtonTitles:nil, nil];\n    [alert show];\n}\n\n#pragma mark - Uitil\n\n- (UIColor *)colorWithRGBHexString:(NSString *)rgbString\n{\n    if ([rgbString length] == 0) {\n        return nil;\n    }\n    \n    NSScanner *scanner = [NSScanner scannerWithString:rgbString];\n    if ([rgbString hasPrefix:@\"#\"]) {\n        scanner.scanLocation = 1;\n    }\n    else if (rgbString.length >= 2 && [[[rgbString substringToIndex:2] lowercaseString] isEqualToString:@\"0x\"]) {\n        scanner.scanLocation = 2;\n    }\n    \n    unsigned int value = 0;\n    [scanner scanHexInt:&value];\n    \n    return [self colorWithRGBHex:value];\n}\n\n- (UIColor *)colorWithRGBHex: (unsigned int)hex\n{\n    int r = (hex >> 16) & 0xFF;\n    int g = (hex >> 8) & 0xFF;\n    int b = (hex) & 0xFF;\n    \n    return [UIColor colorWithRed:r / 255.0f\n                           green:g / 255.0f\n                            blue:b / 255.0f\n                           alpha:1.0f];\n}\n\n- (UIImage *)imageFromColor:(UIColor *)color\n{\n    CGRect rect = CGRectMake(0, 0, 1, 1);\n    UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextSetFillColorWithColor(context, color.CGColor);\n    CGContextFillRect(context, rect);\n    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    return image;\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicEventObserver.h",
    "content": "//\n//  SonicEventObserver.h\n//  SonicSample\n//\n//  Created by zyvincenthu on 2018/1/15.\n//  Copyright © 2018年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@import Sonic;\n\n@interface SonicEventObserver : NSObject<SonicEventStatisticsObserver>\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicEventObserver.m",
    "content": "//\n//  SonicEventObserver.m\n//  SonicSample\n//\n//  Created by zyvincenthu on 2018/1/15.\n//  Copyright © 2018年 Tencent. All rights reserved.\n//\n\n#import \"SonicEventObserver.h\"\n\n@implementation SonicEventObserver\n\n+ (NSString *)eventTypeToString:(SonicStatisticsEvent)event\n{\n    NSDictionary *relation = @{\n                               @(SonicStatisticsEvent_SubResourceDidFail):@\"SubResourceDidFail\",\n                               @(SonicStatisticsEvent_SubResourceLoadLocalCache):@\"SubResourceLoadLocalCache\",\n                               @(SonicStatisticsEvent_SubResourceDidSave):@\"SubResourceDidSave\",\n                               @(SonicStatisticsEvent_TrimCache):@\"TrimCache\",\n                               @(SonicStatisticsEvent_SessionDestroy):@\"SessionDestroy\",\n                               @(SonicStatisticsEvent_SessionRefresh):@\"SessionRefresh\",\n                               @(SonicStatisticsEvent_SessionHitCache):@\"SessionHitCache\",\n                               @(SonicStatisticsEvent_SessionFirstLoad):@\"SessionFirstLoad\",\n                               @(SonicStatisticsEvent_SessionHttpError):@\"SessionHttpError\",\n                               @(SonicStatisticsEvent_SessionRecvResponse):@\"SessionRecvResponse\",\n                               @(SonicStatisticsEvent_SessionDataUpdated):@\"SessionDataUpdated\",\n                               @(SonicStatisticsEvent_SessionDidLoadLocalCache):@\"SessionDidLoadLocalCache\",\n                               @(SonicStatisticsEvent_SessionUnavilable):@\"SessionUnavilable\",\n                               @(SonicStatisticsEvent_SessionTemplateChanged):@\"SessionTemplateChanged\",\n                               };\n    return relation[@(event)];\n}\n\n- (void)handleEvent:(SonicStatisticsEvent)event withEventInfo:(NSDictionary *)info\n{\n    if (event == SonicStatisticsEvent_EventLog) {\n        NSLog(@\"%@\",info[@\"logMsg\"]);\n    }else{\n        NSString *eventString = [SonicEventObserver eventTypeToString:event];\n        SonicLogEvent(@\"event :%@ info:%@\",eventString,info.debugDescription);\n    }\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicJSContext.h",
    "content": "//\n//  SonicJSContext.h\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import <JavaScriptCore/JavaScriptCore.h>\n#import \"SonicWebViewController.h\"\n\n@protocol SonicJSExport <JSExport>\n\nJSExportAs(getDiffData,\n- (void)getDiffData:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n);\n\nJSExportAs(getPerformance,\n- (NSString *)getPerformance:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n);\n\n@end\n\n@interface SonicJSContext : NSObject<SonicJSExport>\n\n@property (nonatomic,weak)SonicWebViewController *owner;\n\n- (void)getDiffData:(NSDictionary *)option withCallBack:(JSValue *)jscallback;\n\n- (NSString *)getPerformance:(NSDictionary *)option withCallBack:(JSValue *)jscallback;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicJSContext.m",
    "content": "//\n//  SonicJSContext.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicJSContext.h\"\n#import <Sonic/Sonic.h>\n\n@implementation SonicJSContext\n\n- (void)getDiffData:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n{\n    SonicWebViewController *owner = self.owner;\n    if (!owner) { return; }\n    \n    __weak typeof(SonicWebViewController *) weakOwner = owner;\n    [[SonicEngine sharedEngine] sonicUpdateDiffDataByWebDelegate:owner completion:^(NSDictionary *result) {\n        __strong typeof(SonicWebViewController *) strongOwner = weakOwner;\n        if (strongOwner && result) {\n            JSValue *callback = strongOwner.jscontext.globalObject;\n            NSData *json = [NSJSONSerialization dataWithJSONObject:result options:NSJSONWritingPrettyPrinted error:nil];\n            NSString *jsonStr = [[NSString alloc]initWithData:json encoding:NSUTF8StringEncoding];\n            \n            [callback invokeMethod:@\"getDiffDataCallback\" withArguments:@[jsonStr]];\n        }\n    }];\n}\n\n- (NSString *)getPerformance:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n{\n    NSDictionary *result = @{\n                             @\"clickTime\":@(self.owner.clickTime),\n                             };\n    NSData *json = [NSJSONSerialization dataWithJSONObject:result options:NSJSONWritingPrettyPrinted error:nil];\n    NSString *jsonStr = [[NSString alloc]initWithData:json encoding:NSUTF8StringEncoding];\n    \n    return jsonStr;\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicOfflineCacheConnection.h",
    "content": "//\n//  SonicOfflineCacheRequest.h\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n@import Sonic;\n\n@interface SonicOfflineCacheConnection : SonicConnection\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicOfflineCacheConnection.m",
    "content": "//\n//  SonicOfflineCacheRequest.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicOfflineCacheConnection.h\"\n\n@implementation SonicOfflineCacheConnection\n\n+ (BOOL)canInitWithRequest:(NSURLRequest *)request\n{\n    if ([request.URL.absoluteString isEqualToString:@\"http://mc.vip.qq.com/demo/indexv3?offline=1\"]) {\n        return YES;\n    }\n    return NO;\n}\n\n- (void)startLoading\n{\n    NSString *offlinePath = [[NSBundle mainBundle]pathForResource:@\"main\" ofType:@\"html\"];\n    NSData *htmlData = [NSData dataWithContentsOfFile:offlinePath];\n    \n    NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc]initWithURL:self.request.URL MIMEType:@\"text/html\" expectedContentLength:htmlData.length textEncodingName:@\"utf8\"];\n    \n    [self.delegate connection:self didReceiveResponse:response];\n    [self.delegate connection:self didReceiveData:htmlData];\n    [self.delegate connectionDidCompleteWithoutError:self];\n}\n\n- (void)stopLoading\n{\n    \n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicWebViewController.h",
    "content": "//\n//  SonicWebViewController.h\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n#import <JavaScriptCore/JavaScriptCore.h>\n@import Sonic;\n\n@interface SonicWebViewController : UIViewController<SonicSessionDelegate,UIWebViewDelegate>\n@property (nonatomic,strong)NSString *url;\n@property (nonatomic,strong)UIWebView *webView;\n@property (nonatomic,assign)long long clickTime;\n@property (nonatomic,weak)JSContext *jscontext;\n\n- (instancetype)initWithUrl:(NSString *)aUrl useSonicMode:(BOOL)isSonic unStrictMode:(BOOL)state;\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/SonicWebViewController.m",
    "content": "//\n//  SonicWebViewController.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import \"SonicWebViewController.h\"\n#import \"SonicJSContext.h\"\n\n@interface SonicWebViewController ()\n\n@property (nonatomic,strong)SonicJSContext *sonicContext;\n\n@property (nonatomic,assign)BOOL isStandSonic;\n\n@end\n\n@implementation SonicWebViewController\n\n- (instancetype)initWithUrl:(NSString *)aUrl useSonicMode:(BOOL)isSonic unStrictMode:(BOOL)state\n{\n    if (self = [super init]) {\n        \n        self.url = aUrl;\n        \n        self.clickTime = (long long)([[NSDate date]timeIntervalSince1970]*1000);\n        \n        if (isSonic) {\n            if (state) {\n                SonicSessionConfiguration *configuration = [SonicSessionConfiguration new];\n                NSString *linkValue = @\"http://assets.kgc.cn/ff7f069b/css/common-min.www.kgc.css?v=e4ecfe82;http://assets.kgc.cn/ff7f069b/css/themes.www.kgc.css?v=612eb426;http://assets.kgc.cn/ff7f069b/css/style.www.kgc.css?v=05d94f84\";\n                configuration.customResponseHeaders = @{\n                                                        SonicHeaderKeyCacheOffline:SonicHeaderValueCacheOfflineStore,\n                                                        SonicHeaderKeyLink:linkValue\n                                                        };\n                configuration.enableLocalServer = YES;\n                configuration.supportCacheControl = YES;\n                [[SonicEngine sharedEngine] createSessionWithUrl:self.url withWebDelegate:self withConfiguration:configuration];\n            }else{\n                self.isStandSonic = YES;\n                [[SonicEngine sharedEngine] createSessionWithUrl:self.url withWebDelegate:self];\n            }\n        }\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    self.sonicContext = nil;\n    [[SonicEngine sharedEngine] removeSessionWithWebDelegate:self];\n}\n\n- (void)loadView\n{\n    [super loadView];\n    \n    self.webView = [[UIWebView alloc]initWithFrame:self.view.bounds];\n    self.webView.delegate = self;\n    self.webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;\n    self.view = self.webView;\n    \n    if (self.isStandSonic) {\n        UIBarButtonItem *reloadItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(updateAction)];\n        self.navigationItem.rightBarButtonItem = reloadItem;\n    }\n    \n    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];\n    \n    SonicSession* session = [[SonicEngine sharedEngine] sessionWithWebDelegate:self];\n    if (session) {\n        [self.webView loadRequest:[SonicUtil sonicWebRequestWithSession:session withOrigin:request]];\n    }else{\n        [self.webView loadRequest:request];\n    }\n    \n    self.sonicContext = [[SonicJSContext alloc]init];\n    self.sonicContext.owner = self;\n}\n\n- (void)updateAction\n{\n    [[SonicEngine sharedEngine] reloadSessionWithWebDelegate:self completion:^(NSDictionary *result) {\n        \n    }];\n}\n\n#pragma mark - UIWebViewDelegate\n\n- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType\n{\n    self.jscontext = [self.webView valueForKeyPath:@\"documentView.webView.mainFrame.javaScriptContext\"];\n    self.jscontext[@\"sonic\"] = self.sonicContext;\n    \n    return YES;\n}\n\n- (void)webViewDidFinishLoad:(UIWebView *)webView\n{\n    self.jscontext = [self.webView valueForKeyPath:@\"documentView.webView.mainFrame.javaScriptContext\"];\n    self.jscontext[@\"sonic\"] = self.sonicContext;\n}\n\n#pragma mark - Sonic Session Delegate\n\n- (void)sessionWillRequest:(SonicSession *)session\n{\n    //可以在请求发起前同步Cookie等信息\n}\n\n- (void)session:(SonicSession *)session requireWebViewReload:(NSURLRequest *)request\n{\n    [self.webView loadRequest:request];\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample/main.m",
    "content": "//\n//  main.m\n//  SonicSample\n//\n//  Tencent is pleased to support the open source community by making VasSonic available.\n//  Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n//  Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n//  in compliance with the License. You may obtain a copy of the License at\n//\n//  https://opensource.org/licenses/BSD-3-Clause\n//\n//  Unless required by applicable law or agreed to in writing, software distributed under the\n//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n//  either express or implied. See the License for the specific language governing permissions\n//  and limitations under the License.\n//\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t5428A2751F17A97200AF122B /* header.png in Resources */ = {isa = PBXBuildFile; fileRef = 5428A2741F17A97200AF122B /* header.png */; };\n\t\t5433CC291F171DDB00F24C1B /* Sonic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5433CC281F171DDB00F24C1B /* Sonic.framework */; };\n\t\t5433CC301F1725EE00F24C1B /* logo.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 5433CC2F1F17245B00F24C1B /* logo.jpg */; };\n\t\t5436964A1F166A0F00579BA5 /* main.html in Resources */ = {isa = PBXBuildFile; fileRef = 543696461F166A0F00579BA5 /* main.html */; };\n\t\t5436964E1F166A4200579BA5 /* SonicOfflineCacheConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 5436964D1F166A4200579BA5 /* SonicOfflineCacheConnection.m */; };\n\t\t546B78461F0106C8003F08AE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B78451F0106C8003F08AE /* main.m */; };\n\t\t546B78491F0106C8003F08AE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B78481F0106C8003F08AE /* AppDelegate.m */; };\n\t\t546B78511F0106C8003F08AE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 546B78501F0106C8003F08AE /* Assets.xcassets */; };\n\t\t546B785F1F0106C8003F08AE /* SonicSampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B785E1F0106C8003F08AE /* SonicSampleUITests.m */; };\n\t\t546B78711F010710003F08AE /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B786C1F010710003F08AE /* RootViewController.m */; };\n\t\t546B78721F010710003F08AE /* SonicJSContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B786E1F010710003F08AE /* SonicJSContext.m */; };\n\t\t546B78731F010710003F08AE /* SonicWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B78701F010710003F08AE /* SonicWebViewController.m */; };\n\t\t546F47F1200C87C10086CCF1 /* SonicEventObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 546F47F0200C87C10086CCF1 /* SonicEventObserver.m */; };\n\t\t54DEED511F0D06C2007E9A7F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 54DEED501F0D06C2007E9A7F /* LaunchScreen.storyboard */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t546B785B1F0106C8003F08AE /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 546B78391F0106C8003F08AE /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 546B78401F0106C8003F08AE;\n\t\t\tremoteInfo = SonicSample;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t5428A2741F17A97200AF122B /* header.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = header.png; sourceTree = \"<group>\"; };\n\t\t5433CC281F171DDB00F24C1B /* Sonic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sonic.framework; path = \"../../../../../../Library/Developer/Xcode/DerivedData/Sonic-butbvuzcjkdxhofbrefepmvmhzgc/Build/Products/Debug-iphoneos/Sonic.framework\"; sourceTree = \"<group>\"; };\n\t\t5433CC2F1F17245B00F24C1B /* logo.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = logo.jpg; sourceTree = \"<group>\"; };\n\t\t543696461F166A0F00579BA5 /* main.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = main.html; sourceTree = \"<group>\"; };\n\t\t5436964C1F166A4200579BA5 /* SonicOfflineCacheConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicOfflineCacheConnection.h; sourceTree = \"<group>\"; };\n\t\t5436964D1F166A4200579BA5 /* SonicOfflineCacheConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicOfflineCacheConnection.m; sourceTree = \"<group>\"; };\n\t\t546B78411F0106C8003F08AE /* SonicSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SonicSample.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t546B78451F0106C8003F08AE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\t546B78471F0106C8003F08AE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t546B78481F0106C8003F08AE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t546B78501F0106C8003F08AE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t546B78551F0106C8003F08AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t546B785A1F0106C8003F08AE /* SonicSampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SonicSampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t546B785E1F0106C8003F08AE /* SonicSampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicSampleUITests.m; sourceTree = \"<group>\"; };\n\t\t546B78601F0106C8003F08AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t546B786B1F010710003F08AE /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = \"<group>\"; };\n\t\t546B786C1F010710003F08AE /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = \"<group>\"; };\n\t\t546B786D1F010710003F08AE /* SonicJSContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicJSContext.h; sourceTree = \"<group>\"; };\n\t\t546B786E1F010710003F08AE /* SonicJSContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicJSContext.m; sourceTree = \"<group>\"; };\n\t\t546B786F1F010710003F08AE /* SonicWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SonicWebViewController.h; sourceTree = \"<group>\"; };\n\t\t546B78701F010710003F08AE /* SonicWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SonicWebViewController.m; sourceTree = \"<group>\"; };\n\t\t546F47EF200C87C10086CCF1 /* SonicEventObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SonicEventObserver.h; sourceTree = \"<group>\"; };\n\t\t546F47F0200C87C10086CCF1 /* SonicEventObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SonicEventObserver.m; sourceTree = \"<group>\"; };\n\t\t54DEED501F0D06C2007E9A7F /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t546B783E1F0106C8003F08AE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t5433CC291F171DDB00F24C1B /* Sonic.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78571F0106C8003F08AE /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t543696431F166A0F00579BA5 /* offline */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t543696461F166A0F00579BA5 /* main.html */,\n\t\t\t);\n\t\t\tname = offline;\n\t\t\tpath = 36f620dddab622727b270e6b79b20a98;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78381F0106C8003F08AE = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B78431F0106C8003F08AE /* SonicSample */,\n\t\t\t\t546B785D1F0106C8003F08AE /* SonicSampleUITests */,\n\t\t\t\t546B78421F0106C8003F08AE /* Products */,\n\t\t\t\t546B78741F0107D9003F08AE /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78421F0106C8003F08AE /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B78411F0106C8003F08AE /* SonicSample.app */,\n\t\t\t\t546B785A1F0106C8003F08AE /* SonicSampleUITests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78431F0106C8003F08AE /* SonicSample */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B786A1F010702003F08AE /* Classes */,\n\t\t\t\t546B78691F0106D2003F08AE /* Application */,\n\t\t\t\t546B78441F0106C8003F08AE /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = SonicSample;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78441F0106C8003F08AE /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B78451F0106C8003F08AE /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B785D1F0106C8003F08AE /* SonicSampleUITests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t546B785E1F0106C8003F08AE /* SonicSampleUITests.m */,\n\t\t\t\t546B78601F0106C8003F08AE /* Info.plist */,\n\t\t\t);\n\t\t\tpath = SonicSampleUITests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78691F0106D2003F08AE /* Application */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5428A2741F17A97200AF122B /* header.png */,\n\t\t\t\t5433CC2F1F17245B00F24C1B /* logo.jpg */,\n\t\t\t\t546B78471F0106C8003F08AE /* AppDelegate.h */,\n\t\t\t\t546B78481F0106C8003F08AE /* AppDelegate.m */,\n\t\t\t\t546B78501F0106C8003F08AE /* Assets.xcassets */,\n\t\t\t\t546B78551F0106C8003F08AE /* Info.plist */,\n\t\t\t\t54DEED501F0D06C2007E9A7F /* LaunchScreen.storyboard */,\n\t\t\t);\n\t\t\tname = Application;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B786A1F010702003F08AE /* Classes */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t543696431F166A0F00579BA5 /* offline */,\n\t\t\t\t546B786B1F010710003F08AE /* RootViewController.h */,\n\t\t\t\t546B786C1F010710003F08AE /* RootViewController.m */,\n\t\t\t\t546B786D1F010710003F08AE /* SonicJSContext.h */,\n\t\t\t\t546B786E1F010710003F08AE /* SonicJSContext.m */,\n\t\t\t\t546B786F1F010710003F08AE /* SonicWebViewController.h */,\n\t\t\t\t546B78701F010710003F08AE /* SonicWebViewController.m */,\n\t\t\t\t5436964C1F166A4200579BA5 /* SonicOfflineCacheConnection.h */,\n\t\t\t\t5436964D1F166A4200579BA5 /* SonicOfflineCacheConnection.m */,\n\t\t\t\t546F47EF200C87C10086CCF1 /* SonicEventObserver.h */,\n\t\t\t\t546F47F0200C87C10086CCF1 /* SonicEventObserver.m */,\n\t\t\t);\n\t\t\tname = Classes;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t546B78741F0107D9003F08AE /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5433CC281F171DDB00F24C1B /* Sonic.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t546B78401F0106C8003F08AE /* SonicSample */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 546B78631F0106C8003F08AE /* Build configuration list for PBXNativeTarget \"SonicSample\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t546B783D1F0106C8003F08AE /* Sources */,\n\t\t\t\t546B783E1F0106C8003F08AE /* Frameworks */,\n\t\t\t\t546B783F1F0106C8003F08AE /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = SonicSample;\n\t\t\tproductName = SonicSample;\n\t\t\tproductReference = 546B78411F0106C8003F08AE /* SonicSample.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t546B78591F0106C8003F08AE /* SonicSampleUITests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 546B78661F0106C8003F08AE /* Build configuration list for PBXNativeTarget \"SonicSampleUITests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t546B78561F0106C8003F08AE /* Sources */,\n\t\t\t\t546B78571F0106C8003F08AE /* Frameworks */,\n\t\t\t\t546B78581F0106C8003F08AE /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t546B785C1F0106C8003F08AE /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = SonicSampleUITests;\n\t\t\tproductName = SonicSampleUITests;\n\t\t\tproductReference = 546B785A1F0106C8003F08AE /* SonicSampleUITests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.ui-testing\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t546B78391F0106C8003F08AE /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0920;\n\t\t\t\tORGANIZATIONNAME = Tencent;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t546B78401F0106C8003F08AE = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2;\n\t\t\t\t\t\tDevelopmentTeam = Q4ZJ4XF89A;\n\t\t\t\t\t\tProvisioningStyle = Manual;\n\t\t\t\t\t};\n\t\t\t\t\t546B78591F0106C8003F08AE = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tTestTargetID = 546B78401F0106C8003F08AE;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 546B783C1F0106C8003F08AE /* Build configuration list for PBXProject \"SonicSample\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 546B78381F0106C8003F08AE;\n\t\t\tproductRefGroup = 546B78421F0106C8003F08AE /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t546B78401F0106C8003F08AE /* SonicSample */,\n\t\t\t\t546B78591F0106C8003F08AE /* SonicSampleUITests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t546B783F1F0106C8003F08AE /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t5433CC301F1725EE00F24C1B /* logo.jpg in Resources */,\n\t\t\t\t54DEED511F0D06C2007E9A7F /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t5436964A1F166A0F00579BA5 /* main.html in Resources */,\n\t\t\t\t5428A2751F17A97200AF122B /* header.png in Resources */,\n\t\t\t\t546B78511F0106C8003F08AE /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78581F0106C8003F08AE /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t546B783D1F0106C8003F08AE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t546B78491F0106C8003F08AE /* AppDelegate.m in Sources */,\n\t\t\t\t546B78721F010710003F08AE /* SonicJSContext.m in Sources */,\n\t\t\t\t546B78461F0106C8003F08AE /* main.m in Sources */,\n\t\t\t\t546B78711F010710003F08AE /* RootViewController.m in Sources */,\n\t\t\t\t546B78731F010710003F08AE /* SonicWebViewController.m in Sources */,\n\t\t\t\t5436964E1F166A4200579BA5 /* SonicOfflineCacheConnection.m in Sources */,\n\t\t\t\t546F47F1200C87C10086CCF1 /* SonicEventObserver.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t546B78561F0106C8003F08AE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t546B785F1F0106C8003F08AE /* SonicSampleUITests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t546B785C1F0106C8003F08AE /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 546B78401F0106C8003F08AE /* SonicSample */;\n\t\t\ttargetProxy = 546B785B1F0106C8003F08AE /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t546B78611F0106C8003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPROVISIONING_PROFILE = \"708a394e-c58f-44b5-af84-8daba31e4d18\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78621F0106C8003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tPROVISIONING_PROFILE = \"708a394e-c58f-44b5-af84-8daba31e4d18\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t546B78641F0106C8003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer: Ming Huang (RMP465DM7N)\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tDEVELOPMENT_TEAM = Q4ZJ4XF89A;\n\t\t\t\tINFOPLIST_FILE = SonicSample/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_CODE_SIGN_FLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicSample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"708a394e-c58f-44b5-af84-8daba31e4d18\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = VasQQDev;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78651F0106C8003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tDEVELOPMENT_TEAM = \"\";\n\t\t\t\tINFOPLIST_FILE = SonicSample/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_CODE_SIGN_FLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicSample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t546B78671F0106C8003F08AE /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = SonicSampleUITests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicSampleUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = SonicSample;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t546B78681F0106C8003F08AE /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = SonicSampleUITests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.tencent.SonicSampleUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = SonicSample;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t546B783C1F0106C8003F08AE /* Build configuration list for PBXProject \"SonicSample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78611F0106C8003F08AE /* Debug */,\n\t\t\t\t546B78621F0106C8003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t546B78631F0106C8003F08AE /* Build configuration list for PBXNativeTarget \"SonicSample\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78641F0106C8003F08AE /* Debug */,\n\t\t\t\t546B78651F0106C8003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t546B78661F0106C8003F08AE /* Build configuration list for PBXNativeTarget \"SonicSampleUITests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t546B78671F0106C8003F08AE /* Debug */,\n\t\t\t\t546B78681F0106C8003F08AE /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 546B78391F0106C8003F08AE /* Project object */;\n}\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:SonicSample.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSampleUITests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "sonic-iOS/SonicSample/SonicSampleUITests/SonicSampleUITests.m",
    "content": "//\n//  SonicSampleUITests.m\n//  SonicSampleUITests\n//\n//  Created by zyvincenthu on 2017/6/26.\n//  Copyright © 2017年 Tencent. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface SonicSampleUITests : XCTestCase\n\n@end\n\n@implementation SonicSampleUITests\n\n- (void)setUp {\n    [super setUp];\n    \n    // Put setup code here. This method is called before the invocation of each test method in the class.\n    \n    // In UI tests it is usually best to stop immediately when a failure occurs.\n    self.continueAfterFailure = NO;\n    // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.\n    [[[XCUIApplication alloc] init] launch];\n    \n    // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // Use recording to get started writing UI tests.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n@end\n"
  },
  {
    "path": "sonic-iOS/docs/iOS终端实现原理.md",
    "content": "# sonic iOS端实现原理\n\n## Sonic主要实现思路\n     基于后端渲染直出的页面拆分成(模版)＋(数据)＝(网页)的模式，在不同场景下，针对(模版)和(数据)分别做更新；\n     \n## 主要功能模块构成\n\n### 1.SonicSession\n\n    单个页面主资源加载所使用的会话，负责当次链接的完整状态流程。会在创建的sonic线程完成网络的加载。\n\n### 2.SonicClient\n\n    负责管理所有的Session,通过传入Url，创建对应的session\n    \n### 3.SonicURLProtocol\n\n    负责拦截WebView产生的主资源请求，将SonicSession发起的网络流桥接给WebKit\n    \n### 4.SonicCache\n  \n    负责为SonicSession提供缓存处理和缓存的返回，建立内存的缓存，会在这里做模板的更新与拆分。\n    \n### 5.SonicConnection\n\n    可以继承此基类，提供针对特定的URL完成所需的资源加载，比如离线资源，可以通过这个方式加载到WebKit。\n    \n## 四大模式场景\n\n### 1.首次加载\n在首次加载页面的时候在未创建UIWebView之前建立起网络链接，等待UIWebView发起主资源请求到NSURLProtocol层完成拦截，并且将提前发起的数据流通过NSURLProtocol返回给WebKit,实现网络提前的并行加载；在网络流完成结束后，对网页数据进行正则匹配，拆分成模板和数据分别保存，保存成功后保存完整的html网页;\n<img src=\"first.png\" width=100% height=100%>\n\n### 2.局部刷新\n有网页缓存情况下，二次进入打开页面前先载入完整的html页面缓存，并且在sonic线程发起请求获取可变的数据部分；在网络回包响应中通过template-change字段判定未发生模板更新，通过与上一次保存的（数据）部分与当次更新的（数据）部分进行对比更新；完成后与（模板）部分进行合并，拼接成新的html网页进行缓存；同时将数据的差异部分通过js回调传递给页面进行局部刷新；\n<img src=\"dataUpdate.png\" width=100% height=100%>\n\n### 3.模版更新\n有网页缓存情况下，二次进入打开页面前先载入完整的html页面缓存，并且在sonic线程发起请求获取可变的数据部分；在网络回包响应中通过template-change字段判定发生模板更新，这里旧的模板和数据已经无法使用，模板更新返回的是一个全新全量的html网页，对网页按照首次加载的模式进行处理，对网页数据进行正则匹配，拆分成模板和数据分别保存，保存成功后保存完整的html网页，然后通过session的回调让UIWebView重新发起一次请求，以便在NSURLProtocol层将新的网页数据返回给UIWebView展示出来；\n<img src=\"TemplateChange.png\" width=100% height=100%>\n\n### 4.完全缓存\n有网页缓存的情况下，二次进入打开页面前先载入完整的html页面缓存，收到页面响应为304，终端不需要任何动作，更新一下本次操作的响应时间参数。\n<img src=\"allCache.png\" width=100% height=100%>\n"
  },
  {
    "path": "sonic-iOS/docs/终端接入指引-iOS版本.md",
    "content": "\n## 终端接入指引-iOS版本\n\n### 1. 引入头文件，声明协议\n\n### (1.1)编译对应平台所需的Sonic.framework ,在Build目录找到.framework文件\n\n### (1.2)将Sonic.framework引入主工程\n在```AppDelegate```中注册```SonicURLProtocol```\n```Objective-C\n      [NSURLProtocol registerClass:[SonicURLProtocol class]];\n```\n\n### (1.3)引入 @import Sonic;\n```Objective-C\n      @interface SonicWebViewController : UIViewController<SonicSessionDelegate,UIWebViewDelegate>\n```\n\n## 2. 实现SonicSessionDelegate\n```Objective-C\n#pragma mark - Sonic Session Delegate\n\n/*\n * sonic请求发起前回调\n */\n- (void)sessionWillRequest:(SonicSession *)session\n{\n    //可以在请求发起前同步Cookie等信息\n}\n\n/*\n * sonic要求webView重新load指定request\n */\n- (void)session:(SonicSession *)session requireWebViewReload:(NSURLRequest *)request\n{\n    [self.webView loadRequest:request];\n}\n```\n\n## 3. 在WebView的ViewController中接入Sonic使用 (Sample:SonicWebViewController)\n```Objective-C\n/*\n * 在初始化ViewController的时候发起sonic的请求\n */\n- (instancetype)initWithUrl:(NSString *)aUrl\n{\n    if (self = [super init]) {\n        \n        self.url = aUrl;\n        \n        self.clickTime = (long long)[[NSDate date]timeIntervalSince1970]*1000; \n\n        //使用sonic链接创建一个会话\n        [[SonicClient sharedClient] createSessionWithUrl:self.url withWebDelegate:self];\n    }\n    return self;\n}\n\n/*\n * 在初始化WebView之后立即发起带有sonic信息的请求\n */\n- (void)loadView\n{\n    [super loadView];\n    \n    self.webView = [[UIWebView alloc]initWithFrame:self.view.bounds];\n    self.webView.delegate = self;\n    self.view = self.webView;\n    \n    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];\n    \n    /*\n     * 查询当前ViewController是否成功创建sonic会话，如果已经创建，那么包装request成sonic请求，以便在NSURLProtocol层拦截\n     * 否则走正常模式加载请求，不会在NSURLProtocol层拦截\n     */\n    if ([[SonicClient sharedClient] sessionWithWebDelegate:self]) {\n        [self.webView loadRequest:sonicWebRequest(request)];\n    }else{\n        [self.webView loadRequest:request];\n    }\n}\n```\n\n## 4. 调用获取差异的接口，传递sonic会话的结果信息\n```Objective-C\n/*\n * 此接口由页面驱动，由前端sonic组件向终端发起请求获取会话结果\n */\n- (void)getDiffData:(NSDictionary *)option withCallBack:(JSValue *)jscallback\n{\n\t/*\n\t * 根据发起sonic会话的ViewController来查询需要的结果\n\t */\n    [[SonicClient sharedClient] sonicUpdateDiffDataByWebDelegate:self.owner completion:^(NSDictionary *result) {\n       \n        /*\n         * 这里将result传递回页面即可\n         */\n        NSData *json = [NSJSONSerialization dataWithJSONObject:result options:NSJSONWritingPrettyPrinted error:nil];\n        NSString *jsonStr = [[NSString alloc]initWithData:json encoding:NSUTF8StringEncoding];\n        \n        JSValue *callback = self.owner.jscontext.globalObject;\n        [callback invokeMethod:@\"getDiffDataCallback\" withArguments:@[jsonStr]];\n        \n    }];\n}\n```\n\n## 5. 在WebDelegate销毁的时候移除WebDelegate对应的Session\n```Objective-C\n\n- (void)dealloc\n{\n[[SonicClient sharedClient] removeSessionWithWebDelegate:self];\n}\n```\n"
  },
  {
    "path": "sonic-java/README.md",
    "content": "## Getting started with Java\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n## How to use for Server\n### Dependencies\n\n1)Apache Tomcat\n\n2)Download VasSonic-1.1.jar and put it in your Java project. If you are familiar with Maven, you can get VasSonic-1.1.jar from [Maven repository](http://search.maven.org/#search%7Cga%7C1%7CVasSonic).\n\n3)Configure the Application Deployment Descriptor - \"web.xml\" in your project. put the following code in web.xml before any other filter or servlet config. \n\n```xml\n  <filter>\n    <filter-name>SonicFilter</filter-name>\n    <filter-class>com.github.tencent.SonicFilter</filter-class>\n  </filter>\n  <filter-mapping>\n    <filter-name>SonicFilter</filter-name>\n    <url-pattern>/*</url-pattern>\n  </filter-mapping>\n```\n4) Redeploy your web apps, and restart server.\n\n\n## How to use for front-end\nHere is a simple demo shows how to use Sonic for front-end.\n```Html\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n    <title>demo</title>\n    <script type=\"text/javascript\">\n            \n            // Interacts with mobile client by JavaScript interface to get Sonic diff data.\n            function getDiffData(){\n                window.sonic.getDiffData();\n            }\n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.   \n           function getDiffDataCallback(result){\n                var sonicStatus = 0; \n                /**\n                * The Sonic status:\n                * 0: It fails to get any data from mobile client.\n                * 1: It is first time for mobile client to use Sonic.\n                * 2: Mobile client reload the whole websites.\n                * 3: Websites will be updated dynamically with local refresh.\n                * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\n                */\n                sonicUpdateData = {}; //sonic diff data\n                var result = JSON.parse(result);\n                if(result['code'] == 200){\n                    sonicStatus = 3;\n                    sonicUpdateData = JSON.parse(result['result']);\n                } else if (result['code'] == 1000) {\n                    sonicStatus = 1;\n                } else if (result['code'] == 2000) {\n                    sonicStatus = 2;\n                } else if(result['code'] == 304) {\n                    sonicStatus = 4;\n                }\n                handleSonicDiffData(sonicStatus, sonicUpdateData);\n            }\n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.  \n            function handleSonicDiffData(sonicStatus, sonicUpdateData){\n                if(sonicStatus == 3){\n                    //Websites will be updated dynamically and run some JavaScript while in local refresh mode. \n                    var html = '';\n                    var id = '';\n                    var elementObj = '';\n                    for(var key in sonicUpdateData){\n                        id = key.substring(1,key.length-1);\n                        html = sonicUpdateData[key];\n                        elementObj = document.getElementById(id+'Content');\n                        elementObj.innerHTML = html;\n                    }\n                }\n            }\n    </script>\n</head>\n<body>\n    // step 1: specify template and data by inserting different comment anchor.\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n    \n    // step 2: Receives diff data from mobile client through Javascript interface.\n    <script type=\"text/javascript\">\n        window.onload = function(){\n            getDiffData();\n        }\n    </script>\n</body>\n</html>\n```\n### Step 1:\nSpecify template and data by inserting different comment anchor. The data will be wrapped with anchor ```<!-- sonicdiff-moduleName -->```  ```<!-- sonicdiff-moduleName-end -->```. The other part of html is template.\n```Html\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n```\n\n### Step 2:\nReceives 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.\n```Html\n<script type=\"text/javascript\">\n    window.onload = function(){\n        getDiffData();\n    }\n</script>\n```\n\n### Step 3:\nHandle 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.\n```Html\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction getDiffDataCallback(result){\n｝\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction handleSonicDiffData(sonicStatus, sonicUpdateData){\n｝\n```\n## Demo\nCopy the 'sample' directory into Tomcat 'webapps' directory, Then restart tomcat server, make a request [http://localhost:8080/sample/webapp/index.jsp](http://localhost:8080/sample/webapp/index.jsp).\n\n## Support\nAny problem?\n\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-java/sample).\n2. Contact us for help.\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n"
  },
  {
    "path": "sonic-java/apidocs/allclasses-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>所有类 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\">所有类</h1>\n<div class=\"indexContainer\">\n<ul>\n<li><a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">AbstractReplaceCallBack</a></li>\n<li><a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">HttpServletResponseCopier</a></li>\n<li><a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\" target=\"classFrame\"><span class=\"interfaceName\">ReplaceCallBack</span></a></li>\n<li><a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">ServletOutputStreamCopier</a></li>\n<li><a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">SonicFilter</a></li>\n<li><a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">SonicUtil</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/allclasses-noframe.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>所有类 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\">所有类</h1>\n<div class=\"indexContainer\">\n<ul>\n<li><a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></li>\n<li><a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></li>\n<li><a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"interfaceName\">ReplaceCallBack</span></a></li>\n<li><a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></li>\n<li><a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></li>\n<li><a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/AbstractReplaceCallBack.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>AbstractReplaceCallBack (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"AbstractReplaceCallBack (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6,\"i1\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/AbstractReplaceCallBack.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/AbstractReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"AbstractReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"类 AbstractReplaceCallBack\" class=\"title\">类 AbstractReplaceCallBack</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">java.lang.Object</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.github.tencent.AbstractReplaceCallBack</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public abstract class <span class=\"typeNameLabel\">AbstractReplaceCallBack</span>\nextends <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a>\nimplements <a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a></pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"字段概要表, 列表字段和解释\">\n<caption><span>字段</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">字段和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>protected <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html#matcher\">matcher</a></span></code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html#AbstractReplaceCallBack--\">AbstractReplaceCallBack</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>abstract <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html#doReplace-java.lang.String-int-java.util.regex.Matcher-\">doReplace</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n         int&nbsp;index,\n         <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</code>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">replace</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n       int&nbsp;index,\n       <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</code>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#clone--\" title=\"java.lang中的类或接口\">clone</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-\" title=\"java.lang中的类或接口\">equals</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#finalize--\" title=\"java.lang中的类或接口\">finalize</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#getClass--\" title=\"java.lang中的类或接口\">getClass</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#hashCode--\" title=\"java.lang中的类或接口\">hashCode</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notify--\" title=\"java.lang中的类或接口\">notify</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notifyAll--\" title=\"java.lang中的类或接口\">notifyAll</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#toString--\" title=\"java.lang中的类或接口\">toString</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait--\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\" title=\"java.lang中的类或接口\">wait</a></code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ FIELD DETAIL =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.detail\">\n<!--   -->\n</a>\n<h3>字段详细资料</h3>\n<a name=\"matcher\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>matcher</h4>\n<pre>protected&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a> matcher</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"AbstractReplaceCallBack--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>AbstractReplaceCallBack</h4>\n<pre>public&nbsp;AbstractReplaceCallBack()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"replace-java.lang.String-int-java.util.regex.Matcher-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>replace</h4>\n<pre>public final&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;replace(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n                            int&nbsp;index,\n                            <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</pre>\n<div class=\"block\"><span class=\"descfrmTypeLabel\">从接口复制的说明:&nbsp;<code><a href=\"../../../com/github/tencent/ReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">ReplaceCallBack</a></code></span></div>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"../../../com/github/tencent/ReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">replace</a></code>&nbsp;在接口中&nbsp;<code><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a></code></dd>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>text</code> - 指定的字符串</dd>\n<dd><code>index</code> - 替换的次序</dd>\n<dd><code>matcher</code> - Matcher对象</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n<a name=\"doReplace-java.lang.String-int-java.util.regex.Matcher-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>doReplace</h4>\n<pre>public abstract&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;doReplace(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n                                 int&nbsp;index,\n                                 <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</pre>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>text</code> - 指定的字符串</dd>\n<dd><code>index</code> - 替换的次序</dd>\n<dd><code>matcher</code> - Matcher对象</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/AbstractReplaceCallBack.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个类</li>\n<li><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/AbstractReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"AbstractReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li><a href=\"#field.summary\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li><a href=\"#field.detail\">字段</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/HttpServletResponseCopier.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>HttpServletResponseCopier (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"HttpServletResponseCopier (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/HttpServletResponseCopier.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/HttpServletResponseCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"HttpServletResponseCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"类 HttpServletResponseCopier\" class=\"title\">类 HttpServletResponseCopier</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">java.lang.Object</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>javax.servlet.ServletResponseWrapper</li>\n<li>\n<ul class=\"inheritance\">\n<li>javax.servlet.http.HttpServletResponseWrapper</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.github.tencent.HttpServletResponseCopier</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>javax.servlet.http.HttpServletResponse, javax.servlet.ServletResponse</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">HttpServletResponseCopier</span>\nextends javax.servlet.http.HttpServletResponseWrapper</pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- =========== FIELD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"field.summary\">\n<!--   -->\n</a>\n<h3>字段概要</h3>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"fields.inherited.from.class.javax.servlet.http.HttpServletResponse\">\n<!--   -->\n</a>\n<h3>从接口继承的字段&nbsp;javax.servlet.http.HttpServletResponse</h3>\n<code>SC_ACCEPTED, SC_BAD_GATEWAY, SC_BAD_REQUEST, SC_CONFLICT, SC_CONTINUE, SC_CREATED, SC_EXPECTATION_FAILED, SC_FORBIDDEN, SC_FOUND, SC_GATEWAY_TIMEOUT, SC_GONE, SC_HTTP_VERSION_NOT_SUPPORTED, SC_INTERNAL_SERVER_ERROR, SC_LENGTH_REQUIRED, SC_METHOD_NOT_ALLOWED, SC_MOVED_PERMANENTLY, SC_MOVED_TEMPORARILY, SC_MULTIPLE_CHOICES, SC_NO_CONTENT, SC_NON_AUTHORITATIVE_INFORMATION, SC_NOT_ACCEPTABLE, SC_NOT_FOUND, SC_NOT_IMPLEMENTED, SC_NOT_MODIFIED, SC_OK, SC_PARTIAL_CONTENT, SC_PAYMENT_REQUIRED, SC_PRECONDITION_FAILED, SC_PROXY_AUTHENTICATION_REQUIRED, SC_REQUEST_ENTITY_TOO_LARGE, SC_REQUEST_TIMEOUT, SC_REQUEST_URI_TOO_LONG, SC_REQUESTED_RANGE_NOT_SATISFIABLE, SC_RESET_CONTENT, SC_SEE_OTHER, SC_SERVICE_UNAVAILABLE, SC_SWITCHING_PROTOCOLS, SC_TEMPORARY_REDIRECT, SC_UNAUTHORIZED, SC_UNSUPPORTED_MEDIA_TYPE, SC_USE_PROXY</code></li>\n</ul>\n</li>\n</ul>\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html#HttpServletResponseCopier-javax.servlet.http.HttpServletResponse-\">HttpServletResponseCopier</a></span>(javax.servlet.http.HttpServletResponse&nbsp;response)</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html#flushBuffer--\">flushBuffer</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>byte[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html#getCopy--\">getCopy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>javax.servlet.ServletOutputStream</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html#getOutputStream--\">getOutputStream</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html?is-external=true\" title=\"java.io中的类或接口\">PrintWriter</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html#getWriter--\">getWriter</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.javax.servlet.http.HttpServletResponseWrapper\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;javax.servlet.http.HttpServletResponseWrapper</h3>\n<code>addCookie, addDateHeader, addHeader, addIntHeader, containsHeader, encodeRedirectUrl, encodeRedirectURL, encodeUrl, encodeURL, getHeader, getHeaderNames, getHeaders, getStatus, getTrailerFields, sendError, sendError, sendRedirect, setDateHeader, setHeader, setIntHeader, setStatus, setStatus, setTrailerFields</code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.javax.servlet.ServletResponseWrapper\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;javax.servlet.ServletResponseWrapper</h3>\n<code>getBufferSize, getCharacterEncoding, getContentType, getLocale, getResponse, isCommitted, isWrapperFor, isWrapperFor, reset, resetBuffer, setBufferSize, setCharacterEncoding, setContentLength, setContentLengthLong, setContentType, setLocale, setResponse</code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#clone--\" title=\"java.lang中的类或接口\">clone</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-\" title=\"java.lang中的类或接口\">equals</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#finalize--\" title=\"java.lang中的类或接口\">finalize</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#getClass--\" title=\"java.lang中的类或接口\">getClass</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#hashCode--\" title=\"java.lang中的类或接口\">hashCode</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notify--\" title=\"java.lang中的类或接口\">notify</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notifyAll--\" title=\"java.lang中的类或接口\">notifyAll</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#toString--\" title=\"java.lang中的类或接口\">toString</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait--\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\" title=\"java.lang中的类或接口\">wait</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.javax.servlet.ServletResponse\">\n<!--   -->\n</a>\n<h3>从接口继承的方法&nbsp;javax.servlet.ServletResponse</h3>\n<code>getBufferSize, getCharacterEncoding, getContentType, getLocale, isCommitted, reset, resetBuffer, setBufferSize, setCharacterEncoding, setContentLength, setContentLengthLong, setContentType, setLocale</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"HttpServletResponseCopier-javax.servlet.http.HttpServletResponse-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>HttpServletResponseCopier</h4>\n<pre>public&nbsp;HttpServletResponseCopier(javax.servlet.http.HttpServletResponse&nbsp;response)\n                          throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></pre>\n<dl>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"getOutputStream--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getOutputStream</h4>\n<pre>public&nbsp;javax.servlet.ServletOutputStream&nbsp;getOutputStream()\n                                                  throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>getOutputStream</code>&nbsp;在接口中&nbsp;<code>javax.servlet.ServletResponse</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>getOutputStream</code>&nbsp;在类中&nbsp;<code>javax.servlet.ServletResponseWrapper</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getWriter--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getWriter</h4>\n<pre>public&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html?is-external=true\" title=\"java.io中的类或接口\">PrintWriter</a>&nbsp;getWriter()\n                      throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>getWriter</code>&nbsp;在接口中&nbsp;<code>javax.servlet.ServletResponse</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>getWriter</code>&nbsp;在类中&nbsp;<code>javax.servlet.ServletResponseWrapper</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"flushBuffer--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>flushBuffer</h4>\n<pre>public&nbsp;void&nbsp;flushBuffer()\n                 throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>flushBuffer</code>&nbsp;在接口中&nbsp;<code>javax.servlet.ServletResponse</code></dd>\n<dt><span class=\"overrideSpecifyLabel\">覆盖:</span></dt>\n<dd><code>flushBuffer</code>&nbsp;在类中&nbsp;<code>javax.servlet.ServletResponseWrapper</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getCopy--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getCopy</h4>\n<pre>public&nbsp;byte[]&nbsp;getCopy()</pre>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/HttpServletResponseCopier.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/HttpServletResponseCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"HttpServletResponseCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/ReplaceCallBack.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>ReplaceCallBack (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"ReplaceCallBack (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":6};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],4:[\"t3\",\"抽象方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/ReplaceCallBack.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/ReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"接口 ReplaceCallBack\" class=\"title\">接口 ReplaceCallBack</h2>\n</div>\n<div class=\"contentContainer\">\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已知实现类:</dt>\n<dd><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public interface <span class=\"typeNameLabel\">ReplaceCallBack</span></pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">抽象方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">replace</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n       int&nbsp;index,\n       <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</code>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n</td>\n</tr>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"replace-java.lang.String-int-java.util.regex.Matcher-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>replace</h4>\n<pre><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;replace(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;text,\n               int&nbsp;index,\n               <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html?is-external=true\" title=\"java.util.regex中的类或接口\">Matcher</a>&nbsp;matcher)</pre>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>text</code> - 指定的字符串</dd>\n<dd><code>index</code> - 替换的次序</dd>\n<dd><code>matcher</code> - Matcher对象</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/ReplaceCallBack.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/ReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li>构造器&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/ServletOutputStreamCopier.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>ServletOutputStreamCopier (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"ServletOutputStreamCopier (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10,\"i3\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/ServletOutputStreamCopier.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/ServletOutputStreamCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ServletOutputStreamCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"类 ServletOutputStreamCopier\" class=\"title\">类 ServletOutputStreamCopier</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">java.lang.Object</a></li>\n<li>\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true\" title=\"java.io中的类或接口\">java.io.OutputStream</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>javax.servlet.ServletOutputStream</li>\n<li>\n<ul class=\"inheritance\">\n<li>com.github.tencent.ServletOutputStreamCopier</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html?is-external=true\" title=\"java.io中的类或接口\">Closeable</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Flushable.html?is-external=true\" title=\"java.io中的类或接口\">Flushable</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html?is-external=true\" title=\"java.lang中的类或接口\">AutoCloseable</a></dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">ServletOutputStreamCopier</span>\nextends javax.servlet.ServletOutputStream</pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html#ServletOutputStreamCopier--\">ServletOutputStreamCopier</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>byte[]</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html#getCopy--\">getCopy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>boolean</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html#isReady--\">isReady</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html#setWriteListener-javax.servlet.WriteListener-\">setWriteListener</a></span>(javax.servlet.WriteListener&nbsp;writeListener)</code>&nbsp;</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html#write-int-\">write</a></span>(int&nbsp;b)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.javax.servlet.ServletOutputStream\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;javax.servlet.ServletOutputStream</h3>\n<code>print, print, print, print, print, print, print, println, println, println, println, println, println, println, println</code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.io.OutputStream\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true\" title=\"java.io中的类或接口\">OutputStream</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true#close--\" title=\"java.io中的类或接口\">close</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true#flush--\" title=\"java.io中的类或接口\">flush</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true#write-byte:A-\" title=\"java.io中的类或接口\">write</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true#write-byte:A-int-int-\" title=\"java.io中的类或接口\">write</a></code></li>\n</ul>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#clone--\" title=\"java.lang中的类或接口\">clone</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-\" title=\"java.lang中的类或接口\">equals</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#finalize--\" title=\"java.lang中的类或接口\">finalize</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#getClass--\" title=\"java.lang中的类或接口\">getClass</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#hashCode--\" title=\"java.lang中的类或接口\">hashCode</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notify--\" title=\"java.lang中的类或接口\">notify</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notifyAll--\" title=\"java.lang中的类或接口\">notifyAll</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#toString--\" title=\"java.lang中的类或接口\">toString</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait--\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\" title=\"java.lang中的类或接口\">wait</a></code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"ServletOutputStreamCopier--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>ServletOutputStreamCopier</h4>\n<pre>public&nbsp;ServletOutputStreamCopier()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"write-int-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>write</h4>\n<pre>public&nbsp;void&nbsp;write(int&nbsp;b)\n           throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true#write-int-\" title=\"java.io中的类或接口\">write</a></code>&nbsp;在类中&nbsp;<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true\" title=\"java.io中的类或接口\">OutputStream</a></code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"getCopy--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>getCopy</h4>\n<pre>public&nbsp;byte[]&nbsp;getCopy()</pre>\n</li>\n</ul>\n<a name=\"isReady--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>isReady</h4>\n<pre>public&nbsp;boolean&nbsp;isReady()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>isReady</code>&nbsp;在类中&nbsp;<code>javax.servlet.ServletOutputStream</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"setWriteListener-javax.servlet.WriteListener-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>setWriteListener</h4>\n<pre>public&nbsp;void&nbsp;setWriteListener(javax.servlet.WriteListener&nbsp;writeListener)</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>setWriteListener</code>&nbsp;在类中&nbsp;<code>javax.servlet.ServletOutputStream</code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/ServletOutputStreamCopier.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/ServletOutputStreamCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ServletOutputStreamCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/SonicFilter.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>SonicFilter (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicFilter (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":10,\"i1\":10,\"i2\":10};\nvar tabs = {65535:[\"t0\",\"所有方法\"],2:[\"t2\",\"实例方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/SonicFilter.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/SonicFilter.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFilter.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"类 SonicFilter\" class=\"title\">类 SonicFilter</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">java.lang.Object</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.github.tencent.SonicFilter</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<dl>\n<dt>所有已实现的接口:</dt>\n<dd>javax.servlet.Filter</dd>\n</dl>\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicFilter</span>\nextends <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a>\nimplements javax.servlet.Filter</pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicFilter.html#SonicFilter--\">SonicFilter</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">实例方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicFilter.html#destroy--\">destroy</a></span>()</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicFilter.html#doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-\">doFilter</a></span>(javax.servlet.ServletRequest&nbsp;request,\n        javax.servlet.ServletResponse&nbsp;response,\n        javax.servlet.FilterChain&nbsp;chain)</code>&nbsp;</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>void</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicFilter.html#init-javax.servlet.FilterConfig-\">init</a></span>(javax.servlet.FilterConfig&nbsp;config)</code>&nbsp;</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#clone--\" title=\"java.lang中的类或接口\">clone</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-\" title=\"java.lang中的类或接口\">equals</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#finalize--\" title=\"java.lang中的类或接口\">finalize</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#getClass--\" title=\"java.lang中的类或接口\">getClass</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#hashCode--\" title=\"java.lang中的类或接口\">hashCode</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notify--\" title=\"java.lang中的类或接口\">notify</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notifyAll--\" title=\"java.lang中的类或接口\">notifyAll</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#toString--\" title=\"java.lang中的类或接口\">toString</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait--\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\" title=\"java.lang中的类或接口\">wait</a></code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicFilter--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicFilter</h4>\n<pre>public&nbsp;SonicFilter()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"destroy--\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>destroy</h4>\n<pre>public&nbsp;void&nbsp;destroy()</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>destroy</code>&nbsp;在接口中&nbsp;<code>javax.servlet.Filter</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>doFilter</h4>\n<pre>public&nbsp;void&nbsp;doFilter(javax.servlet.ServletRequest&nbsp;request,\n                     javax.servlet.ServletResponse&nbsp;response,\n                     javax.servlet.FilterChain&nbsp;chain)\n              throws <a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a>,\n                     javax.servlet.ServletException</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>doFilter</code>&nbsp;在接口中&nbsp;<code>javax.servlet.Filter</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html?is-external=true\" title=\"java.io中的类或接口\">IOException</a></code></dd>\n<dd><code>javax.servlet.ServletException</code></dd>\n</dl>\n</li>\n</ul>\n<a name=\"init-javax.servlet.FilterConfig-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>init</h4>\n<pre>public&nbsp;void&nbsp;init(javax.servlet.FilterConfig&nbsp;config)\n          throws javax.servlet.ServletException</pre>\n<dl>\n<dt><span class=\"overrideSpecifyLabel\">指定者:</span></dt>\n<dd><code>init</code>&nbsp;在接口中&nbsp;<code>javax.servlet.Filter</code></dd>\n<dt><span class=\"throwsLabel\">抛出:</span></dt>\n<dd><code>javax.servlet.ServletException</code></dd>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/SonicFilter.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li><a href=\"../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">下一个类</span></a></li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/SonicFilter.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFilter.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/SonicUtil.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>SonicUtil (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"SonicUtil (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\nvar methods = {\"i0\":9,\"i1\":9,\"i2\":9,\"i3\":9,\"i4\":9};\nvar tabs = {65535:[\"t0\",\"所有方法\"],1:[\"t1\",\"静态方法\"],8:[\"t4\",\"具体方法\"]};\nvar altColor = \"altColor\";\nvar rowColor = \"rowColor\";\nvar tableTab = \"tableTab\";\nvar activeTableTab = \"activeTableTab\";\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/SonicUtil.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/SonicUtil.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtil.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<!-- ======== START OF CLASS DATA ======== -->\n<div class=\"header\">\n<div class=\"subTitle\">com.github.tencent</div>\n<h2 title=\"类 SonicUtil\" class=\"title\">类 SonicUtil</h2>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"inheritance\">\n<li><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">java.lang.Object</a></li>\n<li>\n<ul class=\"inheritance\">\n<li>com.github.tencent.SonicUtil</li>\n</ul>\n</li>\n</ul>\n<div class=\"description\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<hr>\n<br>\n<pre>public class <span class=\"typeNameLabel\">SonicUtil</span>\nextends <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></pre>\n</li>\n</ul>\n</div>\n<div class=\"summary\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ======== CONSTRUCTOR SUMMARY ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.summary\">\n<!--   -->\n</a>\n<h3>构造器概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"构造器概要表, 列表构造器和解释\">\n<caption><span>构造器</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">构造器和说明</th>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colOne\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#SonicUtil--\">SonicUtil</a></span>()</code>&nbsp;</td>\n</tr>\n</table>\n</li>\n</ul>\n<!-- ========== METHOD SUMMARY =========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.summary\">\n<!--   -->\n</a>\n<h3>方法概要</h3>\n<table class=\"memberSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"方法概要表, 列表方法和解释\">\n<caption><span id=\"t0\" class=\"activeTableTab\"><span>所有方法</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">静态方法</a></span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">具体方法</a></span><span class=\"tabEnd\">&nbsp;</span></span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tr id=\"i0\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#encrypt-java.lang.String-java.lang.String-\">encrypt</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;inputText,\n       <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;algorithmName)</code>&nbsp;</td>\n</tr>\n<tr id=\"i1\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/Map.html?is-external=true\" title=\"java.util中的类或接口\">Map</a>&lt;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>,<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&gt;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#getAllHttpHeaders-javax.servlet.http.HttpServletRequest-\">getAllHttpHeaders</a></span>(javax.servlet.http.HttpServletRequest&nbsp;httpRequest)</code>\n<div class=\"block\">获取HTTP所有的请求头</div>\n</td>\n</tr>\n<tr id=\"i2\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#hex-byte:A-\">hex</a></span>(byte[]&nbsp;arr)</code>\n<div class=\"block\">返回十六进制字符串</div>\n</td>\n</tr>\n<tr id=\"i3\" class=\"rowColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#pregMatch-java.lang.String-java.lang.String-\">pregMatch</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;strContent,\n         <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;strPattern)</code>&nbsp;</td>\n</tr>\n<tr id=\"i4\" class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../com/github/tencent/SonicUtil.html#replaceAllCallBack-java.lang.String-java.util.regex.Pattern-com.github.tencent.ReplaceCallBack-\">replaceAllCallBack</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;string,\n                  <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html?is-external=true\" title=\"java.util.regex中的类或接口\">Pattern</a>&nbsp;pattern,\n                  <a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>&nbsp;replacement)</code>\n<div class=\"block\">将String中的所有pattern匹配的字符串替换掉</div>\n</td>\n</tr>\n</table>\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"methods.inherited.from.class.java.lang.Object\">\n<!--   -->\n</a>\n<h3>从类继承的方法&nbsp;java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\">Object</a></h3>\n<code><a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#clone--\" title=\"java.lang中的类或接口\">clone</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-\" title=\"java.lang中的类或接口\">equals</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#finalize--\" title=\"java.lang中的类或接口\">finalize</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#getClass--\" title=\"java.lang中的类或接口\">getClass</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#hashCode--\" title=\"java.lang中的类或接口\">hashCode</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notify--\" title=\"java.lang中的类或接口\">notify</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#notifyAll--\" title=\"java.lang中的类或接口\">notifyAll</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#toString--\" title=\"java.lang中的类或接口\">toString</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait--\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-\" title=\"java.lang中的类或接口\">wait</a>, <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\" title=\"java.lang中的类或接口\">wait</a></code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<div class=\"details\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<!-- ========= CONSTRUCTOR DETAIL ======== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"constructor.detail\">\n<!--   -->\n</a>\n<h3>构造器详细资料</h3>\n<a name=\"SonicUtil--\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>SonicUtil</h4>\n<pre>public&nbsp;SonicUtil()</pre>\n</li>\n</ul>\n</li>\n</ul>\n<!-- ============ METHOD DETAIL ========== -->\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"method.detail\">\n<!--   -->\n</a>\n<h3>方法详细资料</h3>\n<a name=\"hex-byte:A-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>hex</h4>\n<pre>public static&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;hex(byte[]&nbsp;arr)</pre>\n<div class=\"block\">返回十六进制字符串</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>arr</code> - </dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n<a name=\"encrypt-java.lang.String-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>encrypt</h4>\n<pre>public static&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;encrypt(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;inputText,\n                             <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;algorithmName)</pre>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>inputText</code> - </dd>\n<dd><code>algorithmName</code> - </dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n<a name=\"replaceAllCallBack-java.lang.String-java.util.regex.Pattern-com.github.tencent.ReplaceCallBack-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>replaceAllCallBack</h4>\n<pre>public static&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;replaceAllCallBack(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;string,\n                                        <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html?is-external=true\" title=\"java.util.regex中的类或接口\">Pattern</a>&nbsp;pattern,\n                                        <a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>&nbsp;replacement)</pre>\n<div class=\"block\">将String中的所有pattern匹配的字符串替换掉</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>string</code> - 待替换的字符串</dd>\n<dd><code>pattern</code> - 替换查找的正则表达式对象</dd>\n<dd><code>replacement</code> - 替换函数</dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n<a name=\"pregMatch-java.lang.String-java.lang.String-\">\n<!--   -->\n</a>\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h4>pregMatch</h4>\n<pre>public static&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;pregMatch(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;strContent,\n                               <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;strPattern)</pre>\n</li>\n</ul>\n<a name=\"getAllHttpHeaders-javax.servlet.http.HttpServletRequest-\">\n<!--   -->\n</a>\n<ul class=\"blockListLast\">\n<li class=\"blockList\">\n<h4>getAllHttpHeaders</h4>\n<pre>public static&nbsp;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/Map.html?is-external=true\" title=\"java.util中的类或接口\">Map</a>&lt;<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>,<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&gt;&nbsp;getAllHttpHeaders(javax.servlet.http.HttpServletRequest&nbsp;httpRequest)</pre>\n<div class=\"block\">获取HTTP所有的请求头</div>\n<dl>\n<dt><span class=\"paramLabel\">参数:</span></dt>\n<dd><code>httpRequest</code> - </dd>\n<dt><span class=\"returnLabel\">返回:</span></dt>\n</dl>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n</div>\n<!-- ========= END OF CLASS DATA ========= -->\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li class=\"navBarCell1Rev\">类</li>\n<li><a href=\"class-use/SonicUtil.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li><a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">上一个类</span></a></li>\n<li>下一个类</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/SonicUtil.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtil.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<div>\n<ul class=\"subNavList\">\n<li>概要:&nbsp;</li>\n<li>嵌套&nbsp;|&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.summary\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.summary\">方法</a></li>\n</ul>\n<ul class=\"subNavList\">\n<li>详细资料:&nbsp;</li>\n<li>字段&nbsp;|&nbsp;</li>\n<li><a href=\"#constructor.detail\">构造器</a>&nbsp;|&nbsp;</li>\n<li><a href=\"#method.detail\">方法</a></li>\n</ul>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/AbstractReplaceCallBack.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类 com.github.tencent.AbstractReplaceCallBack的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B com.github.tencent.AbstractReplaceCallBack\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/AbstractReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"AbstractReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"类的使用 com.github.tencent.AbstractReplaceCallBack\" class=\"title\">类的使用<br>com.github.tencent.AbstractReplaceCallBack</h2>\n</div>\n<div class=\"classUseContainer\">没有com.github.tencent.AbstractReplaceCallBack的用法</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/AbstractReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"AbstractReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/HttpServletResponseCopier.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类 com.github.tencent.HttpServletResponseCopier的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B com.github.tencent.HttpServletResponseCopier\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/HttpServletResponseCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"HttpServletResponseCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"类的使用 com.github.tencent.HttpServletResponseCopier\" class=\"title\">类的使用<br>com.github.tencent.HttpServletResponseCopier</h2>\n</div>\n<div class=\"classUseContainer\">没有com.github.tencent.HttpServletResponseCopier的用法</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/HttpServletResponseCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"HttpServletResponseCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/ReplaceCallBack.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>接口 com.github.tencent.ReplaceCallBack的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u63A5\\u53E3 com.github.tencent.ReplaceCallBack\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/ReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"接口的使用 com.github.tencent.ReplaceCallBack\" class=\"title\">接口的使用<br>com.github.tencent.ReplaceCallBack</h2>\n</div>\n<div class=\"classUseContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"com.github.tencent\">\n<!--   -->\n</a>\n<h3><a href=\"../../../../com/github/tencent/package-summary.html\">com.github.tencent</a>中<a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>的使用</h3>\n<table class=\"useSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"使用表, 列表类和解释\">\n<caption><span>实现<a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>的<a href=\"../../../../com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">类和说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>class&nbsp;</code></td>\n<td class=\"colLast\"><code><span class=\"memberNameLink\"><a href=\"../../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></span></code>&nbsp;</td>\n</tr>\n</tbody>\n</table>\n<table class=\"useSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"使用表, 列表方法和解释\">\n<caption><span>参数类型为<a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>的<a href=\"../../../../com/github/tencent/package-summary.html\">com.github.tencent</a>中的方法</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">限定符和类型</th>\n<th class=\"colLast\" scope=\"col\">方法和说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><code>static <a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a></code></td>\n<td class=\"colLast\"><span class=\"typeNameLabel\">SonicUtil.</span><code><span class=\"memberNameLink\"><a href=\"../../../../com/github/tencent/SonicUtil.html#replaceAllCallBack-java.lang.String-java.util.regex.Pattern-com.github.tencent.ReplaceCallBack-\">replaceAllCallBack</a></span>(<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/String.html?is-external=true\" title=\"java.lang中的类或接口\">String</a>&nbsp;string,\n                  <a href=\"http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html?is-external=true\" title=\"java.util.regex中的类或接口\">Pattern</a>&nbsp;pattern,\n                  <a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>&nbsp;replacement)</code>\n<div class=\"block\">将String中的所有pattern匹配的字符串替换掉</div>\n</td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/ReplaceCallBack.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ReplaceCallBack.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/ServletOutputStreamCopier.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类 com.github.tencent.ServletOutputStreamCopier的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B com.github.tencent.ServletOutputStreamCopier\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/ServletOutputStreamCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ServletOutputStreamCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"类的使用 com.github.tencent.ServletOutputStreamCopier\" class=\"title\">类的使用<br>com.github.tencent.ServletOutputStreamCopier</h2>\n</div>\n<div class=\"classUseContainer\">没有com.github.tencent.ServletOutputStreamCopier的用法</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/ServletOutputStreamCopier.html\" target=\"_top\">框架</a></li>\n<li><a href=\"ServletOutputStreamCopier.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/SonicFilter.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类 com.github.tencent.SonicFilter的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B com.github.tencent.SonicFilter\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/SonicFilter.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFilter.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"类的使用 com.github.tencent.SonicFilter\" class=\"title\">类的使用<br>com.github.tencent.SonicFilter</h2>\n</div>\n<div class=\"classUseContainer\">没有com.github.tencent.SonicFilter的用法</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/SonicFilter.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicFilter.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/class-use/SonicUtil.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类 com.github.tencent.SonicUtil的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B com.github.tencent.SonicUtil\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/SonicUtil.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtil.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h2 title=\"类的使用 com.github.tencent.SonicUtil\" class=\"title\">类的使用<br>com.github.tencent.SonicUtil</h2>\n</div>\n<div class=\"classUseContainer\">没有com.github.tencent.SonicUtil的用法</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li><a href=\"../../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">类</a></li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"../package-tree.html\">树</a></li>\n<li><a href=\"../../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../../index.html?com/github/tencent/class-use/SonicUtil.html\" target=\"_top\">框架</a></li>\n<li><a href=\"SonicUtil.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/package-frame.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>com.github.tencent (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<h1 class=\"bar\"><a href=\"../../../com/github/tencent/package-summary.html\" target=\"classFrame\">com.github.tencent</a></h1>\n<div class=\"indexContainer\">\n<h2 title=\"接口\">接口</h2>\n<ul title=\"接口\">\n<li><a href=\"ReplaceCallBack.html\" title=\"com.github.tencent中的接口\" target=\"classFrame\"><span class=\"interfaceName\">ReplaceCallBack</span></a></li>\n</ul>\n<h2 title=\"类\">类</h2>\n<ul title=\"类\">\n<li><a href=\"AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">AbstractReplaceCallBack</a></li>\n<li><a href=\"HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">HttpServletResponseCopier</a></li>\n<li><a href=\"ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">ServletOutputStreamCopier</a></li>\n<li><a href=\"SonicFilter.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">SonicFilter</a></li>\n<li><a href=\"SonicUtil.html\" title=\"com.github.tencent中的类\" target=\"classFrame\">SonicUtil</a></li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/package-summary.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>com.github.tencent (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.github.tencent (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li><a href=\"package-use.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个程序包</li>\n<li>下一个程序包</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"程序包\" class=\"title\">程序包&nbsp;com.github.tencent</h1>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"接口概要表, 列表接口和解释\">\n<caption><span>接口概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">接口</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n</tbody>\n</table>\n</li>\n<li class=\"blockList\">\n<table class=\"typeSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"类概要表, 列表类和解释\">\n<caption><span>类概要</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colFirst\" scope=\"col\">类</th>\n<th class=\"colLast\" scope=\"col\">说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"rowColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n<tr class=\"altColor\">\n<td class=\"colFirst\"><a href=\"../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></td>\n<td class=\"colLast\">&nbsp;</td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li><a href=\"package-use.html\">使用</a></li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个程序包</li>\n<li>下一个程序包</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-summary.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-summary.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/package-tree.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>com.github.tencent 类分层结构 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"com.github.tencent \\u7C7B\\u5206\\u5C42\\u7ED3\\u6784 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">程序包com.github.tencent的分层结构</h1>\n</div>\n<div class=\"contentContainer\">\n<h2 title=\"类分层结构\">类分层结构</h2>\n<ul>\n<li type=\"circle\">java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\"><span class=\"typeNameLink\">Object</span></a>\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">AbstractReplaceCallBack</span></a> (implements com.github.tencent.<a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>)</li>\n<li type=\"circle\">java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true\" title=\"java.io中的类或接口\"><span class=\"typeNameLink\">OutputStream</span></a> (implements java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html?is-external=true\" title=\"java.io中的类或接口\">Closeable</a>, java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Flushable.html?is-external=true\" title=\"java.io中的类或接口\">Flushable</a>)\n<ul>\n<li type=\"circle\">javax.servlet.ServletOutputStream\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">ServletOutputStreamCopier</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li type=\"circle\">javax.servlet.ServletResponseWrapper (implements javax.servlet.ServletResponse)\n<ul>\n<li type=\"circle\">javax.servlet.http.HttpServletResponseWrapper (implements javax.servlet.http.HttpServletResponse)\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">HttpServletResponseCopier</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicFilter</span></a> (implements javax.servlet.Filter)</li>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicUtil</span></a></li>\n</ul>\n</li>\n</ul>\n<h2 title=\"接口分层结构\">接口分层结构</h2>\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"../../../com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">ReplaceCallBack</span></a></li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/com/github/tencent/package-use.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>程序包 com.github.tencent的使用 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"../../../script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7A0B\\u5E8F\\u5305 com.github.tencent\\u7684\\u4F7F\\u7528 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-use.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-use.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"程序包的使用 com.github.tencent\" class=\"title\">程序包的使用<br>com.github.tencent</h1>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\"><a name=\"com.github.tencent\">\n<!--   -->\n</a>\n<table class=\"useSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" summary=\"使用表, 列表类和解释\">\n<caption><span><a href=\"../../../com/github/tencent/package-summary.html\">com.github.tencent</a>使用的<a href=\"../../../com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</span><span class=\"tabEnd\">&nbsp;</span></caption>\n<tr>\n<th class=\"colOne\" scope=\"col\">类和说明</th>\n</tr>\n<tbody>\n<tr class=\"altColor\">\n<td class=\"colOne\"><a href=\"../../../com/github/tencent/class-use/ReplaceCallBack.html#com.github.tencent\">ReplaceCallBack</a>&nbsp;</td>\n</tr>\n</tbody>\n</table>\n</li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"../../../com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li class=\"navBarCell1Rev\">使用</li>\n<li><a href=\"package-tree.html\">树</a></li>\n<li><a href=\"../../../deprecated-list.html\">已过时</a></li>\n<li><a href=\"../../../index-all.html\">索引</a></li>\n<li><a href=\"../../../help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"../../../index.html?com/github/tencent/package-use.html\" target=\"_top\">框架</a></li>\n<li><a href=\"package-use.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"../../../allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/constant-values.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>常量字段值 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u5E38\\u91CF\\u5B57\\u6BB5\\u503C (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?constant-values.html\" target=\"_top\">框架</a></li>\n<li><a href=\"constant-values.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"常量字段值\" class=\"title\">常量字段值</h1>\n<h2 title=\"目录\">目录</h2>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?constant-values.html\" target=\"_top\">框架</a></li>\n<li><a href=\"constant-values.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/deprecated-list.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>已过时的列表 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u5DF2\\u8FC7\\u65F6\\u7684\\u5217\\u8868 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li class=\"navBarCell1Rev\">已过时</li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?deprecated-list.html\" target=\"_top\">框架</a></li>\n<li><a href=\"deprecated-list.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 title=\"已过时的 API\" class=\"title\">已过时的 API</h1>\n<h2 title=\"目录\">目录</h2>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li class=\"navBarCell1Rev\">已过时</li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?deprecated-list.html\" target=\"_top\">框架</a></li>\n<li><a href=\"deprecated-list.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/help-doc.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>API 帮助 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"API \\u5E2E\\u52A9 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li class=\"navBarCell1Rev\">帮助</li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?help-doc.html\" target=\"_top\">框架</a></li>\n<li><a href=\"help-doc.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">此 API 文档的组织方式</h1>\n<div class=\"subTitle\">此 API (应用程序编程接口) 文档包含对应于导航栏中的项目的页面, 如下所述。</div>\n</div>\n<div class=\"contentContainer\">\n<ul class=\"blockList\">\n<li class=\"blockList\">\n<h2>程序包</h2>\n<p>每个程序包都有一个页面, 其中包含它的类和接口的列表及其概要。此页面可以包含六个类别:</p>\n<ul>\n<li>接口 (斜体)</li>\n<li>类</li>\n<li>枚举</li>\n<li>异常错误</li>\n<li>错误</li>\n<li>注释类型</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>类/接口</h2>\n<p>每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:</p>\n<ul>\n<li>类继承图</li>\n<li>直接子类</li>\n<li>所有已知子接口</li>\n<li>所有已知实现类</li>\n<li>类/接口声明</li>\n<li>类/接口说明</li>\n</ul>\n<ul>\n<li>嵌套类概要</li>\n<li>字段概要</li>\n<li>构造器概要</li>\n<li>方法概要</li>\n</ul>\n<ul>\n<li>字段详细资料</li>\n<li>构造器详细资料</li>\n<li>方法详细资料</li>\n</ul>\n<p>每个概要条目都包含该项目的详细说明的第一句。概要条目按字母顺序排列, 而详细说明则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。</p>\n</li>\n<li class=\"blockList\">\n<h2>注释类型</h2>\n<p>每个注释类型都有各自的页面, 其中包含以下部分:</p>\n<ul>\n<li>注释类型声明</li>\n<li>注释类型说明</li>\n<li>必需元素概要</li>\n<li>可选元素概要</li>\n<li>元素详细资料</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>枚举</h2>\n<p>每个枚举都有各自的页面, 其中包含以下部分:</p>\n<ul>\n<li>枚举声明</li>\n<li>枚举说明</li>\n<li>枚举常量概要</li>\n<li>枚举常量详细资料</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>使用</h2>\n<p>每个已文档化的程序包, 类和接口都有各自的“使用”页面。此页面介绍了使用给定类或程序包的任何部分的程序包, 类, 方法, 构造器和字段。对于给定的类或接口 A, 其“使用”页面包含 A 的子类, 声明为 A 的字段, 返回 A 的方法, 以及带有类型为 A 的参数的方法和构造器。访问此页面的方法是: 首先转至程序包, 类或接口, 然后单击导航栏中的 \"使用\" 链接。</p>\n</li>\n<li class=\"blockList\">\n<h2>树 (类分层结构)</h2>\n<p>对于所有程序包, 有一个<a href=\"overview-tree.html\">类分层结构</a>页面, 以及每个程序包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从<code>java.lang.Object</code>开始, 按继承结构对类进行排列。接口不从<code>java.lang.Object</code>继承。</p>\n<ul>\n<li>查看“概览”页面时, 单击 \"树\" 将显示所有程序包的分层结构。</li>\n<li>查看特定程序包, 类或接口页面时, 单击 \"树\" 将仅显示该程序包的分层结构。</li>\n</ul>\n</li>\n<li class=\"blockList\">\n<h2>已过时的 API</h2>\n<p><a href=\"deprecated-list.html\">已过时的 API</a> 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API, 所以建议不要使用已过时的 API。在将来的实现过程中, 可能会删除已过时的 API。</p>\n</li>\n<li class=\"blockList\">\n<h2>索引</h2>\n<p><a href=\"index-all.html\">索引</a> 包含按字母顺序排列的所有类, 接口, 构造器, 方法和字段的列表。</p>\n</li>\n<li class=\"blockList\">\n<h2>上一个/下一个</h2>\n<p>这些链接使您可以转至下一个或上一个类, 接口, 程序包或相关页面。</p>\n</li>\n<li class=\"blockList\">\n<h2>框架/无框架</h2>\n<p>这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。</p>\n</li>\n<li class=\"blockList\">\n<h2>所有类</h2>\n<p><a href=\"allclasses-noframe.html\">所有类</a>链接显示所有类和接口 (除了非静态嵌套类型)。</p>\n</li>\n<li class=\"blockList\">\n<h2>序列化表格</h2>\n<p>每个可序列化或可外部化的类都有其序列化字段和方法的说明。此信息对重新实现者有用, 而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接, 但您可以通过下列方式获取此信息: 转至任何序列化类, 然后单击类说明的 \"另请参阅\" 部分中的 \"序列化表格\"。</p>\n</li>\n<li class=\"blockList\">\n<h2>常量字段值</h2>\n<p><a href=\"constant-values.html\">常量字段值</a>页面列出了静态最终字段及其值。</p>\n</li>\n</ul>\n<span class=\"emphasizedPhrase\">此帮助文件适用于使用标准 doclet 生成的 API 文档。</span></div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li class=\"navBarCell1Rev\">帮助</li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?help-doc.html\" target=\"_top\">框架</a></li>\n<li><a href=\"help-doc.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/index-all.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>索引 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7D22\\u5F15 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li class=\"navBarCell1Rev\">索引</li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?index-all.html\" target=\"_top\">框架</a></li>\n<li><a href=\"index-all.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"contentContainer\"><a href=\"#I:A\">A</a>&nbsp;<a href=\"#I:C\">C</a>&nbsp;<a href=\"#I:D\">D</a>&nbsp;<a href=\"#I:E\">E</a>&nbsp;<a href=\"#I:F\">F</a>&nbsp;<a href=\"#I:G\">G</a>&nbsp;<a href=\"#I:H\">H</a>&nbsp;<a href=\"#I:I\">I</a>&nbsp;<a href=\"#I:M\">M</a>&nbsp;<a href=\"#I:P\">P</a>&nbsp;<a href=\"#I:R\">R</a>&nbsp;<a href=\"#I:S\">S</a>&nbsp;<a href=\"#I:W\">W</a>&nbsp;<a name=\"I:A\">\n<!--   -->\n</a>\n<h2 class=\"title\">A</h2>\n<dl>\n<dt><a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">AbstractReplaceCallBack</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/AbstractReplaceCallBack.html#AbstractReplaceCallBack--\">AbstractReplaceCallBack()</a></span> - 类 的构造器com.github.tencent.<a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:C\">\n<!--   -->\n</a>\n<h2 class=\"title\">C</h2>\n<dl>\n<dt><a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a> - 程序包 com.github.tencent</dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:D\">\n<!--   -->\n</a>\n<h2 class=\"title\">D</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicFilter.html#destroy--\">destroy()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicFilter.html#doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-\">doFilter(ServletRequest, ServletResponse, FilterChain)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/AbstractReplaceCallBack.html#doReplace-java.lang.String-int-java.util.regex.Matcher-\">doReplace(String, int, Matcher)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></dt>\n<dd>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n</dd>\n</dl>\n<a name=\"I:E\">\n<!--   -->\n</a>\n<h2 class=\"title\">E</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#encrypt-java.lang.String-java.lang.String-\">encrypt(String, String)</a></span> - 类 中的静态方法com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:F\">\n<!--   -->\n</a>\n<h2 class=\"title\">F</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/HttpServletResponseCopier.html#flushBuffer--\">flushBuffer()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:G\">\n<!--   -->\n</a>\n<h2 class=\"title\">G</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#getAllHttpHeaders-javax.servlet.http.HttpServletRequest-\">getAllHttpHeaders(HttpServletRequest)</a></span> - 类 中的静态方法com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>\n<div class=\"block\">获取HTTP所有的请求头</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/HttpServletResponseCopier.html#getCopy--\">getCopy()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ServletOutputStreamCopier.html#getCopy--\">getCopy()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/HttpServletResponseCopier.html#getOutputStream--\">getOutputStream()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/HttpServletResponseCopier.html#getWriter--\">getWriter()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:H\">\n<!--   -->\n</a>\n<h2 class=\"title\">H</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#hex-byte:A-\">hex(byte[])</a></span> - 类 中的静态方法com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>\n<div class=\"block\">返回十六进制字符串</div>\n</dd>\n<dt><a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">HttpServletResponseCopier</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/HttpServletResponseCopier.html#HttpServletResponseCopier-javax.servlet.http.HttpServletResponse-\">HttpServletResponseCopier(HttpServletResponse)</a></span> - 类 的构造器com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\">HttpServletResponseCopier</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:I\">\n<!--   -->\n</a>\n<h2 class=\"title\">I</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicFilter.html#init-javax.servlet.FilterConfig-\">init(FilterConfig)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ServletOutputStreamCopier.html#isReady--\">isReady()</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:M\">\n<!--   -->\n</a>\n<h2 class=\"title\">M</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/AbstractReplaceCallBack.html#matcher\">matcher</a></span> - 类 中的变量com.github.tencent.<a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:P\">\n<!--   -->\n</a>\n<h2 class=\"title\">P</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#pregMatch-java.lang.String-java.lang.String-\">pregMatch(String, String)</a></span> - 类 中的静态方法com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:R\">\n<!--   -->\n</a>\n<h2 class=\"title\">R</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/AbstractReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">replace(String, int, Matcher)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\">AbstractReplaceCallBack</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ReplaceCallBack.html#replace-java.lang.String-int-java.util.regex.Matcher-\">replace(String, int, Matcher)</a></span> - 接口 中的方法com.github.tencent.<a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a></dt>\n<dd>\n<div class=\"block\">将text转化为特定的字符串返回</div>\n</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#replaceAllCallBack-java.lang.String-java.util.regex.Pattern-com.github.tencent.ReplaceCallBack-\">replaceAllCallBack(String, Pattern, ReplaceCallBack)</a></span> - 类 中的静态方法com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>\n<div class=\"block\">将String中的所有pattern匹配的字符串替换掉</div>\n</dd>\n<dt><a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">ReplaceCallBack</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的接口</dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:S\">\n<!--   -->\n</a>\n<h2 class=\"title\">S</h2>\n<dl>\n<dt><a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">ServletOutputStreamCopier</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ServletOutputStreamCopier.html#ServletOutputStreamCopier--\">ServletOutputStreamCopier()</a></span> - 类 的构造器com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ServletOutputStreamCopier.html#setWriteListener-javax.servlet.WriteListener-\">setWriteListener(WriteListener)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicFilter</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicFilter.html#SonicFilter--\">SonicFilter()</a></span> - 类 的构造器com.github.tencent.<a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\">SonicFilter</a></dt>\n<dd>&nbsp;</dd>\n<dt><a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicUtil</span></a> - <a href=\"com/github/tencent/package-summary.html\">com.github.tencent</a>中的类</dt>\n<dd>&nbsp;</dd>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/SonicUtil.html#SonicUtil--\">SonicUtil()</a></span> - 类 的构造器com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\">SonicUtil</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a name=\"I:W\">\n<!--   -->\n</a>\n<h2 class=\"title\">W</h2>\n<dl>\n<dt><span class=\"memberNameLink\"><a href=\"com/github/tencent/ServletOutputStreamCopier.html#write-int-\">write(int)</a></span> - 类 中的方法com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\">ServletOutputStreamCopier</a></dt>\n<dd>&nbsp;</dd>\n</dl>\n<a href=\"#I:A\">A</a>&nbsp;<a href=\"#I:C\">C</a>&nbsp;<a href=\"#I:D\">D</a>&nbsp;<a href=\"#I:E\">E</a>&nbsp;<a href=\"#I:F\">F</a>&nbsp;<a href=\"#I:G\">G</a>&nbsp;<a href=\"#I:H\">H</a>&nbsp;<a href=\"#I:I\">I</a>&nbsp;<a href=\"#I:M\">M</a>&nbsp;<a href=\"#I:P\">P</a>&nbsp;<a href=\"#I:R\">R</a>&nbsp;<a href=\"#I:S\">S</a>&nbsp;<a href=\"#I:W\">W</a>&nbsp;</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li><a href=\"com/github/tencent/package-tree.html\">树</a></li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li class=\"navBarCell1Rev\">索引</li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?index-all.html\" target=\"_top\">框架</a></li>\n<li><a href=\"index-all.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/index.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>com.github.tencent:VasSonic 1.1 API</title>\n<script type=\"text/javascript\">\n    tmpTargetPage = \"\" + window.location.search;\n    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n        tmpTargetPage = tmpTargetPage.substring(1);\n    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n        tmpTargetPage = \"undefined\";\n    targetPage = tmpTargetPage;\n    function validURL(url) {\n        try {\n            url = decodeURIComponent(url);\n        }\n        catch (error) {\n            return false;\n        }\n        var pos = url.indexOf(\".html\");\n        if (pos == -1 || pos != url.length - 5)\n            return false;\n        var allowNumber = false;\n        var allowSep = false;\n        var seenDot = false;\n        for (var i = 0; i < url.length - 5; i++) {\n            var ch = url.charAt(i);\n            if ('a' <= ch && ch <= 'z' ||\n                    'A' <= ch && ch <= 'Z' ||\n                    ch == '$' ||\n                    ch == '_' ||\n                    ch.charCodeAt(0) > 127) {\n                allowNumber = true;\n                allowSep = true;\n            } else if ('0' <= ch && ch <= '9'\n                    || ch == '-') {\n                if (!allowNumber)\n                     return false;\n            } else if (ch == '/' || ch == '.') {\n                if (!allowSep)\n                    return false;\n                allowNumber = false;\n                allowSep = false;\n                if (ch == '.')\n                     seenDot = true;\n                if (ch == '/' && seenDot)\n                     return false;\n            } else {\n                return false;\n            }\n        }\n        return true;\n    }\n    function loadFrames() {\n        if (targetPage != \"\" && targetPage != \"undefined\")\n             top.classFrame.location = top.targetPage;\n    }\n</script>\n</head>\n<frameset cols=\"20%,80%\" title=\"Documentation frame\" onload=\"top.loadFrames()\">\n<frame src=\"allclasses-frame.html\" name=\"packageFrame\" title=\"所有类和接口 (除了非静态嵌套类型)\">\n<frame src=\"com/github/tencent/package-summary.html\" name=\"classFrame\" title=\"程序包, 类和接口说明\" scrolling=\"yes\">\n<noframes>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<h2>框架预警</h2>\n<p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href=\"com/github/tencent/package-summary.html\">非框架版本</a>。</p>\n</noframes>\n</frameset>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/overview-tree.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<!-- NewPage -->\n<html lang=\"zh\">\n<head>\n<!-- Generated by javadoc (1.8.0_161) on Sun Mar 25 14:01:27 CST 2018 -->\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>类分层结构 (com.github.tencent:VasSonic 1.1 API)</title>\n<meta name=\"date\" content=\"2018-03-25\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">\n<script type=\"text/javascript\" src=\"script.js\"></script>\n</head>\n<body>\n<script type=\"text/javascript\"><!--\n    try {\n        if (location.href.indexOf('is-external=true') == -1) {\n            parent.document.title=\"\\u7C7B\\u5206\\u5C42\\u7ED3\\u6784 (com.github.tencent:VasSonic 1.1 API)\";\n        }\n    }\n    catch(err) {\n    }\n//-->\n</script>\n<noscript>\n<div>您的浏览器已禁用 JavaScript。</div>\n</noscript>\n<!-- ========= START OF TOP NAVBAR ======= -->\n<div class=\"topNav\"><a name=\"navbar.top\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.top\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.top.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_top\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_top\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.top\">\n<!--   -->\n</a></div>\n<!-- ========= END OF TOP NAVBAR ========= -->\n<div class=\"header\">\n<h1 class=\"title\">所有程序包的分层结构</h1>\n<span class=\"packageHierarchyLabel\">程序包分层结构:</span>\n<ul class=\"horizontal\">\n<li><a href=\"com/github/tencent/package-tree.html\">com.github.tencent</a></li>\n</ul>\n</div>\n<div class=\"contentContainer\">\n<h2 title=\"类分层结构\">类分层结构</h2>\n<ul>\n<li type=\"circle\">java.lang.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html?is-external=true\" title=\"java.lang中的类或接口\"><span class=\"typeNameLink\">Object</span></a>\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/AbstractReplaceCallBack.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">AbstractReplaceCallBack</span></a> (implements com.github.tencent.<a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\">ReplaceCallBack</a>)</li>\n<li type=\"circle\">java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html?is-external=true\" title=\"java.io中的类或接口\"><span class=\"typeNameLink\">OutputStream</span></a> (implements java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html?is-external=true\" title=\"java.io中的类或接口\">Closeable</a>, java.io.<a href=\"http://docs.oracle.com/javase/7/docs/api/java/io/Flushable.html?is-external=true\" title=\"java.io中的类或接口\">Flushable</a>)\n<ul>\n<li type=\"circle\">javax.servlet.ServletOutputStream\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/ServletOutputStreamCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">ServletOutputStreamCopier</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li type=\"circle\">javax.servlet.ServletResponseWrapper (implements javax.servlet.ServletResponse)\n<ul>\n<li type=\"circle\">javax.servlet.http.HttpServletResponseWrapper (implements javax.servlet.http.HttpServletResponse)\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/HttpServletResponseCopier.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">HttpServletResponseCopier</span></a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/SonicFilter.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicFilter</span></a> (implements javax.servlet.Filter)</li>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/SonicUtil.html\" title=\"com.github.tencent中的类\"><span class=\"typeNameLink\">SonicUtil</span></a></li>\n</ul>\n</li>\n</ul>\n<h2 title=\"接口分层结构\">接口分层结构</h2>\n<ul>\n<li type=\"circle\">com.github.tencent.<a href=\"com/github/tencent/ReplaceCallBack.html\" title=\"com.github.tencent中的接口\"><span class=\"typeNameLink\">ReplaceCallBack</span></a></li>\n</ul>\n</div>\n<!-- ======= START OF BOTTOM NAVBAR ====== -->\n<div class=\"bottomNav\"><a name=\"navbar.bottom\">\n<!--   -->\n</a>\n<div class=\"skipNav\"><a href=\"#skip.navbar.bottom\" title=\"跳过导航链接\">跳过导航链接</a></div>\n<a name=\"navbar.bottom.firstrow\">\n<!--   -->\n</a>\n<ul class=\"navList\" title=\"导航\">\n<li><a href=\"com/github/tencent/package-summary.html\">程序包</a></li>\n<li>类</li>\n<li>使用</li>\n<li class=\"navBarCell1Rev\">树</li>\n<li><a href=\"deprecated-list.html\">已过时</a></li>\n<li><a href=\"index-all.html\">索引</a></li>\n<li><a href=\"help-doc.html\">帮助</a></li>\n</ul>\n</div>\n<div class=\"subNav\">\n<ul class=\"navList\">\n<li>上一个</li>\n<li>下一个</li>\n</ul>\n<ul class=\"navList\">\n<li><a href=\"index.html?overview-tree.html\" target=\"_top\">框架</a></li>\n<li><a href=\"overview-tree.html\" target=\"_top\">无框架</a></li>\n</ul>\n<ul class=\"navList\" id=\"allclasses_navbar_bottom\">\n<li><a href=\"allclasses-noframe.html\">所有类</a></li>\n</ul>\n<div>\n<script type=\"text/javascript\"><!--\n  allClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n  if(window==top) {\n    allClassesLink.style.display = \"block\";\n  }\n  else {\n    allClassesLink.style.display = \"none\";\n  }\n  //-->\n</script>\n</div>\n<a name=\"skip.navbar.bottom\">\n<!--   -->\n</a></div>\n<!-- ======== END OF BOTTOM NAVBAR ======= -->\n<p class=\"legalCopy\"><small>Copyright &#169; 2018. All rights reserved.</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "sonic-java/apidocs/package-list",
    "content": "com.github.tencent\n"
  },
  {
    "path": "sonic-java/apidocs/script.js",
    "content": "function show(type)\n{\n    count = 0;\n    for (var key in methods) {\n        var row = document.getElementById(key);\n        if ((methods[key] &  type) != 0) {\n            row.style.display = '';\n            row.className = (count++ % 2) ? rowColor : altColor;\n        }\n        else\n            row.style.display = 'none';\n    }\n    updateTabs(type);\n}\n\nfunction updateTabs(type)\n{\n    for (var value in tabs) {\n        var sNode = document.getElementById(tabs[value][0]);\n        var spanNode = sNode.firstChild;\n        if (value == type) {\n            sNode.className = activeTableTab;\n            spanNode.innerHTML = tabs[value][1];\n        }\n        else {\n            sNode.className = tableTab;\n            spanNode.innerHTML = \"<a href=\\\"javascript:show(\"+ value + \");\\\">\" + tabs[value][1] + \"</a>\";\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-java/apidocs/stylesheet.css",
    "content": "/* Javadoc style sheet */\n/*\nOverall document style\n*/\n\n@import url('resources/fonts/dejavu.css');\n\nbody {\n    background-color:#ffffff;\n    color:#353833;\n    font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;\n    font-size:14px;\n    margin:0;\n}\na:link, a:visited {\n    text-decoration:none;\n    color:#4A6782;\n}\na:hover, a:focus {\n    text-decoration:none;\n    color:#bb7a2a;\n}\na:active {\n    text-decoration:none;\n    color:#4A6782;\n}\na[name] {\n    color:#353833;\n}\na[name]:hover {\n    text-decoration:none;\n    color:#353833;\n}\npre {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n}\nh1 {\n    font-size:20px;\n}\nh2 {\n    font-size:18px;\n}\nh3 {\n    font-size:16px;\n    font-style:italic;\n}\nh4 {\n    font-size:13px;\n}\nh5 {\n    font-size:12px;\n}\nh6 {\n    font-size:11px;\n}\nul {\n    list-style-type:disc;\n}\ncode, tt {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n    margin-top:8px;\n    line-height:1.4em;\n}\ndt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n}\ntable tr td dt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    vertical-align:top;\n    padding-top:4px;\n}\nsup {\n    font-size:8px;\n}\n/*\nDocument title and Copyright styles\n*/\n.clear {\n    clear:both;\n    height:0px;\n    overflow:hidden;\n}\n.aboutLanguage {\n    float:right;\n    padding:0px 21px;\n    font-size:11px;\n    z-index:200;\n    margin-top:-9px;\n}\n.legalCopy {\n    margin-left:.5em;\n}\n.bar a, .bar a:link, .bar a:visited, .bar a:active {\n    color:#FFFFFF;\n    text-decoration:none;\n}\n.bar a:hover, .bar a:focus {\n    color:#bb7a2a;\n}\n.tab {\n    background-color:#0066FF;\n    color:#ffffff;\n    padding:8px;\n    width:5em;\n    font-weight:bold;\n}\n/*\nNavigation bar styles\n*/\n.bar {\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    padding:.8em .5em .4em .8em;\n    height:auto;/*height:1.8em;*/\n    font-size:11px;\n    margin:0;\n}\n.topNav {\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px; \n}\n.bottomNav {\n    margin-top:10px;\n    background-color:#4D7A97;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav {\n    background-color:#dee3e9;\n    float:left;\n    width:100%;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav div {\n    clear:left;\n    float:left;\n    padding:0 0 5px 6px;\n    text-transform:uppercase;\n}\nul.navList, ul.subNavList {\n    float:left;\n    margin:0 25px 0 0;\n    padding:0;\n}\nul.navList li{\n    list-style:none;\n    float:left;\n    padding: 5px 6px;\n    text-transform:uppercase;\n}\nul.subNavList li{\n    list-style:none;\n    float:left;\n}\n.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {\n    color:#FFFFFF;\n    text-decoration:none;\n    text-transform:uppercase;\n}\n.topNav a:hover, .bottomNav a:hover {\n    text-decoration:none;\n    color:#bb7a2a;\n    text-transform:uppercase;\n}\n.navBarCell1Rev {\n    background-color:#F8981D;\n    color:#253441;\n    margin: auto 5px;\n}\n.skipNav {\n    position:absolute;\n    top:auto;\n    left:-9999px;\n    overflow:hidden;\n}\n/*\nPage header and footer styles\n*/\n.header, .footer {\n    clear:both;\n    margin:0 20px;\n    padding:5px 0 0 0;\n}\n.indexHeader {\n    margin:10px;\n    position:relative;\n}\n.indexHeader span{\n    margin-right:15px;\n}\n.indexHeader h1 {\n    font-size:13px;\n}\n.title {\n    color:#2c4557;\n    margin:10px 0;\n}\n.subTitle {\n    margin:5px 0 0 0;\n}\n.header ul {\n    margin:0 0 15px 0;\n    padding:0;\n}\n.footer ul {\n    margin:20px 0 5px 0;\n}\n.header ul li, .footer ul li {\n    list-style:none;\n    font-size:13px;\n}\n/*\nHeading styles\n*/\ndiv.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList li.blockList h3 {\n    padding:0;\n    margin:15px 0;\n}\nul.blockList li.blockList h2 {\n    padding:0px 0 20px 0;\n}\n/*\nPage layout container styles\n*/\n.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {\n    clear:both;\n    padding:10px 20px;\n    position:relative;\n}\n.indexContainer {\n    margin:10px;\n    position:relative;\n    font-size:12px;\n}\n.indexContainer h2 {\n    font-size:13px;\n    padding:0 0 3px 0;\n}\n.indexContainer ul {\n    margin:0;\n    padding:0;\n}\n.indexContainer ul li {\n    list-style:none;\n    padding-top:2px;\n}\n.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {\n    font-size:12px;\n    font-weight:bold;\n    margin:10px 0 0 0;\n    color:#4E4E4E;\n}\n.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {\n    margin:5px 0 10px 0px;\n    font-size:14px;\n    font-family:'DejaVu Sans Mono',monospace;\n}\n.serializedFormContainer dl.nameValue dt {\n    margin-left:1px;\n    font-size:1.1em;\n    display:inline;\n    font-weight:bold;\n}\n.serializedFormContainer dl.nameValue dd {\n    margin:0 0 0 1px;\n    font-size:1.1em;\n    display:inline;\n}\n/*\nList styles\n*/\nul.horizontal li {\n    display:inline;\n    font-size:0.9em;\n}\nul.inheritance {\n    margin:0;\n    padding:0;\n}\nul.inheritance li {\n    display:inline;\n    list-style:none;\n}\nul.inheritance li ul.inheritance {\n    margin-left:15px;\n    padding-left:15px;\n    padding-top:1px;\n}\nul.blockList, ul.blockListLast {\n    margin:10px 0 10px 0;\n    padding:0;\n}\nul.blockList li.blockList, ul.blockListLast li.blockList {\n    list-style:none;\n    margin-bottom:15px;\n    line-height:1.4;\n}\nul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {\n    padding:0px 20px 5px 10px;\n    border:1px solid #ededed; \n    background-color:#f8f8f8;\n}\nul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {\n    padding:0 0 5px 8px;\n    background-color:#ffffff;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockList {\n    margin-left:0;\n    padding-left:0;\n    padding-bottom:15px;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {\n    list-style:none;\n    border-bottom:none;\n    padding-bottom:0;\n}\ntable tr td dl, table tr td dl dt, table tr td dl dd {\n    margin-top:0;\n    margin-bottom:1px;\n}\n/*\nTable styles\n*/\n.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {\n    width:100%;\n    border-left:1px solid #EEE; \n    border-right:1px solid #EEE; \n    border-bottom:1px solid #EEE; \n}\n.overviewSummary, .memberSummary  {\n    padding:0px;\n}\n.overviewSummary caption, .memberSummary caption, .typeSummary caption,\n.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {\n    position:relative;\n    text-align:left;\n    background-repeat:no-repeat;\n    color:#253441;\n    font-weight:bold;\n    clear:none;\n    overflow:hidden;\n    padding:0px;\n    padding-top:10px;\n    padding-left:1px;\n    margin:0px;\n    white-space:pre;\n}\n.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,\n.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,\n.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,\n.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,\n.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,\n.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,\n.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,\n.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {\n    color:#FFFFFF;\n}\n.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,\n.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    padding-bottom:7px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    border: none;\n    height:16px;\n}\n.memberSummary caption span.activeTableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    height:16px;\n}\n.memberSummary caption span.tableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#4D7A97;\n    height:16px;\n}\n.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {\n    padding-top:0px;\n    padding-left:0px;\n    padding-right:0px;\n    background-image:none;\n    float:none;\n    display:inline;\n}\n.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,\n.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {\n    display:none;\n    width:5px;\n    position:relative;\n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .activeTableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative; \n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .tableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative;\n    background-color:#4D7A97;\n    float:left;\n\n}\n.overviewSummary td, .memberSummary td, .typeSummary td,\n.useSummary td, .constantsSummary td, .deprecatedSummary td {\n    text-align:left;\n    padding:0px 0px 12px 10px;\n}\nth.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,\ntd.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{\n    vertical-align:top;\n    padding-right:0px;\n    padding-top:8px;\n    padding-bottom:3px;\n}\nth.colFirst, th.colLast, th.colOne, .constantsSummary th {\n    background:#dee3e9;\n    text-align:left;\n    padding:8px 3px 3px 7px;\n}\ntd.colFirst, th.colFirst {\n    white-space:nowrap;\n    font-size:13px;\n}\ntd.colLast, th.colLast {\n    font-size:13px;\n}\ntd.colOne, th.colOne {\n    font-size:13px;\n}\n.overviewSummary td.colFirst, .overviewSummary th.colFirst,\n.useSummary td.colFirst, .useSummary th.colFirst,\n.overviewSummary td.colOne, .overviewSummary th.colOne,\n.memberSummary td.colFirst, .memberSummary th.colFirst,\n.memberSummary td.colOne, .memberSummary th.colOne,\n.typeSummary td.colFirst{\n    width:25%;\n    vertical-align:top;\n}\ntd.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 {\n    font-weight:bold;\n}\n.tableSubHeadingColor {\n    background-color:#EEEEFF;\n}\n.altColor {\n    background-color:#FFFFFF;\n}\n.rowColor {\n    background-color:#EEEEEF;\n}\n/*\nContent styles\n*/\n.description pre {\n    margin-top:0;\n}\n.deprecatedContent {\n    margin:0;\n    padding:10px 0;\n}\n.docSummary {\n    padding:0;\n}\n\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    font-style:normal;\n}\n\ndiv.block {\n    font-size:14px;\n    font-family:'DejaVu Serif', Georgia, \"Times New Roman\", Times, serif;\n}\n\ntd.colLast div {\n    padding-top:0px;\n}\n\n\ntd.colLast a {\n    padding-bottom:3px;\n}\n/*\nFormatting effect styles\n*/\n.sourceLineNo {\n    color:green;\n    padding:0 30px 0 0;\n}\nh1.hidden {\n    visibility:hidden;\n    overflow:hidden;\n    font-size:10px;\n}\n.block {\n    display:block;\n    margin:3px 10px 2px 0px;\n    color:#474747;\n}\n.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,\n.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,\n.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {\n    font-weight:bold;\n}\n.deprecationComment, .emphasizedPhrase, .interfaceName {\n    font-style:italic;\n}\n\ndiv.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,\ndiv.block div.block span.interfaceName {\n    font-style:normal;\n}\n\ndiv.contentContainer ul.blockList li.blockList h2{\n    padding-bottom:0px;\n}\n"
  },
  {
    "path": "sonic-java/sample/webapp/WEB-INF/web.xml",
    "content": "<web-app version=\"3.1\" xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd\">\n  <filter>\n    <filter-name>SonicFilter</filter-name>\n    <filter-class>com.github.tencent.SonicFilter</filter-class>\n  </filter>\n  <filter-mapping>\n    <filter-name>SonicFilter</filter-name>\n    <url-pattern>/*</url-pattern>\n  </filter-mapping>\n</web-app>\n"
  },
  {
    "path": "sonic-java/sample/webapp/index.jsp",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>SONIC</title>\n</head>\n<body>\n<h2>Hello World!</h2>\n<!--sonicdiff-data1-->\n<p>example：</p>\n<img src=\"//mc.vip.qq.com/img/img-1.png?max_age=2592000\" alt=\"\">\n<!--sonicdiff-data1-end-->\n</body>\n</html>"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/AbstractReplaceCallBack.java",
    "content": "package com.github.tencent;\n\nimport java.util.regex.Matcher;\n\npublic abstract class AbstractReplaceCallBack implements ReplaceCallBack {\n\n    protected Matcher matcher;\n\n    final public String replace(String text, int index, Matcher matcher) {\n        this.matcher = matcher;\n        try {\n            return doReplace(text, index, matcher);\n        } finally {\n            this.matcher = null;\n        }\n    }\n\n    /**\n     * replace string using matcher\n     * @param text\n     * @param index\n     * @param matcher\n     * @return\n     */\n    public abstract String doReplace(String text, int index, Matcher matcher);\n\n}\n"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/HttpServletResponseCopier.java",
    "content": "package com.github.tencent;\n\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\n\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.servlet.http.HttpServletResponseWrapper;\n\npublic class HttpServletResponseCopier extends HttpServletResponseWrapper {\n    private PrintWriter writer;\n    private ServletOutputStreamCopier copier;\n\n    public HttpServletResponseCopier(HttpServletResponse response) throws IOException {\n        super(response);\n    }\n\n    @Override\n    public ServletOutputStream getOutputStream() throws IOException {\n        if (writer != null) {\n            throw new IllegalStateException(\"getWriter() has already been called on this response.\");\n        }\n        copier = new ServletOutputStreamCopier();\n        return copier;\n    }\n\n    @Override\n    public PrintWriter getWriter() throws IOException {\n        if (copier != null) {\n            throw new IllegalStateException(\"getOutputStream() has already been called on this response.\");\n        }\n        if (writer == null) {\n            copier = new ServletOutputStreamCopier();\n            writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()), true);\n        }\n        return writer;\n    }\n\n    @Override\n    public void flushBuffer() throws IOException {\n        if (writer != null) {\n            writer.flush();\n        } else if (copier != null) {\n            copier.flush();\n        }\n    }\n\n    public byte[] getCopy() {\n        if (copier != null) {\n            return copier.getCopy();\n        } else {\n            return new byte[0];\n        }\n    }\n}\n"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/ReplaceCallBack.java",
    "content": "package com.github.tencent;\n\nimport java.util.regex.Matcher;\n\npublic interface ReplaceCallBack {\n    /**\n     * replace string using matcher\n     * @param text \n     * @param index \n     * @param matcher \n     * @return\n     */\n    public String replace(String text, int index, Matcher matcher);\n}\n"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/ServletOutputStreamCopier.java",
    "content": "package com.github.tencent;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\n\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.WriteListener;\n\npublic class ServletOutputStreamCopier extends ServletOutputStream {\n\n    private ByteArrayOutputStream copy;\n\n    public ServletOutputStreamCopier() {\n        this.copy = new ByteArrayOutputStream();\n    }\n\n    @Override\n    public void write(int b) throws IOException {\n        copy.write(b);\n    }\n\n    public byte[] getCopy() {\n        return copy.toByteArray();\n    }\n\n    @Override\n    public boolean isReady() {\n        return this.isReady();\n    }\n\n    @Override\n    public void setWriteListener(WriteListener writeListener) {\n        this.setWriteListener(writeListener);\n    }\n\n}\n"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/SonicFilter.java",
    "content": "package com.github.tencent;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport javax.servlet.Filter;\nimport javax.servlet.FilterChain;\nimport javax.servlet.FilterConfig;\nimport javax.servlet.ServletException;\nimport javax.servlet.ServletRequest;\nimport javax.servlet.ServletResponse;\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport com.google.gson.*;\n\nclass TemplateReplace extends AbstractReplaceCallBack {\n    public static boolean shoudSonicDiffBodyReplace = false; \n    public static int diffIndex = 0;\n    public static String tagPrefix = \"auto\";\n    public static HashMap<String, String> diffTagNames = new HashMap<String, String>(); \n\n    public String doReplace(String text, int index, Matcher matcher) {\n        StringBuilder tagBuilder = new StringBuilder();\n        String tagName;\n        shoudSonicDiffBodyReplace = true;\n        if(matcher.groupCount() == 1) {\n            tagName = matcher.group(1);\n        }\n        else {\n            StringBuilder sb = new StringBuilder();\n            sb.append(tagPrefix).append(diffIndex++);\n            tagName = sb.toString();\n        }\n        diffTagNames.put(tagName, matcher.group(0));\n        return tagBuilder.append(\"{\").append(tagName).append(\"}\").toString();\n    }\n\n    public static void reset() {\n        shoudSonicDiffBodyReplace = false;\n        diffIndex = 0;\n        diffTagNames.clear();\n    }\n\n}\n\npublic class SonicFilter implements Filter {\n\n    private FilterConfig filterConfig;\n\n    @Override\n    public void destroy() {\n        this.filterConfig = null;\n    }\n\n    @Override\n    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)\n            throws IOException, ServletException {\n\n        HttpServletRequest httpRequest = (HttpServletRequest) request;\n        HttpServletResponse httpResponse = (HttpServletResponse) response;\n        Map<String,String> headerMap = SonicUtil.getAllHttpHeaders(httpRequest);\n        String etag = \"\";\n        String htmlContent;\n        String htmlContentSha1 =\"\"; \n        String value = headerMap.get(\"accept-diff\");\n        if (headerMap.containsKey(\"accept-diff\") && value.equals(\"true\")) {\n            httpResponse.addHeader(\"Cache-Control\", \"no-cache\");\n            httpResponse.addHeader(\"Cache-Offline\", \"true\");\n            if (headerMap.containsKey(\"if-none-match\") || headerMap.containsKey(\"If-None-Match\")) {\n                etag = (headerMap.get(\"if-none-match\") != null ? headerMap.get(\"if-none-match\")\n                        : headerMap.get(\"If-None-Match\"));\n            }\n        }\n        HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);\n        try {\n            chain.doFilter(request, responseCopier);\n            responseCopier.flushBuffer();\n        } finally {\n            String contentType = responseCopier.getContentType();\n            byte[] copy = responseCopier.getCopy();\n            //sonic only filter out text\n            if(contentType == null || !contentType.contains(\"text\")){\n                ServletOutputStream out =  httpResponse.getOutputStream();\n                out.write(copy);\n                out.close();\n                return;\n            }\n            htmlContent = new String(copy, \"UTF-8\");\n            htmlContentSha1 = SonicUtil.encrypt(htmlContent, \"sha-1\");\n        }\n        // if not modified, return 304\n        if(etag.equalsIgnoreCase(htmlContentSha1)) {\n            httpResponse.addHeader(\"Cache-Offline\", \"store\");\n            httpResponse.addHeader(\"Content-Length\", \"0\");\n            httpResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);\n            return;\n        }\n\n        httpResponse.setHeader(\"Etag\", htmlContentSha1);\n        String htmlTitle;\n        String clientTemplateTag =\"\";\n        if(headerMap.containsKey(\"template-tag\")) {\n            clientTemplateTag = headerMap.get(\"template-tag\");\n        }\n        \n        String stringTitlePattern = \"<title(.*?)<\\\\/title>\";\n        htmlTitle = SonicUtil.pregMatch(htmlContent, stringTitlePattern);\n        String htmlTemplate= htmlContent.replaceAll(stringTitlePattern,\"{title}\");\n        //replace data with template\n        String stringTemplatePattern = \"<!--sonicdiff-?(\\\\w*)-->[\\\\s\\\\S]+?<!--sonicdiff-?\\\\w*-end-->\";\n        TemplateReplace templateReplace = new TemplateReplace();\n        Pattern pattern = Pattern.compile(stringTemplatePattern, Pattern.CASE_INSENSITIVE);\n        htmlTemplate = SonicUtil.replaceAllCallBack(htmlTemplate, pattern, templateReplace);\n\n        String templateMd5 = SonicUtil.encrypt(htmlTemplate, \"sha-1\");\n        httpResponse.addHeader(\"template-tag\", templateMd5);\n        Map<String, Object> result = new HashMap<String, Object>();\n        Map<String, String> dataMap = new HashMap<String, String>();\n        dataMap.put(\"{title}\", htmlTitle);\n        for (Map.Entry<String, String> entry : TemplateReplace.diffTagNames.entrySet()) {\n            StringBuilder strKey = new StringBuilder();\n            strKey.append(\"{\").append(entry.getKey()).append(\"}\");\n            dataMap.put(strKey.toString(), entry.getValue());\n        }\n\n        TemplateReplace.reset();\n        result.put(\"data\", dataMap);\n        result.put(\"template-tag\", templateMd5);\n        result.put(\"html-sha1\", htmlContentSha1);\n        String resultStr=\"\";\n        if(templateMd5.equals(clientTemplateTag)) {\n            httpResponse.addHeader(\"template-change\", \"false\");\n            result.put(\"diff\", \"\");\n            Gson gson = new Gson();\n            resultStr = gson.toJson(result);\n        }\n        else {\n            httpResponse.addHeader(\"template-change\", \"true\");\n            resultStr = htmlContent;\n        }\n        ServletOutputStream out = httpResponse.getOutputStream();\n        out.write(resultStr.getBytes(\"UTF-8\"));\n        httpResponse.addHeader(\"Content-Length\", String.valueOf(resultStr.getBytes(\"UTF-8\").length));\n        out.close();\n    }\n\n    @Override\n    public void init(FilterConfig config) throws ServletException {\n        this.filterConfig = config;\n    }\n\n}\n"
  },
  {
    "path": "sonic-java/src/main/java/com/github/tencent/SonicUtil.java",
    "content": "package com.github.tencent;\n\nimport java.io.UnsupportedEncodingException;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport javax.servlet.http.HttpServletRequest;\n\npublic class SonicUtil {\n\n    /**\n     * get hex string\n     *\n     * @param arr\n     * @return\n     */\n    public static String hex(byte[] arr) {\n        StringBuffer sb = new StringBuffer();\n        for (int i = 0; i < arr.length; ++i) {\n            sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3));\n        }\n        return sb.toString();\n    }\n\n    /**\n     * encrypt string\n     * @param inputText\n     * @param algorithmName\n     * @return\n     */\n    public static String encrypt(String inputText, String algorithmName) {\n        if (inputText == null || \"\".equals(inputText.trim())) {\n            return \"\";\n        }\n        if (algorithmName == null || \"\".equals(algorithmName.trim())) {\n            algorithmName = \"md5\";\n        }\n        String encryptText = null;\n        try {\n            MessageDigest m = MessageDigest.getInstance(algorithmName);\n            m.update(inputText.getBytes(\"UTF8\"));\n            byte s[] = m.digest();\n            return hex(s);\n        } catch (NoSuchAlgorithmException e) {\n            e.printStackTrace();\n        } catch (UnsupportedEncodingException e) {\n            e.printStackTrace();\n        }\n        return encryptText;\n    }\n\n    /**\n     * replace string which match the pattern with callback\n     * @param string\n     * @param pattern\n     * @param replacement\n     * @return\n     */\n    public static String replaceAllCallBack(String string, Pattern pattern, ReplaceCallBack replacement) {\n        if (string == null) {\n            return null;\n        }\n        Matcher m = pattern.matcher(string);\n        if (m.find()) {\n            StringBuffer sb = new StringBuffer();\n            int index = 0;\n            while (true) {\n                m.appendReplacement(sb, replacement.replace(m.group(0), index++, m));\n                if (!m.find()) {\n                    break;\n                }\n            }\n            m.appendTail(sb);\n            return sb.toString();\n        }\n        return string;\n    }\n\n    /**\n     * get matched string\n     * @param strContent\n     * @param strPattern\n     * @return\n     */\n    public static String pregMatch(String strContent, String strPattern) {\n        Pattern titlePattern = Pattern.compile(strPattern, Pattern.CASE_INSENSITIVE);\n        Matcher titleMatcher = titlePattern.matcher(strContent);\n        if(titleMatcher.find()) {\n            return titleMatcher.group(0);\n        }\n        return \"\";\n    }\n\n    /**\n     * get http headers\n     * @param httpRequest\n     * @return\n     */\n    public static Map<String,String> getAllHttpHeaders(HttpServletRequest httpRequest) {\n        Map<String, String> headerMap = new HashMap<String, String>();\n        Enumeration<String> headerNames = httpRequest.getHeaderNames();\n        if (headerNames != null) {\n            while (headerNames.hasMoreElements()) {\n                String key = headerNames.nextElement();\n                String value = httpRequest.getHeader(key);\n                headerMap.put(key, value);\n            }\n        }\n        return headerMap;\n    }\n}\n"
  },
  {
    "path": "sonic-nodejs/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Dependency directories\nnode_modules/\nsample/node_modules/\nsample/assets/node_modules/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# dotenv environment variables file\n.env\n"
  },
  {
    "path": "sonic-nodejs/README.md",
    "content": "## Getting started with Node.js\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n## How to use for Server\n### Dependencies\n\n1）Node Version > 7.0\n\n2）install **sonic_differ** module\n\n\n```Node.js\nnpm install sonic_differ --save\n```\n\n3）import **sonic_differ** module\n\n```Node.js\nconst differ = require('sonic_differ');\n```\n\n### Intercept and process data from server in Sonic mode.\n\n1）First, create a Sonic cache struct like following code.\n\n```Node.js\nlet sonic = {\n    buffer: [],\n    write: function (chunk, encoding) {\n        let buffer = chunk;\n        let ecode = encoding || 'utf8';\n        if (!Buffer.isBuffer(chunk)) {\n            buffer = new Buffer(chunk, ecode);\n        }\n        sonic.buffer.push(buffer);\n    }\n};\n```\n\n2）Second, Intercept the data from server and use `sonic_differ` module to process\n\n```Node.js\nresponse.on('data', (chunk, encoding) => {\n    sonic.write(chunk, encoding)\n});\nresponse.on('end', () => {\n    let result = differ(ctx, Buffer.concat(sonic.buffer));\n    sonic.buffer = [];\n    if (result.cache) {\n        //304 Not Modified, return nothing.\n        return ''\n    } else {\n        //other Sonic status.\n        return result.data\n    }\n});\n```\n\n## How to use for front-end\n\nHere is a simple demo shows how to use Sonic for front-end.\n```Html\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n    <title>demo</title>\n    <script type=\"text/javascript\">\n            \n            // Interacts with mobile client by JavaScript interface to get Sonic diff data.\n            function getDiffData(){\n                window.sonic.getDiffData();\n            }\n            \n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.   \n           function getDiffDataCallback(result){\n                var sonicStatus = 0; \n                /**\n                * The Sonic status:\n                * 0: It fails to get any data from mobile client.\n                * 1: It is first time for mobile client to use Sonic.\n                * 2: Mobile client reload the whole websites.\n                * 3: Websites will be updated dynamically with local refresh.\n                * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\n                */\n                sonicUpdateData = {}; //sonic diff data\n                var result = JSON.parse(result);\n                if(result['code'] == 200){\n                    sonicStatus = 3;\n                    sonicUpdateData = JSON.parse(result['result']);\n                } else if (result['code'] == 1000) {\n                    sonicStatus = 1;\n                } else if (result['code'] == 2000) {\n                    sonicStatus = 2;\n                } else if(result['code'] == 304) {\n                    sonicStatus = 4;\n                }\n                handleSonicDiffData(sonicStatus, sonicUpdateData);\n            }\n            \n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.  \n            function handleSonicDiffData(sonicStatus, sonicUpdateData){\n                if(sonicStatus == 3){\n                    //Websites will be updated dynamically and run some JavaScript while in local refresh mode. \n                    var html = '';\n                    var id = '';\n                    var elementObj = '';\n                    for(var key in sonicUpdateData){\n                        id = key.substring(1,key.length-1);\n                        html = sonicUpdateData[key];\n                        elementObj = document.getElementById(id+'Content');\n                        elementObj.innerHTML = html;\n                    }\n                }\n            }\n    </script>\n</head>\n\n<body>\n    // step 1: specify template and data by inserting different comment anchor.\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n    \n    // step 2: Receives diff data from mobile client through Javascript interface.\n    <script type=\"text/javascript\">\n        window.onload = function(){\n            getDiffData();\n        }\n    </script>\n</body>\n</html>\n```\n\n### Step 1:\nSpecify template and data by inserting different comment anchor. The data will be wrapped with anchor ```<!-- sonicdiff-moduleName -->```  ```<!-- sonicdiff-moduleName-end -->```. The other part of html is template.\n```Html\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n```\n\n### Step 2:\nReceives 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.\n```Html\n<script type=\"text/javascript\">\n     window.onload = function(){\n         getDiffData();\n     }\n</script>\n```\n\n### Step 3:\nHandle 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.\n```Html\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction getDiffDataCallback(result){\n｝\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction handleSonicDiffData(sonicStatus, sonicUpdateData){\n｝\n```\n\n ## Support\nAny problem?\n\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs).\n2. Contact us for help.\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n"
  },
  {
    "path": "sonic-nodejs/README_CN.md",
    "content": "## 开始使用\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n## Node端的使用\n\n### 依赖关系\n\n1）Node版本必须大于7，因为代码中使用了async/await语法\n\n2）安装`sonic_differ`模块\n\n```Node.js\nnpm install sonic_differ --save\n```\n\n简单情况下直接npm install 即可\n\n3）后端代码中引用`sonic_differ`模块\n\n```Node.js\nconst differ = require('sonic_differ');\n```\n\n### Sonic模式中，需要对数据进行拦截与加工处理\n\n1）第一步，新建一个sonic结构体，主要是方便操作，大家理解之后可以自行修改\n\n```Node.js\nlet sonic = {\n    buffer: [],\n    write: function (chunk, encoding) {\n        let buffer = chunk;\n        let ecode = encoding || 'utf8';\n        if (!Buffer.isBuffer(chunk)) {\n            buffer = new Buffer(chunk, ecode);\n        }\n        sonic.buffer.push(buffer);\n    }\n};\n```\n\n2）第二步，拦截服务端的数据，用`sonic_differ`模块对数据进行处理，这里大家理解之后可以根据自己的后端改造，本质就是直出的内容用`sonic_differ`模块进行一次二次加工，再输出给前端\t\t\n \t\n ```Node.js\t\t\n response.on('data', (chunk, encoding) => {\t\t\n     sonic.write(chunk, encoding)\t\t\n });\t\t\n response.on('end', () => {\t\t\n     let result = differ(ctx, Buffer.concat(sonic.buffer));\t\t\n     sonic.buffer = [];\t\t\n     if (result.cache) {\t\t\n         //304 Not Modified, return nothing.\t\t\n         return ''\t\t\n     } else {\t\t\n         //other Sonic status.\t\t\n         return result.data\t\t\n     }\t\t\n });\t\t\n ```\n \n ## 前端的使用\n\n通过一个简单的demo来说明一下前端使用方法。\n```Html\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n    <title>demo</title>\n    <script type=\"text/javascript\">\n            \n            // 调用终端接口触发终端去获取diff data\n            function getDiffData(){\n                window.sonic.getDiffData();\n            }\n            \n            // step 3: 添加响应方法，用于获取终端返回的diff data\n           function getDiffDataCallback(result){\n                var sonicStatus = 0; \n                /**\n                * The Sonic status:\n                * 0: It fails to get any data from mobile client.\n                * 1: It is first time for mobile client to use Sonic.\n                * 2: Mobile client reload the whole websites.\n                * 3: Websites will be updated dynamically with local refresh.\n                * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\n                */\n                sonicUpdateData = {}; //sonic diff data\n                var result = JSON.parse(result);\n                if(result['code'] == 200){\n                    sonicStatus = 3;\n                    sonicUpdateData = JSON.parse(result['result']);\n                } else if (result['code'] == 1000) {\n                    sonicStatus = 1;\n                } else if (result['code'] == 2000) {\n                    sonicStatus = 2;\n                } else if(result['code'] == 304) {\n                    sonicStatus = 4;\n                }\n                handleSonicDiffData(sonicStatus, sonicUpdateData);\n            }\n            \n            // step 3: 业务上根据diff data来做渲染处理\n            function handleSonicDiffData(sonicStatus, sonicUpdateData){\n                if(sonicStatus == 3){\n                    //Websites will be updated dynamically and run some JavaScript while in local refresh mode. \n                    var html = '';\n                    var id = '';\n                    var elementObj = '';\n                    for(var key in sonicUpdateData){\n                        id = key.substring(1,key.length-1);\n                        html = sonicUpdateData[key];\n                        elementObj = document.getElementById(id+'Content');\n                        elementObj.innerHTML = html;\n                    }\n                }\n            }\n    </script>\n</head>\n\n<body>\n    // step 1: 通过html注释标记模版和数据\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n    \n    // step 2: 调用终端接口获取diff data\n    <script type=\"text/javascript\">\n        window.onload = function(){\n            getDiffData();\n        }\n    </script>\n</body>\n</html>\n```\n\n### Step 1:\n通过注释来标记模版和数据部分。 数据快需要通过 ```<!-- sonicdiff-moduleName -->```  ```<!-- sonicdiff-moduleName-end -->```来标记。其他部分则为模版。\n```Html\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n```\n\n### Step 2:\njs调用终端接口来获取diff data。 本demo中是在页面加载完成后调用js接口，实际调用js接口的时机可以由各个业务自定。\n```Html\n<script type=\"text/javascript\">\n     window.onload = function(){\n         getDiffData();\n     }\n</script>\n```\n\n### Step 3:\n通过终端返回的状态来决定是否重新渲染。 在本demo中，根据终端返回的状态，来获取对应的数据块，继而重新渲染页面。\n```Html\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction getDiffDataCallback(result){\n｝\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction handleSonicDiffData(sonicStatus, sonicUpdateData){\n｝\n```\n\n## 技术支持\n遇到其他问题，可以：\n\n1. 通过demo来理解 [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-nodejs)。\n2. 联系我们。\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n"
  },
  {
    "path": "sonic-nodejs/app.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\n'use strict';\nconst koa = require('koa');\nconst compress = require('./middleware/compress');\nconst through2 = require('through2');\nconst router = require('./router');\nconst app = new koa();\n\napp.use(compress());\n\napp.use(router());\n\n// app.use(async (ctx, next) => {\n//     ctx.body = through2();\n//     ctx.type = 'html';\n//     ctx.body.write('<html><head><meta charset=\"utf-8\"/><title>sonic demo</title></head><body>')\n//     await next();\n// });\n//\n// app.use(async (ctx, next) => {\n//     ctx.body.write(`<h1 id=\"time\"><!--sonicdiff-data1-->现在时间是：${(new Date()).toLocaleString()}<!--sonicdiff-data1-end--></h1>`);\n//     await next();\n// });\n//\n// app.use(async (ctx, next) => {\n//     ctx.body.end(`<body></html>`);\n//     await next();\n// });\n\napp.listen(8080);"
  },
  {
    "path": "sonic-nodejs/assets/build/gulpfile.js",
    "content": "//gulp\nlet gulp = require('gulp');\nlet gutil = require('gulp-util');\nlet sequence = require('gulp-sequence');\nlet through2 = require('through2');\n// let babel = require('gulp-babel');\n// let plumber = require('gulp-plumber');\n\n//路径相关\n// let glob = require('glob');\nlet path = require('path');\nlet fs = require('fs');\n\n//配置\nlet projectPath = '../project.config.js';\nlet projectConfig = require(projectPath);\nlet paths = projectConfig.build;\n\n// //webpack配置及插件\n// let webpackConfigDev = require('./webpack.dev.config');\n// let webpackConfigProd = require('./webpack.production.config');\n//\n// let webpack = require('webpack');\n// let webpackMerge = require('webpack-merge');\n// let CleanWebpackPlugin = require('clean-webpack-plugin');\n\n\n// let async = require('async');\n\n\n/**----------ejs2js--------------**/\nlet ejs2js = require('gulp-ejs2js');\ngulp.task(\"ejs2js\", function (callback) {\n\tconsole.info('执行ejs2js');\n\tbuildEjs2js(paths.ejs2js + '/**/*.ejs', paths.ejs2js, callback);\n});\n\n/**\n * 构建ejs -> jsc\n * @param src 源文件地址\n * @param dest 生成地址\n * @param callback\n */\nfunction buildEjs2js(src, dest, callback) {\n\tgulp.src(src)\n\t\t.on('error', function handleError(err) {\n\t\t\tconsole.error(err.toString());\n\t\t\tthis.emit('end');\n\t\t})\n\t\t.on('end', function () {\n\t\t\tconsole.log('ejsEnd');\n\t\t\tcallback && callback();\n\t\t})\n\t\t.pipe(ejs2js())\n\t\t.pipe(lf2crlf()) //LF2CRLF\n\t\t.pipe(gulp.dest(dest));\n}\n\n\n// /**-----------uglify-------------**/\n// let uglify = require('gulp-uglify');\n// function buildUglify(src, dist, callback) {\n//     return gulp.src(src)\n//         .pipe(uglify())\n//         .pipe(gulp.dest(dist))\n//         .on('end', function () {\n//             console.log('uglify END');\n//             callback();\n//         })\n// }\n// gulp.task('libs', callback => {\n//     let buildPath = projectConfig.build;\n//     buildUglify(buildPath.srcLib + '/**/*.js', buildPath.distLib, callback);\n// });\n\n/**----------辅助方法-------------**/\n//简易gulp插件\nfunction modify(fn) {\n\treturn through2.obj(function (file, encoding, done) {\n\t\tlet content = String(file.contents);\n\t\t//具体业务\n\t\tcontent = fn(content);\n\n\t\tfile.contents = new Buffer(content);\n\t\tthis.push(file);\n\t\tdone();\n\t})\n}\n\n/**\n * gulp lf2crlf\n * @returns {*}\n */\nfunction lf2crlf() {\n\treturn modify(function (content) {\n\t\treturn content.replace(/\\r?\\n/g, '\\r\\n');\n\t});\n}\n\n\n"
  },
  {
    "path": "sonic-nodejs/assets/package.json",
    "content": "{\n  \"name\": \"assets\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"gulp-ejs2js\": \"0.0.1\",\n    \"gulp\": \"^3.9.1\",\n    \"gulp-sequence\": \"^0.4.6\",\n    \"gulp-util\": \"^3.0.8\",\n    \"through2\": \"^2.0.3\"\n  }\n}\n"
  },
  {
    "path": "sonic-nodejs/assets/page/demo1.ejs",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <%- (require('./tpls/common_meta'))() %>\n    <title>demo1</title>\n    <%- (require('./tpls/common_header'))() %>\n</head>\n<body>\n<%- (require('./tpls/common_body_header'))() %>\n<h1>\n    <!--sonicdiff-->服务端时间是：\n    <%= (new Date()).toLocaleString() %>\n    <!--sonicdiff-end-->\n</h1>\n\n</body>\n</html>"
  },
  {
    "path": "sonic-nodejs/assets/page/demo1.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<!doctype html>\\r\\n\\\n<html lang=\"en\">\\r\\n\\\n<head>');\n;_p( (require('./tpls/common_meta'))() );\n;_p('    <title>demo1</title>');\n;_p( (require('./tpls/common_header'))() );\n;_p('</head>\\r\\n\\\n<body>');\n;_p( (require('./tpls/common_body_header'))() );\n;_p('<h1>\\r\\n\\\n    <!--sonicdiff-->服务端时间是：');\n;_p(__e( (new Date()).toLocaleString() ));\n;_p('    <!--sonicdiff-end-->\\r\\n\\\n</h1>\\r\\n\\\n\\r\\n\\\n</body>\\r\\n\\\n</html>');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/demo2-data.js",
    "content": "\nlet dataFn = function(ctx){\n\treturn {urlParams: ctx.request.query};\n};\nmodule.exports = dataFn; "
  },
  {
    "path": "sonic-nodejs/assets/page/demo2.ejs",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n    <%- (require('./tpls/common_meta'))() %>\n    <title>demo2</title>\n\n    <%- (require('./tpls/common_header'))() %>\n    <style>\n        body {\n            background-color: #ddd;\n            text-align: center;\n        }\n\n    </style>\n    <script type=\"application/javascript\">\n        var _pageTime = {};\n        _pageTime.startTime = new Date;\n    </script>\n</head>\n<body>\n<%var urlParams = data && data.urlParams? data.urlParams : {}%>\n<%- (require('./tpls/common_body_header'))() %>\n<div id=\"data1Content\" data-test=\"<%= urlParams.testmode=='1'?Date.now():'' %>\">\n    <!--sonicdiff-data1-->\n    <p id=\"partialRefresh\"><%if(urlParams.testmode=='2'){%>局部刷新:<%= (new Date()).toLocaleString() %><%}%></p>\n    <!--sonicdiff-data1-end-->\n</div>\n<div id=\"data2Content\">\n    <!--sonicdiff-data2-->\n    <p id=\"data2\">数据块</p>\n    <!--sonicdiff-data2-end-->\n\n    <p id=\"pageRefresh\"><%if(urlParams.testmode=='1'){%>页面刷新:<%= (new Date()).toLocaleString() %><%}%></p>\n\n\n</div>\n<div>\n    <p>sonicStatus:<span id=\"sonicStatus\"></span></p>\n    <p>reportSonicStatus:<span id=\"reportSonicStatus\"></span></p>\n    <p>jsbrigeTime:<span id=\"jsbrigeTime\"></span></p>\n    <p>pageTime:<span id=\"pageTime\"></span></p>\n</div>\n<hr/>\n<div>\n    <p>sonic状态含义：</p>\n    <p>0-非sonic</p>\n    <p>2-页面刷新</p>\n    <p>3-局部刷新</p>\n    <p>4-完全缓存</p>\n</div>\n<script>\n    _pageTime.contentLoadedTime = new Date;\n</script>\n\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\"\n        id=\"seajsnode\"></script>\n<script>\n    seajs.config({\n        base: 'http://imgcache.gtimg.cn/club/platform/examples/',\n        localcache: {\n            //浏览器缓存时间\n            maxAge: 2592000,\n            openLocalStorageCache: 0\n        },\n        maxFile: {},\n        debug: 1,\n        //别名\n        alias: {\n            'zepto': 'lib/zepto/zepto'\n        },\n        paths: {\n            'lib': 'http://imgcache.gtimg.cn/club/platform/lib'\n        },\n        manifest: {\n            \"lib/zepto/zepto\": \"1.1.3\",\n            \"lib/sonic/sonic\": \"3-1\"\n        }\n    });\n\n    seajs.use([\"zepto\"], function ($) {\n        /**\n         * sonic后置函数\n         */\n        function afterSonicInit() {\n            console.debug('afterSonicInit');\n        }\n\n        var sonicStatus = 0, //sonic状态 0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n            reportSonicStatus = 0, //sonic上报状态\n            sonicHadExecute = 0, //sonic执行标志位\n            sonicUpdateData = {}; //sonic diff数据\n\n        var sonicStartTime = new Date();\n        window.sonic.getDiffData(); //执行sonicdiff\n        window['getDiffDataCallback'] = function (result) {\n            alert(JSON.stringify(result));\n            if (result['code'] == 200) {\n                reportSonicStatus = sonicStatus = 3;\n                sonicUpdateData = JSON.parse(result['result']);\n                //页面完全没有变化\n            } else if (result['code'] == 1000) {\n                reportSonicStatus = sonicStatus = 1;\n            } else if (result['code'] == 2000) {\n                reportSonicStatus = sonicStatus = 2;\n            } else if (result['code'] == 304) {\n                sonicStatus = 4;\n                switch (parseInt(result['srcCode'])) { //上报状态处理\n                    case 304:\n                        reportSonicStatus = 4;\n                        break;\n                    case 200:\n                        reportSonicStatus = 3;\n                        break;\n                    case 1000:\n                        reportSonicStatus = 1;\n                        break;\n                    case 2000:\n                        reportSonicStatus = 2;\n                        break;\n                    default:\n                        reportSonicStatus = sonicStatus;\n                }\n            }\n            if (sonicHadExecute == 0) {\n                sonicCallback(sonicStatus, reportSonicStatus, sonicUpdateData);\n                sonicHadExecute = 1;\n            }\n        }\n        /**\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\n         * @param sonicStatus\n         * @param reportSonicStatus\n         * @param sonicUpdateData\n         */\n        var sonicCallback = function (sonicStatus, reportSonicStatus, sonicUpdateData) {\n            if (sonicStatus == 1) {\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\n                afterSonicInit();\n            } else if (sonicStatus == 2) {\n                afterSonicInit();\n            } else if (sonicStatus == 3) {\n                mqq && mqq.debug && mqq.debug.detailLog({\n                    id: \"pingtai\",\n                    subid: \"vipcenter\",\n                    content: 'sonic H5 debug data' + JSON.stringify(sonicUpdateData),\n                    level: \"info\"\n                });\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\n                var html = '';\n                var id = '';\n                var elementObj = '';\n                for (var key in sonicUpdateData) {\n                    id = key.substring(1, key.length - 1);\n                    html = sonicUpdateData[key];\n                    elementObj = document.getElementById(id + 'Content');\n                    elementObj.innerHTML = html;\n                }\n                afterSonicInit();\n            } else if (sonicStatus == 4) {\n                afterSonicInit();\n            }\n            alert('sonic数据：' + sonicStatus + JSON.stringify(sonicUpdateData));\n            $(\"#sonicStatus\").text(sonicStatus);\n            $(\"#reportSonicStatus\").text(reportSonicStatus);\n            $(\"#jsbrigeTime\").text((new Date) - sonicStartTime);\n            _pageTime.jsendtTime = new Date();\n            mqq.data.getPerformance(function (json) {\n                alert(JSON.stringify(json, null, 2));\n                if (json && 0 == json.result && json.data) {\n                    var clickStart = json.data.clickStart || 0;\n                    var webviewStart = json.data.webviewStart || 0;\n                    var loadUrl = json.data.pageStart || 0;\n                    var speedPoints = [];\n                    speedPoints[0] = webviewStart - clickStart;      //第一个上报点，从click到webviewstart\n                    speedPoints[1] = loadUrl - clickStart;      //第二上上报时间点，从webviewstart开始到loadurl之间的时间\n                    speedPoints[2] = _pageTime.startTime - clickStart;      //从开始loadurl，到html头获取到得时间点\n                    speedPoints[3] = _pageTime.contentLoadedTime - clickStart;      //从html开始时间点到domready时间点\n                    speedPoints[4] = _pageTime.jsendtTime - clickStart;      //从domready到可以交互的时间点\n                    //alert(JSON.stringify(speedPoints))\n                    $('#pageTime').text(JSON.stringify(speedPoints));\n                    //alert(JSON.stringify(speedPoints))\n\n                }\n            });\n        }\n        /**\n         * sonic超时处理\n         */\n//        setTimeout(function () {\n//            if (sonicHadExecute == 0) {\n//                sonicHadExecute = 1;\n//                sonicCallback(sonicStatus, reportSonicStatus, sonicUpdateData);\n//            }\n//        }, 5000);\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "sonic-nodejs/assets/page/demo2.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<!DOCTYPE HTML>\\r\\n\\\n<html>\\r\\n\\\n<head>');\n;_p( (require('./tpls/common_meta'))() );\n;_p('    <title>demo2</title>');\n;_p( (require('./tpls/common_header'))() );\n;_p('    <style>\\r\\n\\\n        body {\\r\\n\\\n            background-color: #ddd;\\r\\n\\\n            text-align: center;\\r\\n\\\n        }\\r\\n\\\n\\r\\n\\\n    </style>\\r\\n\\\n    <script type=\"application/javascript\">\\r\\n\\\n        var _pageTime = {};\\r\\n\\\n        _pageTime.startTime = new Date;\\r\\n\\\n    </script>\\r\\n\\\n</head>\\r\\n\\\n<body>');\nvar urlParams = data && data.urlParams? data.urlParams : {};_p( (require('./tpls/common_body_header'))() );\n;_p('<div id=\"data1Content\" data-test=\"');\n;_p(__e( urlParams.testmode=='1'?Date.now():'' ));\n;_p('\">\\r\\n\\\n    <!--sonicdiff-data1-->\\r\\n\\\n    <p id=\"partialRefresh\">');\nif(urlParams.testmode=='2'){;_p('局部刷新:');\n;_p(__e( (new Date()).toLocaleString() ));\n};_p('</p>\\r\\n\\\n    <!--sonicdiff-data1-end-->\\r\\n\\\n</div>\\r\\n\\\n<div id=\"data2Content\">\\r\\n\\\n    <!--sonicdiff-data2-->\\r\\n\\\n    <p id=\"data2\">数据块</p>\\r\\n\\\n    <!--sonicdiff-data2-end-->\\r\\n\\\n\\r\\n\\\n    <p id=\"pageRefresh\">');\nif(urlParams.testmode=='1'){;_p('页面刷新:');\n;_p(__e( (new Date()).toLocaleString() ));\n};_p('</p>\\r\\n\\\n\\r\\n\\\n\\r\\n\\\n</div>\\r\\n\\\n<div>\\r\\n\\\n    <p>sonicStatus:<span id=\"sonicStatus\"></span></p>\\r\\n\\\n    <p>reportSonicStatus:<span id=\"reportSonicStatus\"></span></p>\\r\\n\\\n    <p>jsbrigeTime:<span id=\"jsbrigeTime\"></span></p>\\r\\n\\\n    <p>pageTime:<span id=\"pageTime\"></span></p>\\r\\n\\\n</div>\\r\\n\\\n<hr/>\\r\\n\\\n<div>\\r\\n\\\n    <p>sonic状态含义：</p>\\r\\n\\\n    <p>0-非sonic</p>\\r\\n\\\n    <p>2-页面刷新</p>\\r\\n\\\n    <p>3-局部刷新</p>\\r\\n\\\n    <p>4-完全缓存</p>\\r\\n\\\n</div>\\r\\n\\\n<script>\\r\\n\\\n    _pageTime.contentLoadedTime = new Date;\\r\\n\\\n</script>\\r\\n\\\n\\r\\n\\\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\\r\\n\\\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\"\\r\\n\\\n        id=\"seajsnode\"></script>\\r\\n\\\n<script>\\r\\n\\\n    seajs.config({\\r\\n\\\n        base: \\'http://imgcache.gtimg.cn/club/platform/examples/\\',\\r\\n\\\n        localcache: {\\r\\n\\\n            //浏览器缓存时间\\r\\n\\\n            maxAge: 2592000,\\r\\n\\\n            openLocalStorageCache: 0\\r\\n\\\n        },\\r\\n\\\n        maxFile: {},\\r\\n\\\n        debug: 1,\\r\\n\\\n        //别名\\r\\n\\\n        alias: {\\r\\n\\\n            \\'zepto\\': \\'lib/zepto/zepto\\'\\r\\n\\\n        },\\r\\n\\\n        paths: {\\r\\n\\\n            \\'lib\\': \\'http://imgcache.gtimg.cn/club/platform/lib\\'\\r\\n\\\n        },\\r\\n\\\n        manifest: {\\r\\n\\\n            \"lib/zepto/zepto\": \"1.1.3\",\\r\\n\\\n            \"lib/sonic/sonic\": \"3-1\"\\r\\n\\\n        }\\r\\n\\\n    });\\r\\n\\\n\\r\\n\\\n    seajs.use([\"zepto\"], function ($) {\\r\\n\\\n        /**\\r\\n\\\n         * sonic后置函数\\r\\n\\\n         */\\r\\n\\\n        function afterSonicInit() {\\r\\n\\\n            console.debug(\\'afterSonicInit\\');\\r\\n\\\n        }\\r\\n\\\n\\r\\n\\\n        var sonicStatus = 0, //sonic状态 0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\\r\\n\\\n            reportSonicStatus = 0, //sonic上报状态\\r\\n\\\n            sonicHadExecute = 0, //sonic执行标志位\\r\\n\\\n            sonicUpdateData = {}; //sonic diff数据\\r\\n\\\n\\r\\n\\\n        var sonicStartTime = new Date();\\r\\n\\\n        window.sonic.getDiffData(); //执行sonicdiff\\r\\n\\\n        window[\\'getDiffDataCallback\\'] = function (result) {\\r\\n\\\n            alert(JSON.stringify(result));\\r\\n\\\n            if (result[\\'code\\'] == 200) {\\r\\n\\\n                reportSonicStatus = sonicStatus = 3;\\r\\n\\\n                sonicUpdateData = JSON.parse(result[\\'result\\']);\\r\\n\\\n                //页面完全没有变化\\r\\n\\\n            } else if (result[\\'code\\'] == 1000) {\\r\\n\\\n                reportSonicStatus = sonicStatus = 1;\\r\\n\\\n            } else if (result[\\'code\\'] == 2000) {\\r\\n\\\n                reportSonicStatus = sonicStatus = 2;\\r\\n\\\n            } else if (result[\\'code\\'] == 304) {\\r\\n\\\n                sonicStatus = 4;\\r\\n\\\n                switch (parseInt(result[\\'srcCode\\'])) { //上报状态处理\\r\\n\\\n                    case 304:\\r\\n\\\n                        reportSonicStatus = 4;\\r\\n\\\n                        break;\\r\\n\\\n                    case 200:\\r\\n\\\n                        reportSonicStatus = 3;\\r\\n\\\n                        break;\\r\\n\\\n                    case 1000:\\r\\n\\\n                        reportSonicStatus = 1;\\r\\n\\\n                        break;\\r\\n\\\n                    case 2000:\\r\\n\\\n                        reportSonicStatus = 2;\\r\\n\\\n                        break;\\r\\n\\\n                    default:\\r\\n\\\n                        reportSonicStatus = sonicStatus;\\r\\n\\\n                }\\r\\n\\\n            }\\r\\n\\\n            if (sonicHadExecute == 0) {\\r\\n\\\n                sonicCallback(sonicStatus, reportSonicStatus, sonicUpdateData);\\r\\n\\\n                sonicHadExecute = 1;\\r\\n\\\n            }\\r\\n\\\n        }\\r\\n\\\n        /**\\r\\n\\\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\\r\\n\\\n         * @param sonicStatus\\r\\n\\\n         * @param reportSonicStatus\\r\\n\\\n         * @param sonicUpdateData\\r\\n\\\n         */\\r\\n\\\n        var sonicCallback = function (sonicStatus, reportSonicStatus, sonicUpdateData) {\\r\\n\\\n            if (sonicStatus == 1) {\\r\\n\\\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\\r\\n\\\n                afterSonicInit();\\r\\n\\\n            } else if (sonicStatus == 2) {\\r\\n\\\n                afterSonicInit();\\r\\n\\\n            } else if (sonicStatus == 3) {\\r\\n\\\n                mqq && mqq.debug && mqq.debug.detailLog({\\r\\n\\\n                    id: \"pingtai\",\\r\\n\\\n                    subid: \"vipcenter\",\\r\\n\\\n                    content: \\'sonic H5 debug data\\' + JSON.stringify(sonicUpdateData),\\r\\n\\\n                    level: \"info\"\\r\\n\\\n                });\\r\\n\\\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\\r\\n\\\n                var html = \\'\\';\\r\\n\\\n                var id = \\'\\';\\r\\n\\\n                var elementObj = \\'\\';\\r\\n\\\n                for (var key in sonicUpdateData) {\\r\\n\\\n                    id = key.substring(1, key.length - 1);\\r\\n\\\n                    html = sonicUpdateData[key];\\r\\n\\\n                    elementObj = document.getElementById(id + \\'Content\\');\\r\\n\\\n                    elementObj.innerHTML = html;\\r\\n\\\n                }\\r\\n\\\n                afterSonicInit();\\r\\n\\\n            } else if (sonicStatus == 4) {\\r\\n\\\n                afterSonicInit();\\r\\n\\\n            }\\r\\n\\\n            alert(\\'sonic数据：\\' + sonicStatus + JSON.stringify(sonicUpdateData));\\r\\n\\\n            $(\"#sonicStatus\").text(sonicStatus);\\r\\n\\\n            $(\"#reportSonicStatus\").text(reportSonicStatus);\\r\\n\\\n            $(\"#jsbrigeTime\").text((new Date) - sonicStartTime);\\r\\n\\\n            _pageTime.jsendtTime = new Date();\\r\\n\\\n            mqq.data.getPerformance(function (json) {\\r\\n\\\n                alert(JSON.stringify(json, null, 2));\\r\\n\\\n                if (json && 0 == json.result && json.data) {\\r\\n\\\n                    var clickStart = json.data.clickStart || 0;\\r\\n\\\n                    var webviewStart = json.data.webviewStart || 0;\\r\\n\\\n                    var loadUrl = json.data.pageStart || 0;\\r\\n\\\n                    var speedPoints = [];\\r\\n\\\n                    speedPoints[0] = webviewStart - clickStart;      //第一个上报点，从click到webviewstart\\r\\n\\\n                    speedPoints[1] = loadUrl - clickStart;      //第二上上报时间点，从webviewstart开始到loadurl之间的时间\\r\\n\\\n                    speedPoints[2] = _pageTime.startTime - clickStart;      //从开始loadurl，到html头获取到得时间点\\r\\n\\\n                    speedPoints[3] = _pageTime.contentLoadedTime - clickStart;      //从html开始时间点到domready时间点\\r\\n\\\n                    speedPoints[4] = _pageTime.jsendtTime - clickStart;      //从domready到可以交互的时间点\\r\\n\\\n                    //alert(JSON.stringify(speedPoints))\\r\\n\\\n                    $(\\'#pageTime\\').text(JSON.stringify(speedPoints));\\r\\n\\\n                    //alert(JSON.stringify(speedPoints))\\r\\n\\\n\\r\\n\\\n                }\\r\\n\\\n            });\\r\\n\\\n        }\\r\\n\\\n        /**\\r\\n\\\n         * sonic超时处理\\r\\n\\\n         */\\r\\n\\\n//        setTimeout(function () {\\r\\n\\\n//            if (sonicHadExecute == 0) {\\r\\n\\\n//                sonicHadExecute = 1;\\r\\n\\\n//                sonicCallback(sonicStatus, reportSonicStatus, sonicUpdateData);\\r\\n\\\n//            }\\r\\n\\\n//        }, 5000);\\r\\n\\\n    });\\r\\n\\\n\\r\\n\\\n</script>\\r\\n\\\n</body>\\r\\n\\\n</html>');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/demo3-data.js",
    "content": "\nlet dataFn = function(ctx){\n\tvar request = ctx.request;\n\tvar headers = request.header;\n\tvar query = request.query || {};\n\tvar dataImg = 1;\n    var templateFlag = 1;\n    var sonicStatusArr = [\n        2, //templateChange\n        3, //dataUpdate\n        4 //cache\n    ];\n    var sonicStatus = 0; //1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n\n    if (headers['accept-diff']=='true') {\n    \tif (headers['template-tag']) { //有缓存的情况随机局部刷新、模板变更、完全缓存\n    \t\tvar getRandomStatus = function(){\n    \t\t\tvar sonicStatusRand = [3,3,3,3,3,4,4,2,4,4,4];\n    \t\t\tvar index = Math.floor(Math.random() * sonicStatusRand.length);\n    \t\t\treturn sonicStatusRand[index];\n    \t\t}\n    \t\t\n            sonicStatus = sonicStatusArr[parseInt(query['sonicStatus'], 10)]? parseInt(query['sonicStatus'], 10) : getRandomStatus();\n            switch(sonicStatus) {\n                case 2: //模板变更 数据不变 改模板\n                    if (ctx.cookies.get('dataImg')) {\n                        dataImg = parseInt(ctx.cookies.get('dataImg'), 10);\n                    }\n                    if (ctx.cookies.get('templateFlag')) {\n                        templateFlag = +!parseInt(ctx.cookies.get('templateFlag'), 10);\n                    }\n                    break;\n                case 3://局部刷新 数据变 模板不变\n                    if (ctx.cookies.get('dataImg')) {\n                        dataImg = +!parseInt(ctx.cookies.get('dataImg'), 10);\n                    }\n                    // if (ctx.cookies.get('templateFlag')) {\n                    //     templateFlag = templateFlag;\n                    // }\n                    break;\n                case 4:\n                    if (ctx.cookies.get('dataImg')) {\n                        dataImg = parseInt(ctx.cookies.get('dataImg'), 10);\n                    }\n                    if (ctx.cookies.get('templateFlag')) {\n                        templateFlag = parseInt(ctx.cookies.get('templateFlag'), 10);\n                    }\n                    break;\n            }\n    \t} else { //首次\n            sonicStatus = 1;\n        }\n    }\n\n    ctx.cookies.set('dataImg', parseInt(dataImg, 10));\n    ctx.cookies.set('templateFlag',parseInt(templateFlag, 10));\n\n    return {\n    \tdataImg: dataImg,\n    \ttemplateFlag: templateFlag,\n    \tsonicStatus: sonicStatus\n    };\n};\nmodule.exports = dataFn; "
  },
  {
    "path": "sonic-nodejs/assets/page/demo3.ejs",
    "content": "<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n    <%- (require('./tpls/common_meta'))() %>\r\n    <title>SONIC</title>\r\n    <style>\r\n        body {\r\n            margin: 0;\r\n            padding: 0;\r\n            font-size: 14px;\r\n            color: #777;\r\n            margin-top: 20px;\r\n        }\r\n        .sonic-wrapper {\r\n            padding: 0 12px;\r\n        }\r\n        .sonic-wrapper h1 {\r\n            font-size: 18px;\r\n            font-weight: 400;\r\n            color: #000;\r\n        }\r\n        .sonic-wrapper h2 {\r\n            font-size: 14px;\r\n            color: #000;\r\n        }\r\n        .sonic-wrapper p {\r\n            font-size: 14px;\r\n            color: #777;\r\n            line-height: 1.6em;\r\n        }\r\n        .sonic-wrapper img {\r\n            width: 100%;\r\n        }\r\n        .sonic-wrapper table {\r\n            width: 100%;\r\n        }\r\n        .sonic-wrapper table img {\r\n            width: 100%;\r\n        }\r\n        .sonic_des {display:none;}\r\n    </style>\r\n    <script type=\"application/javascript\">\r\n        var _pageTime = {};\r\n        _pageTime.startTime = new Date;\r\n    </script>\r\n</head>\r\n<body>\r\n<div class=\"sonic-wrapper\">\r\n    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\r\n    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\r\n    <span id=\"data1Content\">\r\n    <!--sonicdiff-data1-->\r\n    <p>示例：</p>\r\n    <img src=\"//mc.vip.qq.com/img/img-<%=data.dataImg%>.png?max_age=2592000\" alt=\"\">\r\n    <!--sonicdiff-data1-end-->\r\n    </span>\r\n    <span id=\"des0\" class=\"sonic_des\">\r\n        <h2>非Sonic模式 点击到页面打开耗时:<span id=\"pageTime0\"></span></h2>\r\n        <p>普通直出的方式</p>\r\n    </span>\r\n    <span id=\"des1\" class=\"sonic_des\">\r\n        <h2>首次访问 点击到页面打开耗时:<span id=\"pageTime1\"></span></h2>\r\n        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\r\n    </span>\r\n    <span id=\"des2\" class=\"sonic_des\">\r\n        <h2>模版更新 点击到页面打开耗时:<span id=\"pageTime2\"></span></h2>\r\n        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\r\n    </span>\r\n    <span id=\"des3\" class=\"sonic_des\">\r\n        <h2>数据更新 点击到页面打开耗时:<span id=\"pageTime3\"></span></h2>\r\n        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\r\n    </span>\r\n    <span id=\"des4\" class=\"sonic_des\">\r\n        <h2>完全缓存 点击到页面打开耗时:<span id=\"pageTime4\"></span></h2>\r\n        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\r\n    </span>\r\n    <%if(data.templateFlag){%>\r\n    <h2>页面打开速度效果对比</h2>\r\n    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\r\n\r\n    <table>\r\n        <tr>\r\n            <td>原有直出页面：</td>\r\n            <td>Sonic改造页面：</td>\r\n        </tr>\r\n        <tr>\r\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\" alt=\"\"></td>\r\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\" alt=\"\"></td>\r\n        </tr>\r\n    </table>\r\n    <% }%>\r\n    <h2>Sonic实现原理简介</h2>\r\n    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\r\n</div>\r\n<script>\r\n    _pageTime.jsendtTime = new Date();\r\n</script>\r\n\r\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\r\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\" id=\"seajsnode\"></script>\r\n<script>\r\n    seajs.config({\r\n        base: 'http://imgcache.gtimg.cn/club/platform/examples/',\r\n        localcache: {\r\n            //浏览器缓存时间\r\n            maxAge: 2592000,\r\n            openLocalStorageCache: 0\r\n        },\r\n        maxFile: {},\r\n        debug: 1,\r\n        //别名\r\n        alias: {\r\n            'zepto': 'lib/zepto/zepto'\r\n        },\r\n        paths: {\r\n            'lib': 'http://imgcache.gtimg.cn/club/platform/lib'\r\n        },\r\n        manifest: {\r\n            \"lib/zepto/zepto\": \"1.1.3\",\r\n            \"lib/sonic/sonic\": \"3-1\"\r\n        }\r\n    });\r\n\r\n    seajs.use([\"zepto\", \"lib/sonic/sonic\"], function ($, sonic) {\r\n        /**\r\n         * 后置函数 sonic或普通模式 执行页面初始化等操作\r\n         */\r\n        function afterInit(sonicStatus){\r\n            $('.sonic_des').css('display', 'none');\r\n            $('#des'+sonicStatus).css('display', 'block');\r\n            //耗时分析(上报)\r\n            var performanceJson;\r\n            if (window.sonic && window.sonic.getPerformance) {\r\n                performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\r\n            } else if (window.performance && window.performance.timing) {\r\n                performanceJson = {clickTime: window.performance.timing.navigationStart, loadUrlTime: window.performance.timing.fetchStart};\r\n            } else {\r\n                performanceJson = {clickTime: 0, loadUrlTime: 0};\r\n            }\r\n            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\r\n            $(\"#pageTime\"+sonicStatus).text(pageTime+'ms');\r\n        }\r\n        <% if(data.sonicStatus != 0) {%>\r\n        /**\r\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\r\n         * @param sonicStatus\r\n         * @param reportSonicStatus\r\n         * @param sonicUpdateData\r\n         */\r\n        window.sonicStartTime = new Date;\r\n        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\r\n        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\r\n            if(sonicStatus == 1){\r\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\r\n            }else if(sonicStatus == 2){\r\n\r\n            }else if(sonicStatus == 3){\r\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\r\n                var html = '';\r\n                var id = '';\r\n                var elementObj = '';\r\n                for(var key in sonicUpdateData){\r\n                    id = key.substring(1,key.length-1);\r\n                    html = sonicUpdateData[key];\r\n                    elementObj = document.getElementById(id+'Content');\r\n                    elementObj.innerHTML = html;\r\n                }\r\n\r\n            }else if(sonicStatus == 4){\r\n\r\n            }\r\n            afterInit(reportSonicStatus);\r\n        });\r\n        <% } else {%>\r\n            afterInit(0);\r\n        <% }%>\r\n    });\r\n\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "sonic-nodejs/assets/page/demo3.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\r\n__b=/[&<>\"']/g,\r\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\r\n\r\nmodule.exports = function (data, children) {\r\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\r\nvar __p=[],_p=function(s){__p.push(s)};\r\n;_p('<!DOCTYPE HTML>\\r\\n\\\r\n<html>\\r\\n\\\r\n<head>');\r\n;_p( (require('./tpls/common_meta'))() );\r\n;_p('    <title>SONIC</title>\\r\\n\\\r\n    <style>\\r\\n\\\r\n        body {\\r\\n\\\r\n            margin: 0;\\r\\n\\\r\n            padding: 0;\\r\\n\\\r\n            font-size: 14px;\\r\\n\\\r\n            color: #777;\\r\\n\\\r\n            margin-top: 20px;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper {\\r\\n\\\r\n            padding: 0 12px;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper h1 {\\r\\n\\\r\n            font-size: 18px;\\r\\n\\\r\n            font-weight: 400;\\r\\n\\\r\n            color: #000;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper h2 {\\r\\n\\\r\n            font-size: 14px;\\r\\n\\\r\n            color: #000;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper p {\\r\\n\\\r\n            font-size: 14px;\\r\\n\\\r\n            color: #777;\\r\\n\\\r\n            line-height: 1.6em;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper img {\\r\\n\\\r\n            width: 100%;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper table {\\r\\n\\\r\n            width: 100%;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic-wrapper table img {\\r\\n\\\r\n            width: 100%;\\r\\n\\\r\n        }\\r\\n\\\r\n        .sonic_des {display:none;}\\r\\n\\\r\n    </style>\\r\\n\\\r\n    <script type=\"application/javascript\">\\r\\n\\\r\n        var _pageTime = {};\\r\\n\\\r\n        _pageTime.startTime = new Date;\\r\\n\\\r\n    </script>\\r\\n\\\r\n</head>\\r\\n\\\r\n<body>\\r\\n\\\r\n<div class=\"sonic-wrapper\">\\r\\n\\\r\n    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\\r\\n\\\r\n    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\\r\\n\\\r\n    <span id=\"data1Content\">\\r\\n\\\r\n    <!--sonicdiff-data1-->\\r\\n\\\r\n    <p>示例：</p>\\r\\n\\\r\n    <img src=\"//mc.vip.qq.com/img/img-');\r\n;_p(__e(data.dataImg));\r\n;_p('.png?max_age=2592000\" alt=\"\">\\r\\n\\\r\n    <!--sonicdiff-data1-end-->\\r\\n\\\r\n    </span>\\r\\n\\\r\n    <span id=\"des0\" class=\"sonic_des\">\\r\\n\\\r\n        <h2>非Sonic模式 点击到页面打开耗时:<span id=\"pageTime0\"></span></h2>\\r\\n\\\r\n        <p>普通直出的方式</p>\\r\\n\\\r\n    </span>\\r\\n\\\r\n    <span id=\"des1\" class=\"sonic_des\">\\r\\n\\\r\n        <h2>首次访问 点击到页面打开耗时:<span id=\"pageTime1\"></span></h2>\\r\\n\\\r\n        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\\r\\n\\\r\n    </span>\\r\\n\\\r\n    <span id=\"des2\" class=\"sonic_des\">\\r\\n\\\r\n        <h2>模版更新 点击到页面打开耗时:<span id=\"pageTime2\"></span></h2>\\r\\n\\\r\n        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\\r\\n\\\r\n    </span>\\r\\n\\\r\n    <span id=\"des3\" class=\"sonic_des\">\\r\\n\\\r\n        <h2>数据更新 点击到页面打开耗时:<span id=\"pageTime3\"></span></h2>\\r\\n\\\r\n        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\\r\\n\\\r\n    </span>\\r\\n\\\r\n    <span id=\"des4\" class=\"sonic_des\">\\r\\n\\\r\n        <h2>完全缓存 点击到页面打开耗时:<span id=\"pageTime4\"></span></h2>\\r\\n\\\r\n        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\\r\\n\\\r\n    </span>');\r\nif(data.templateFlag){;_p('    <h2>页面打开速度效果对比</h2>\\r\\n\\\r\n    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\\r\\n\\\r\n\\r\\n\\\r\n    <table>\\r\\n\\\r\n        <tr>\\r\\n\\\r\n            <td>原有直出页面：</td>\\r\\n\\\r\n            <td>Sonic改造页面：</td>\\r\\n\\\r\n        </tr>\\r\\n\\\r\n        <tr>\\r\\n\\\r\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\" alt=\"\"></td>\\r\\n\\\r\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\" alt=\"\"></td>\\r\\n\\\r\n        </tr>\\r\\n\\\r\n    </table>');\r\n };_p('    <h2>Sonic实现原理简介</h2>\\r\\n\\\r\n    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\\r\\n\\\r\n</div>\\r\\n\\\r\n<script>\\r\\n\\\r\n    _pageTime.jsendtTime = new Date();\\r\\n\\\r\n</script>\\r\\n\\\r\n\\r\\n\\\r\n<script src=\"http://open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\\r\\n\\\r\n<script src=\"http://imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\" id=\"seajsnode\"></script>\\r\\n\\\r\n<script>\\r\\n\\\r\n    seajs.config({\\r\\n\\\r\n        base: \\'http://imgcache.gtimg.cn/club/platform/examples/\\',\\r\\n\\\r\n        localcache: {\\r\\n\\\r\n            //浏览器缓存时间\\r\\n\\\r\n            maxAge: 2592000,\\r\\n\\\r\n            openLocalStorageCache: 0\\r\\n\\\r\n        },\\r\\n\\\r\n        maxFile: {},\\r\\n\\\r\n        debug: 1,\\r\\n\\\r\n        //别名\\r\\n\\\r\n        alias: {\\r\\n\\\r\n            \\'zepto\\': \\'lib/zepto/zepto\\'\\r\\n\\\r\n        },\\r\\n\\\r\n        paths: {\\r\\n\\\r\n            \\'lib\\': \\'http://imgcache.gtimg.cn/club/platform/lib\\'\\r\\n\\\r\n        },\\r\\n\\\r\n        manifest: {\\r\\n\\\r\n            \"lib/zepto/zepto\": \"1.1.3\",\\r\\n\\\r\n            \"lib/sonic/sonic\": \"3-1\"\\r\\n\\\r\n        }\\r\\n\\\r\n    });\\r\\n\\\r\n\\r\\n\\\r\n    seajs.use([\"zepto\", \"lib/sonic/sonic\"], function ($, sonic) {\\r\\n\\\r\n        /**\\r\\n\\\r\n         * 后置函数 sonic或普通模式 执行页面初始化等操作\\r\\n\\\r\n         */\\r\\n\\\r\n        function afterInit(sonicStatus){\\r\\n\\\r\n            $(\\'.sonic_des\\').css(\\'display\\', \\'none\\');\\r\\n\\\r\n            $(\\'#des\\'+sonicStatus).css(\\'display\\', \\'block\\');\\r\\n\\\r\n            //耗时分析(上报)\\r\\n\\\r\n            var performanceJson;\\r\\n\\\r\n            if (window.sonic && window.sonic.getPerformance) {\\r\\n\\\r\n                performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\\r\\n\\\r\n            } else if (window.performance && window.performance.timing) {\\r\\n\\\r\n                performanceJson = {clickTime: window.performance.timing.navigationStart, loadUrlTime: window.performance.timing.fetchStart};\\r\\n\\\r\n            } else {\\r\\n\\\r\n                performanceJson = {clickTime: 0, loadUrlTime: 0};\\r\\n\\\r\n            }\\r\\n\\\r\n            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\\r\\n\\\r\n            $(\"#pageTime\"+sonicStatus).text(pageTime+\\'ms\\');\\r\\n\\\r\n        }');\r\n if(data.sonicStatus != 0) {;_p('        /**\\r\\n\\\r\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\\r\\n\\\r\n         * @param sonicStatus\\r\\n\\\r\n         * @param reportSonicStatus\\r\\n\\\r\n         * @param sonicUpdateData\\r\\n\\\r\n         */\\r\\n\\\r\n        window.sonicStartTime = new Date;\\r\\n\\\r\n        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\\r\\n\\\r\n        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\\r\\n\\\r\n            if(sonicStatus == 1){\\r\\n\\\r\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\\r\\n\\\r\n            }else if(sonicStatus == 2){\\r\\n\\\r\n\\r\\n\\\r\n            }else if(sonicStatus == 3){\\r\\n\\\r\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\\r\\n\\\r\n                var html = \\'\\';\\r\\n\\\r\n                var id = \\'\\';\\r\\n\\\r\n                var elementObj = \\'\\';\\r\\n\\\r\n                for(var key in sonicUpdateData){\\r\\n\\\r\n                    id = key.substring(1,key.length-1);\\r\\n\\\r\n                    html = sonicUpdateData[key];\\r\\n\\\r\n                    elementObj = document.getElementById(id+\\'Content\\');\\r\\n\\\r\n                    elementObj.innerHTML = html;\\r\\n\\\r\n                }\\r\\n\\\r\n\\r\\n\\\r\n            }else if(sonicStatus == 4){\\r\\n\\\r\n\\r\\n\\\r\n            }\\r\\n\\\r\n            afterInit(reportSonicStatus);\\r\\n\\\r\n        });');\r\n } else {;_p('            afterInit(0);');\r\n };_p('    });\\r\\n\\\r\n\\r\\n\\\r\n</script>\\r\\n\\\r\n</body>\\r\\n\\\r\n</html>');\r\n\r\nreturn __p.join(\"\");\r\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/index.ejs",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <%- (require('./tpls/common_meta'))() %>\n    <title>sonic demo</title>\n    <%- (require('./tpls/common_header'))() %>\n</head>\n<body>\n<%- (require('./tpls/common_body_header'))() %>\n<ul class=\"ui-list ui-list-text\">\n\t<a href=\"/demo3?sonicStatus=1\"><li class=\"ui-arrowlink\">首次进入</li></a>\n\t<a href=\"/demo3?sonicStatus=2\"><li class=\"ui-arrowlink\">页面刷新</li></a>\n    <a href=\"/demo3?sonicStatus=3\"><li class=\"ui-arrowlink\">局部刷新</li></a>\n    <a href=\"/demo3?sonicStatus=4\"><li class=\"ui-arrowlink\">完全缓存</li></a>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "sonic-nodejs/assets/page/index.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<!doctype html>\\r\\n\\\n<html lang=\"en\">\\r\\n\\\n<head>');\n;_p( (require('./tpls/common_meta'))() );\n;_p('    <title>sonic demo</title>');\n;_p( (require('./tpls/common_header'))() );\n;_p('</head>\\r\\n\\\n<body>');\n;_p( (require('./tpls/common_body_header'))() );\n;_p('<ul class=\"ui-list ui-list-text\">\\r\\n\\\n\t<a href=\"/demo3?sonicStatus=1\"><li class=\"ui-arrowlink\">首次进入</li></a>\\r\\n\\\n\t<a href=\"/demo3?sonicStatus=2\"><li class=\"ui-arrowlink\">页面刷新</li></a>\\r\\n\\\n    <a href=\"/demo3?sonicStatus=3\"><li class=\"ui-arrowlink\">局部刷新</li></a>\\r\\n\\\n    <a href=\"/demo3?sonicStatus=4\"><li class=\"ui-arrowlink\">完全缓存</li></a>\\r\\n\\\n</ul>\\r\\n\\\n</body>\\r\\n\\\n</html>');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_body_header.ejs",
    "content": "<style>\n    body{padding-top:45px;}\n</style>\n<header class=\"ui-header ui-header-positive ui-border-b\">\n    <i class=\"ui-icon-return\" onclick=\"history.back()\"></i><h1>sonic demo</h1><button class=\"ui-btn\" onclick=\"location.reload()\">刷新</button>\n</header>"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_body_header.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<style>\\r\\n\\\n    body{padding-top:45px;}\\r\\n\\\n</style>\\r\\n\\\n<header class=\"ui-header ui-header-positive ui-border-b\">\\r\\n\\\n    <i class=\"ui-icon-return\" onclick=\"history.back()\"></i><h1>sonic demo</h1><button class=\"ui-btn\" onclick=\"location.reload()\">刷新</button>\\r\\n\\\n</header>');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_header.ejs",
    "content": "<link rel=\"stylesheet\" href=\"http://frozenui.github.io/frozenui/css/frozen.css\">"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_header.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<link rel=\"stylesheet\" href=\"http://frozenui.github.io/frozenui/css/frozen.css\">');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_meta.ejs",
    "content": "<meta charset=\"utf-8\">\n<meta name=\"format-detection\" content=\"telephone=no\"/>\n<meta http-equiv=\"x-dns-prefetch-control\" content=\"on\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,user-scalable=no\"/>\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\"/>"
  },
  {
    "path": "sonic-nodejs/assets/page/tpls/common_meta.js",
    "content": ";(function(){var __a={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'},\n__b=/[&<>\"']/g,\n__e=function (s) {s = String(s);return s.replace(__b, function (m) {return __a[m]});};\n\nmodule.exports = function (data, children) {\ndata=typeof data != \"undefined\"?data:{},children= typeof children != \"undefined\"?children:{};\nvar __p=[],_p=function(s){__p.push(s)};\n;_p('<meta charset=\"utf-8\">\\r\\n\\\n<meta name=\"format-detection\" content=\"telephone=no\"/>\\r\\n\\\n<meta http-equiv=\"x-dns-prefetch-control\" content=\"on\">\\r\\n\\\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,user-scalable=no\"/>\\r\\n\\\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\"/>\\r\\n\\\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\"/>');\n\nreturn __p.join(\"\");\n};})();"
  },
  {
    "path": "sonic-nodejs/assets/project.config.js",
    "content": "let path = require('path');\nmodule.exports = {\n    build: {\n        ejs2js: path.resolve(__dirname, './page') //构建ejs2js的范围\n    }\n};"
  },
  {
    "path": "sonic-nodejs/common/diff.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * Licensed under the BSD 3-Clause License (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst crypto = require('crypto');\n\nmodule.exports = function (ctx, buffer, {'sonic-etag-key': sonicEtagKey = 'Etag'}) {\n\tlet etag = ctx.get('if-none-match');\n\tlet now = Date.now();\n\tlet md5 = crypto.createHash('sha1').update(buffer).digest('hex');\n\n\tconsole.info(`请求头etag = ${etag}`);\n\tconsole.info(`页面md5 = ${md5}`);\n\n\t//sonicMode含义\n\t// 0-非sonic（没有sonicdiff标签）\n\t// 1-首次加载（本地无模板和数据）\n\t// 2-页面刷新（模板有变）\n\t// 3-局部数据刷新（模板不变，数据有变）\n\t// 4-完成缓存304（模板不变，数据不变）\n\tif (etag && md5 == etag) {\n\t\tctx.set('Cache-Offline', 'store');\n\t\tctx.set('Content-Length', 0);\n\t\tctx.status = 304;\n\t\tctx.sonicMode = 4;\n\t\treturn {\n\t\t\tcache: true\n\t\t}\n\t} else {\n\t\tlet htmlStr = buffer.toString('utf8');\n\t\t//替换 &&提取　title，body\n\t\tlet title = \"\";\n\n\t\tlet now2 = Date.now();\n\t\tlet templateHtml = htmlStr.replace(/<title(.*?)<\\/title>/i, function (titleHtml) {\n\t\t\ttitle = titleHtml;\n\t\t\treturn \"{title}\";\n\t\t});\n\t\t//判断是否成功替换wnsdiffbody\n\t\tlet flag = false;\n\n\t\tlet tagIndex = 0, tagPrefix = 'auto';\n\n\t\tlet diffTagNames = {};\n\n\t\ttemplateHtml = templateHtml.replace(/<!--sonicdiff-?(\\w*)-->([\\s\\S]+?)<!--sonicdiff-?(\\w*)-end-->/ig, function (diffhtml, tagName) {\n\t\t\tflag = true;\n\t\t\tif (!tagName) {\n\t\t\t\ttagName = tagPrefix + tagIndex++;\n\t\t\t}\n\n\t\t\tdiffTagNames[tagName] = diffhtml;\n\n\t\t\treturn '{' + tagName + '}';\n\t\t});\n\n\t\tconsole.info(`获取sonic diff耗时${Date.now() - now2}`);\n\n\t\tlet now3 = Date.now();\n\n\t\tlet templateMd5 = crypto.createHash('sha1').update(new Buffer(templateHtml)).digest('hex');\n\n\t\tconsole.info(`获取sonic diff耗时${Date.now() - now3}`);\n        ctx.set('sonic-etag-key', sonicEtagKey);\n\t\tctx.set(sonicEtagKey, md5);\n\t\tctx.set('template-tag', templateMd5);\n\n\t\tctx.set('Cache-Offline', true);\n\n\t\tif (flag) {\n\t\t\tlet templateTag = ctx.get('template-tag');\n\t\t\tif (templateMd5 == templateTag) {\n\t\t\t\tctx.set('template-change', 'false');\n\n\t\t\t\tlet result = {\n\t\t\t\t\t'data': {\n\t\t\t\t\t\t'{title}': title\n\t\t\t\t\t},\n\t\t\t\t\t'diff': '',\n\t\t\t\t\t'html-sha1': md5,\n\t\t\t\t\t\"template-tag\": templateMd5\n\t\t\t\t};\n\n\t\t\t\tObject.keys(diffTagNames).forEach(v => {\n\t\t\t\t\tresult['data']['{' + v + '}'] = diffTagNames[v];\n\t\t\t\t});\n\n\t\t\t\tconsole.info(`数据更新耗时${Date.now() - now}`);\n\n\t\t\t\tctx.sonicMode = 3;\n\n\t\t\t\treturn {\n\t\t\t\t\tdata: new Buffer(JSON.stringify(result))\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tctx.set('template-change', 'true');\n\n\t\t\t\tctx.sonicMode = templateTag ? 2 : 1;\n\n\t\t\t\tconsole.info(`模版更新耗时${Date.now() - now}`);\n\n\t\t\t\treturn {\n\t\t\t\t\tdata: new Buffer(htmlStr)\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tctx.set('template-change', 'true');\n\n\t\t\tctx.sonicMode = 0;\n\n\t\t\treturn {\n\t\t\t\tdata: new Buffer(htmlStr)\n\t\t\t}\n\t\t}\n\t}\n};"
  },
  {
    "path": "sonic-nodejs/middleware/compress.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst stream = require('stream');\nconst isJSON = require('koa-is-json');\nconst differ = require('sonic_differ');\nconst zlib = require('zlib');\nconst method = {\n\tgzip: zlib.createGzip,\n\tdeflate: zlib.createDeflate\n};\n\nmodule.exports = () => {\n\treturn async function (ctx, next) {\n\t\tawait next();\n\t\tlet body = ctx.body;\n\n\t\tif (!body) return;\n\n\t\tif (isJSON(body)) body = ctx.body = JSON.stringify(body);\n\t\tlet encoding = ctx.acceptsEncodings('gzip', 'deflate', 'identity');\n\t\tif (!encoding) ctx.throw(406, 'supported encodings: gzip, deflate, identity');\n\t\tif (encoding === 'identity') return;\n\t\tif (ctx.response.length < 2048) return;\n\n\t\tctx.set('Content-Encoding', encoding);\n\t\tctx.res.removeHeader('Content-Length');\n\n\t\tlet zip = ctx.body = method[encoding]({\n\t\t\tflush: require('zlib').Z_SYNC_FLUSH\n\t\t});\n\n\t\tzip.on('error', err => {\n\t\t\tconsole.info(err)\n\t\t});\n\n\t\tzip.on('finish', () => {\n\t\t\tconsole.info('zip succ')\n\t\t});\n\n\t\tlet sonic = {\n\t\t\tbuffer: [],\n\t\t\twrite: function (chunk, encoding) {\n\t\t\t\tlet buffer = chunk;\n\t\t\t\tlet ecode = encoding || 'utf8';\n\t\t\t\tif (!Buffer.isBuffer(chunk)) {\n\t\t\t\t\tbuffer = new Buffer(chunk, ecode);\n\t\t\t\t}\n\t\t\t\tsonic.buffer.push(buffer);\n\t\t\t}\n\t\t};\n\n\t\tfunction getDiff() {\n\t\t\tconsole.info('sonic 开始拦截返回数据');\n\t\t\tbody.on('data', (chunk, encoding) => {\n\t\t\t\tsonic.write(chunk, encoding)\n\t\t\t});\n\n\t\t\tbody.on('end', () => {\n\t\t\t\tlet result = differ(ctx, Buffer.concat(sonic.buffer));\n\t\t\t\tsonic.buffer = [];\n\t\t\t\tif (result.cache) {\n\t\t\t\t\tconsole.info('sonic 完全cache');\n\t\t\t\t\tzip.end()\n\t\t\t\t} else {\n\t\t\t\t\tconsole.info('sonic 非缓存模式');\n\t\t\t\t\tzip.end(result.data)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\ttry {\n\t\t\tbody instanceof stream ? ctx.get('accept-diff') ? getDiff() : body.pipe(zip) : zip.end(body);\n\t\t} catch (e) {\n\t\t\tconsole.info('zip error');\n\t\t\tconsole.error(e)\n\t\t}\n\t}\n};"
  },
  {
    "path": "sonic-nodejs/package.json",
    "content": "{\n  \"name\": \"koa-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"sonic demo with koa\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"sonic\"\n  ],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"sonic_differ\": \"^1.0.0\",\n    \"koa\": \"^2.2.0\",\n    \"koa-is-json\": \"^1.0.0\",\n    \"pm2\": \"^2.4.6\",\n    \"through2\": \"^2.0.3\"\n  }\n}\n"
  },
  {
    "path": "sonic-nodejs/router/config.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst path = require('path');\nmodule.exports = {\n\t'/': {\n\t\ttemplate: path.resolve(__dirname, '../assets/page/index.js')\n\t},\n\t'/demo1': {\n\t\ttemplate: path.resolve(__dirname, '../assets/page/demo1.js')\n\t},\n\t'/demo2': {\n\t\ttemplate: path.resolve(__dirname, '../assets/page/demo2.js'),\n\t\tdata: path.resolve(__dirname, '../assets/page/demo2-data.js')\n\t},\n\t'/demo3': {\n\t\ttemplate: path.resolve(__dirname, '../assets/page/demo3.js'),\n\t\tdata: path.resolve(__dirname, '../assets/page/demo3-data.js')\n\t}\n};"
  },
  {
    "path": "sonic-nodejs/router/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst routerConfig = require('./config');\nconst through2 = require('through2');\nmodule.exports = () => {\n\treturn async function (ctx, next) {\n\t\tlet pathname = (ctx.request.url || '').split('?')[0];\n\t\tif (routerConfig[pathname]) {\n\t\t\tconsole.log(routerConfig[pathname]);\n\t\t\ttry {\n\t\t\t\tlet tpl = require(routerConfig[pathname].template), data = {};\n\t\t\t\tif (routerConfig[pathname].data) {\n\t\t\t\t\tlet dataFn = require(routerConfig[pathname].data);\n\t\t\t\t\tdata = dataFn(ctx) || {};\n\t\t\t\t}\n\t\t\t\tctx.body = through2();\n\t\t\t\tctx.type = 'html';\n\t\t\t\tctx.body.end(tpl(data));\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(e);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log('路由未配置', pathname);\n\t\t}\n\t}\n};"
  },
  {
    "path": "sonic-php/README.md",
    "content": "## Getting started with PHP\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\n---\n\n## How to use for Server\nDownload and import ```sonic.php```. \n```PHP\nrequire_once(PATH.\"/sonic.php\");\n```\nThen add following code.\n\n```\nif (isset($_GET['sonic']) && $_GET['sonic'] == '1') {\n// Check if Sonic is needed or not \n    util_sonic::start();\n    $this->_index_v5($uin);\n    util_sonic::end();\n}\n```\n\n## How to use for front-end\nHere is a simple demo shows how to use Sonic for front-end.\n```Html\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n    <title>demo</title>\n    <script type=\"text/javascript\">\n            \n            // Interacts with mobile client by JavaScript interface to get Sonic diff data.\n            function getDiffData(){\n                window.sonic.getDiffData();\n            }\n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.   \n           function getDiffDataCallback(result){\n                var sonicStatus = 0; \n                /**\n                * The Sonic status:\n                * 0: It fails to get any data from mobile client.\n                * 1: It is first time for mobile client to use Sonic.\n                * 2: Mobile client reload the whole websites.\n                * 3: Websites will be updated dynamically with local refresh.\n                * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\n                */\n                sonicUpdateData = {}; //sonic diff data\n                var result = JSON.parse(result);\n                if(result['code'] == 200){\n                    sonicStatus = 3;\n                    sonicUpdateData = JSON.parse(result['result']);\n                } else if (result['code'] == 1000) {\n                    sonicStatus = 1;\n                } else if (result['code'] == 2000) {\n                    sonicStatus = 2;\n                } else if(result['code'] == 304) {\n                    sonicStatus = 4;\n                }\n                handleSonicDiffData(sonicStatus, sonicUpdateData);\n            }\n            // step 3: Handle the response from mobile client which include Sonic response code and diff data.  \n            function handleSonicDiffData(sonicStatus, sonicUpdateData){\n                if(sonicStatus == 3){\n                    //Websites will be updated dynamically and run some JavaScript while in local refresh mode. \n                    var html = '';\n                    var id = '';\n                    var elementObj = '';\n                    for(var key in sonicUpdateData){\n                        id = key.substring(1,key.length-1);\n                        html = sonicUpdateData[key];\n                        elementObj = document.getElementById(id+'Content');\n                        elementObj.innerHTML = html;\n                    }\n                }\n            }\n    </script>\n</head>\n<body>\n    // step 1: specify template and data by inserting different comment anchor.\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n    \n    // step 2: Receives diff data from mobile client through Javascript interface.\n    <script type=\"text/javascript\">\n        window.onload = function(){\n            getDiffData();\n        }\n    </script>\n</body>\n</html>\n```\n### Step 1:\nSpecify template and data by inserting different comment anchor. The data will be wrapped with anchor ```<!-- sonicdiff-moduleName -->```  ```<!-- sonicdiff-moduleName-end -->```. The other part of html is template.\n```Html\n    <div id=\"data1Content\">\n        <!--sonicdiff-data1-->\n        <p id=\"partialRefresh\"></p>\n        <!--sonicdiff-data1-end-->\n    </div>\n    <div id=\"data2Content\">\n        <!--sonicdiff-data2-->\n        <p id=\"data2\">here is the data</p>\n        <!--sonicdiff-data2-end-->\n        <p id=\"pageRefresh\"></p>\n    </div>\n    <div id = \"data3\">data3</div>\n```\n\n### Step 2:\nReceives 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.\n```Html\n<script type=\"text/javascript\">\n    window.onload = function(){\n        getDiffData();\n    }\n</script>\n```\n\n### Step 3:\nHandle 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.\n```Html\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction getDiffDataCallback(result){\n｝\n//step 3 Handle the response from mobile client which include Sonic response code and diff data.  \nfunction handleSonicDiffData(sonicStatus, sonicUpdateData){\n｝\n```\n\n## Support\nAny problem?\n\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-php/sample).\n2. Contact us for help.\n\n## License\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\n\n[1]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120005424.gif\n[2]: https://github.com/Tencent/VasSonic/blob/master/article/20170705120029897.gif\n\n\n"
  },
  {
    "path": "sonic-php/sample/README.md",
    "content": "将sample放在php的web目录\n访问入口localhost/sample/index.php"
  },
  {
    "path": "sonic-php/sample/controller/demo.php",
    "content": "<?php\n/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n\n * sonic demo控制器\n * @author owenlai\n *\n */\nclass controller_demo\n{\n    public function actionIndex(){\n        /**\n         * 构造随机sonic状态 begin\n         */\n        $headers = getallheaders();\n        $dataImg = 1;\n        $templateFlag = 1;\n        $sonicStatusMap = array(\n            'templateChange' => 2,\n            'dataUpdate' => 3,\n            'cache' => 4\n        );\n        $sonicStatus = 0; //1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n        if (isset($headers['accept-diff']) && $headers['accept-diff'] == 'true') {\n            if (isset($headers['template-tag']) && !empty($headers['template-tag'])) { //有缓存的情况随机局部刷新、模板变更、完全缓存\n                $sonicStatusRand = array(3,3,3,3,3,4,4,2,4,4,4);\n                $sonicStatus = isset($_GET['sonicStatus']) && in_array($_GET['sonicStatus'], array_keys($sonicStatusMap))\n                    ? $sonicStatusMap[$_GET['sonicStatus']] : $sonicStatusRand[array_rand($sonicStatusRand)];\n                switch($sonicStatus) {\n                    case 2: //模板变更 数据不变 改模板\n                        if (isset($_COOKIE['dataImg'])) {\n                            $dataImg = $_COOKIE['dataImg'];\n                        }\n                        if (isset($_COOKIE['templateFlag'])) {\n                            $templateFlag = !$_COOKIE['templateFlag'];\n                        }\n                        break;\n                    case 3://局部刷新 数据变 模板不变\n                        if (isset($_COOKIE['dataImg'])) {\n                            $dataImg = !$_COOKIE['dataImg'];\n                        }\n                        if (isset($_COOKIE['templateFlag'])) {\n                            $templateFlag = $templateFlag;\n                        }\n                        break;\n                    case 4:\n                        if (isset($_COOKIE['dataImg'])) {\n                            $dataImg = $_COOKIE['dataImg'];\n                        }\n                        if (isset($_COOKIE['templateFlag'])) {\n                            $templateFlag = $_COOKIE['templateFlag'];\n                        }\n                        break;\n                }\n            } else { //首次\n                $sonicStatus = 1;\n            }\n        }\n        setcookie('dataImg', intval($dataImg));\n        setcookie('templateFlag',intval($templateFlag));\n        /**\n         * 构造随机sonic状态 end\n         */\n        /**\n         * 模拟后台耗时操作 begin\n         */\n        sleep(1);\n        /**\n         * 模拟后台耗时操作 end\n         */\n        require_once 'util/sonic.php';\n        util_sonic::start();\n        require 'view/demo_template.php';\n        util_sonic::end();\n    }\n}\n"
  },
  {
    "path": "sonic-php/sample/index.php",
    "content": "<?php\n/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\nif (!function_exists('getallheaders'))  {\n    function getallheaders()\n    {\n        if (!is_array($_SERVER)) {\n            return array();\n        }\n        $headers = array();\n        foreach ($_SERVER as $name => $value) {\n            if (substr($name, 0, 5) == 'HTTP_') {\n                $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value;\n            }\n        }\n        return $headers;\n    }\n}\nrequire_once 'controller/demo.php';\n$demo = new controller_demo();\n$demo->actionIndex();"
  },
  {
    "path": "sonic-php/sample/js/sonic-3.js",
    "content": "/**\n *\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n *\n * @作者 craigchen\n * @版本 2.0.0\n *  sonic前端JS类库\n */\n;(function(){\n    function getSonicData(callback) {\n        var sonicStatus = 0, //sonic状态 0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n            reportSonicStatus = 0, //sonic上报状态\n            sonicHadExecute = 0, //sonic执行标志位\n            sonicUpdateData = {}; //sonic diff数据\n\n        window.sonic && window.sonic.getDiffData(); //执行sonicdiff\n        window['getDiffDataCallback'] = function (diffData) {\n            try{\n                var result = JSON.parse(diffData);\n            } catch (e) {}\n            if(result['code'] == 200){\n                reportSonicStatus = sonicStatus = 3;\n                sonicUpdateData = JSON.parse(result['result']);\n                //页面完全没有变化\n            } else if (result['code'] == 1000) {\n                reportSonicStatus = sonicStatus = 1;\n            } else if (result['code'] == 2000) {\n                reportSonicStatus = sonicStatus = 2;\n            } else if(result['code'] == 304) {\n                sonicStatus = 4;\n                switch(parseInt(result['srcCode'])) { //上报状态处理\n                    case 304:\n                        reportSonicStatus = 4;\n                        break;\n                    case 200: //局部刷新也可能返回304 但srcCode是200，当返回的局部数据足够快，终端会组装好页面返回304\n                        reportSonicStatus = 3;\n                        break;\n                    case 1000:\n                        reportSonicStatus = 1;\n                        break;\n                    case 2000:\n                        reportSonicStatus = 2;\n                        break;\n                    default:\n                        reportSonicStatus = sonicStatus;\n                }\n            }\n            if (sonicHadExecute == 0) {\n                callback(sonicStatus, reportSonicStatus, sonicUpdateData);\n                sonicHadExecute = 1;\n            }\n        }\n        /**\n         * sonic超时处理 默认5s\n         */\n        setTimeout(function(){\n            if(sonicHadExecute == 0){\n                sonicHadExecute = 1;\n                callback(sonicStatus, reportSonicStatus, sonicUpdateData);\n            }\n        }, 5000);\n    }\n    if (typeof module !== 'undefined' && typeof exports === 'object') {\n        module.exports = getSonicData;\n    } else if (typeof define === 'function') {\n        define(\"lib/sonic/sonic\",[], function(require, exports){ exports.getSonicData = getSonicData; });\n    } else if (typeof define === 'function' && define.amd) {\n        define(function() { return getSonicData; });\n    } else {\n        this.moduleName = getSonicData;\n    }\n}).call(function() {\n    return this || (typeof window !== 'undefined' ? window : global);\n});"
  },
  {
    "path": "sonic-php/sample/util/sonic.php",
    "content": "<?php\n/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n\n * sonic插件\n * 在所有controller中都可以调用sonic插件\n * @author shawnlzhang\n * @time 2017.03.24\n *\n */\nif (!function_exists('getallheaders'))  {\n    function getallheaders()\n    {\n        if (!is_array($_SERVER)) {\n            return array();\n        }\n        $headers = array();\n        foreach ($_SERVER as $name => $value) {\n            if (substr($name, 0, 5) == 'HTTP_') {\n                $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value;\n            }\n        }\n        return $headers;\n    }\n}\nclass TemplateReplace{\n    public static $shotWnsDiffBodyReplace = false; //判断是否成功替换sonicdiffbody\n    public static $diffIndex = 0; \n    public static $tagPrefix = 'auto';\n    public static $diffTagNames = array(); //数据块\n\n    public function callback($matches) {\n        if(isset($matches) && isset($matches[0])) {\n            self::$shotWnsDiffBodyReplace = true;\n            if(isset($matches[1])) {\n                $tagName = $matches[1];\n            } else {\n                $tagName = self::$tagPrefix.self::$diffIndex++;\n            }\n            self::$diffTagNames[$tagName] = $matches[0];\n\n            return '{'.$tagName.'}';\n        }\n    }\n}\nclass util_sonic {\n\tpublic static function start(){\n\t\tob_start();\n        $_SERVER['PHP_SONIC'] = '1';\n\t}\n\n    public static function end() {\n\t\t$outContent = ob_get_clean();\n    \t$headers = getallheaders();\n\n        if(isset($headers['accept-diff']) && $headers['accept-diff'] === 'true'){\n            header('Cache-Control: no-cache');\n\n            $offline = 'true';\n            header(\"Cache-Offline: $offline\");\n\n            $Etag = NULL;\n            if(isset($headers['if-none-match']) || isset($headers['If-None-Match'])){\n                $Etag = isset($headers['if-none-match']) ? $headers['if-none-match'] : $headers['If-None-Match'];\n            }\n\n            //offline值需要进入离线\n            if(isset($offline) && $offline !== 'false'){\n                //取响应内容的md5\n                $md5 = sha1($outContent);\n                //304命中离线缓存\n                if($Etag === $md5) {\n                    header('Cache-Offline: store');\n                    header('Content-Length: 0');\n                    header('HTTP/1.1 304 Not Modified');\n                    exit;\n                }\n                header('Etag: '.$md5);\n            }\n            $outContent = self::wnsHtmlDiffDivision($outContent);\n            header('Content-Length:'.strlen($outContent));\n\n        }\n        echo $outContent;\n    }\n\n    public static function wnsHtmlDiffDivision($htmlStr){\n        $htmlMd5 = sha1($htmlStr);\n\n        $headers = getallheaders();\n        $clientTemplateTag = NULL;\n        if(isset($headers['template-tag'])){\n            $clientTemplateTag = $headers['template-tag'];\n        }\n        \n        preg_match('/<title(.*?)<\\/title>/i', $htmlStr, $titleMatchs);\n        $title = '';\n        if(isset($titleMatchs[0])) {\n           $title = $titleMatchs[0];\n        }\n        $templateHtml = preg_replace('/<title(.*?)<\\/title>/i', '{title}', $htmlStr);\n        $templateReplace = new TemplateReplace();\n        $templateHtml = preg_replace_callback('/<!--sonicdiff-?(\\w*)-->[\\s\\S]+?<!--sonicdiff-?\\w*-end-->/i', array($templateReplace, 'callback'),$templateHtml);\n\n        //转换模板为buffer，再获取模板md5，作为template-tag\n        $templateMd5 = sha1($templateHtml);\n        //加个头，告诉客户端，我是一个diff结构的响应\n        //var_dump($clientTemplateTag, $templateMd5); exit;\n        header('template-tag: '.$templateMd5);\n\n        //结构化数据\n        $result = array(\n            'data' =>array(),\n            'template-tag' => $templateMd5\n        );\n        $result['data']['{title}'] = $title;\n        // 设置数据块数据\n        $diffTagNames = TemplateReplace::$diffTagNames;\n        foreach($diffTagNames as $i => $diffTagName) {\n            if(isset($diffTagNames[$i])) {\n                $result['data']['{'.$i.'}'] = $diffTagNames[$i];\n            }\n        }\n        $result['html-sha1'] = $htmlMd5;\n\n        $resultStr = '';\n        if($templateMd5 === $clientTemplateTag){\n            header('template-change: false');\n            //离线模板没有差异，不用更新\n            $result['diff'] = '';\n            $resultStr =  json_encode($result);\n        } else {\n            if($templateMd5 != $clientTemplateTag){\n                header('template-change: true');\n            }\n            \n            //客户端没有带离线版本，直接全量即可\n            $resultStr = $htmlStr;\n        }\n\n        return $resultStr;\n    }\n\t\n}"
  },
  {
    "path": "sonic-php/sample/view/demo_template.php",
    "content": "<!--\n    Tencent is pleased to support the open source community by making VasSonic available.\n    Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n    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\n    https://opensource.org/licenses/BSD-3-Clause\n    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.\n-->\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <script type=\"application/javascript\">\n        var _pageTime = {};\n        _pageTime.startTime = new Date;\n    </script>\n    <title>SONIC</title>\n    <style>\n        body {\n            margin: 0;\n            padding: 0;\n            font-size: 14px;\n            color: #777;\n            margin-top: 20px;\n        }\n        .sonic-wrapper {\n            padding: 0 12px;\n        }\n        .sonic-wrapper h1 {\n            font-size: 18px;\n            font-weight: 400;\n            color: #000;\n        }\n        .sonic-wrapper h2 {\n            font-size: 14px;\n            color: #000;\n        }\n        .sonic-wrapper p {\n            font-size: 14px;\n            color: #777;\n            line-height: 1.6em;\n        }\n        .sonic-wrapper img {\n            width: 100%;\n        }\n        .sonic-wrapper table {\n            width: 100%;\n        }\n        .sonic-wrapper table img {\n            width: 100%;\n        }\n        .sonic_des {display:none;}\n    </style>\n</head>\n<body>\n<div class=\"sonic-wrapper\">\n    <h1>Sonic：轻量级的高性能的Hybrid框架</h1>\n    <p>Sonic是腾讯QQ会员团队研发的一个轻量级的高性能的Hybrid框架，专注于提升H5页面首屏加载速度，让H5页面的体验更加接近原生，提升用户体验及用户留存率。</p>\n    <span id=\"data1Content\">\n    <!--sonicdiff-data1-->\n    <p>示例：</p>\n    <img src=\"//mc.vip.qq.com/img/img-<?php echo intval($dataImg)?>.png?max_age=2592000\" alt=\"\">\n    <!--sonicdiff-data1-end-->\n    </span>\n    <span id=\"des0\" class=\"sonic_des\">\n        <h2>非Sonic模式 点击到页面打开耗时:<span id=\"pageTime0\"></span></h2>\n        <p>普通直出的方式</p>\n    </span>\n    <span id=\"des1\" class=\"sonic_des\">\n        <h2>首次访问 点击到页面打开耗时:<span id=\"pageTime1\"></span></h2>\n        <p>用户第一次访问，本地无缓存;使用直出的方式，终端生成缓存。</p>\n    </span>\n    <span id=\"des2\" class=\"sonic_des\">\n        <h2>模版更新 点击到页面打开耗时:<span id=\"pageTime2\"></span></h2>\n        <p>本地模版跟服务器模版不一样;缓存失效，清除缓存，重新加载页面。</p>\n    </span>\n    <span id=\"des3\" class=\"sonic_des\">\n        <h2>数据更新 点击到页面打开耗时:<span id=\"pageTime3\"></span></h2>\n        <p>模板一致，数据变更;针对页面局部数据变化的场景，Sonic会预先加载本地缓存再将变化部分的数据异步更新，提升用户体验。</p>\n    </span>\n    <span id=\"des4\" class=\"sonic_des\">\n        <h2>完全缓存 点击到页面打开耗时:<span id=\"pageTime4\"></span></h2>\n        <p>本地数据与服务器数据完全一样;直接使用缓存，页面秒开。</p>\n    </span>\n    <?php if($templateFlag){?>\n    <h2>页面打开速度效果对比</h2>\n    <p>以手机QQ-VIP中心首页为例，在接入Sonic框架之后，页面打开速度在数据更新场景下优化提升42%，页面内容不变的场景下(完全cache模式)优化提升50%以上。</p>\n\n    <table>\n        <tr>\n            <td>原有直出页面：</td>\n            <td>Sonic改造页面：</td>\n        </tr>\n        <tr>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049810_nosonic.gif?max_age=2592000\" alt=\"\"></td>\n            <td><img src=\"//imgcache.gtimg.cn/ACT/svip_act/act_img/public/201707/1499049823_sonic.gif?max_age=2592000\" alt=\"\"></td>\n        </tr>\n    </table>\n    <?php }?>\n    <h2>Sonic实现原理简介</h2>\n    <p>Sonic框架使用终端应用层原生传输通道取代系统浏览器内核自身资源传输通道来请求页面主资源，在移动终端初始化的同时并行请求页面主资源并做到流式拦截，减少传统方案上终端初始化耗时长导致页面主资源发起请求时机慢或传统并行方案下必须等待主资源完成下载才能交给内核加载的影响。另外通过客户端和服务器端双方遵守Sonic格式规范(通过在html内增加注释代码区分模板和数据)，该框架能做到智能地对页面内容进行动态缓存和增量更新，减少对网络的依赖，节省用户流量，加快页面打开速度。</p>\n</div>\n<script>\n    _pageTime.jsendtTime = new Date();\n</script>\n<script src=\"//open.mobile.qq.com/sdk/qqapi.js?_bid=152\"></script>\n<script src=\"//imgcache.gtimg.cn/club/platform/lib/seajs/sea-with-plugin-2.2.1.js?_bid=250&max_age=2592000\" id=\"seajsnode\"></script>\n<script>\n    seajs.config({\n        base: location.protocol+'//imgcache.gtimg.cn/club/platform/examples/',\n        localcache:{\n            //浏览器缓存时间\n            maxAge: 2592000,\n            openLocalStorageCache: 0\n        },\n        maxFile : {\n\n        },\n        debug:1,\n        //别名\n        alias:{\n            'zepto': 'lib/zepto/zepto'\n        },\n        paths:{\n            'lib' : location.protocol+'//imgcache.gtimg.cn/club/platform/lib'\n        },\n        manifest:{\n            \"lib/zepto/zepto\": \"1.1.3\",\n            \"lib/sonic/sonic\": \"3-1\"\n        }\n    });\n\n    seajs.use([\"zepto\", \"lib/sonic/sonic\"],function($, sonic){\n        /**\n         * 后置函数 sonic或普通模式 执行页面初始化等操作\n         */\n        function afterInit(sonicStatus){\n            $('.sonic_des').css('display', 'none');\n            $('#des'+sonicStatus).css('display', 'block');\n            //耗时分析(上报)\n            var performanceJson;\n            if (window.sonic && window.sonic.getPerformance) {\n                performanceJson = JSON.parse(window.sonic.getPerformance());//clickTime;loadUrlTime\n            } else if (window.performance && window.performance.timing) {\n                performanceJson = {clickTime: window.performance.timing.navigationStart, loadUrlTime: window.performance.timing.fetchStart};\n            } else {\n                performanceJson = {clickTime: 0, loadUrlTime: 0};\n            }\n            var pageTime = _pageTime.jsendtTime - performanceJson.clickTime;\n            $(\"#pageTime\"+sonicStatus).text(pageTime+'ms');\n        }\n        <?php if($sonicStatus != 0) {?>\n        /**\n         * sonic业务逻辑 diff数据处理，后置函数执行，状态上报\n         * @param sonicStatus\n         * @param reportSonicStatus\n         * @param sonicUpdateData\n         */\n        window.sonicStartTime = new Date;\n        //0-状态获取失败 1-sonic首次 2-页面刷新 3-局部刷新 4-完全cache\n        sonic.getSonicData(function(sonicStatus, reportSonicStatus, sonicUpdateData){\n            if(sonicStatus == 1){\n                //首次没有特殊的逻辑处理，直接执行sonic完成后的逻辑，比如上报等\n            }else if(sonicStatus == 2){\n\n            }else if(sonicStatus == 3){\n                //局部刷新的时候需要更新页面的数据块和一些JS操作\n                var html = '';\n                var id = '';\n                var elementObj = '';\n                for(var key in sonicUpdateData){\n                    id = key.substring(1,key.length-1);\n                    html = sonicUpdateData[key];\n                    elementObj = document.getElementById(id+'Content');\n                    elementObj.innerHTML = html;\n                }\n\n            }else if(sonicStatus == 4){\n\n            }\n            afterInit(reportSonicStatus);\n        });\n        <?php } else {?>\n            afterInit(0);\n        <?php }?>\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "sonic-php/sdk/sonic.php",
    "content": "<?php\n/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n * sonic插件\n * 在所有controller中都可以调用sonic插件\n * @author shawnlzhang\n * @time 2017.03.24\n *\n */\nif (!function_exists('getallheaders'))  {\n    function getallheaders()\n    {\n        if (!is_array($_SERVER)) {\n            return array();\n        }\n        $headers = array();\n        foreach ($_SERVER as $name => $value) {\n            if (substr($name, 0, 5) == 'HTTP_') {\n                $headers[str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($name, 5))))] = $value;\n            }\n        }\n        return $headers;\n    }\n}\nclass TemplateReplace{\n    public static $shotWnsDiffBodyReplace = false; //判断是否成功替换sonicdiffbody\n    public static $diffIndex = 0; \n    public static $tagPrefix = 'auto';\n    public static $diffTagNames = array(); //数据块\n\n    public function callback($matches) {\n        if(isset($matches) && isset($matches[0])) {\n            self::$shotWnsDiffBodyReplace = true;\n            if(isset($matches[1])) {\n                $tagName = $matches[1];\n            } else {\n                $tagName = self::$tagPrefix.self::$diffIndex++;\n            }\n            self::$diffTagNames[$tagName] = $matches[0];\n\n            return '{'.$tagName.'}';\n        }\n    }\n}\nclass util_sonic {\n\tpublic static function start(){\n\t\tob_start();\n        $_SERVER['PHP_SONIC'] = '1';\n\t}\n\n    public static function end() {\n\t\t$outContent = ob_get_clean();\n    \t$headers = getallheaders();\n\n        if(isset($headers['accept-diff']) && $headers['accept-diff'] === 'true'){\n            header('Cache-Control: no-cache');\n\n            $offline = 'true';\n            header(\"Cache-Offline: $offline\");\n\n            $Etag = NULL;\n            if(isset($headers['if-none-match']) || isset($headers['If-None-Match'])){\n                $Etag = isset($headers['if-none-match']) ? $headers['if-none-match'] : $headers['If-None-Match'];\n            }\n\n            //offline值需要进入离线\n            if(isset($offline) && $offline !== 'false'){\n                //取响应内容的md5\n                $md5 = sha1($outContent);\n                //304命中离线缓存\n                if($Etag === $md5) {\n                    header('Cache-Offline: store');\n                    header('Content-Length: 0');\n                    header('HTTP/1.1 304 Not Modified');\n                    exit;\n                }\n                header('Etag: '.$md5);\n            }\n            $outContent = self::wnsHtmlDiffDivision($outContent);\n            header('Content-Length:'.strlen($outContent));\n\n        }\n        echo $outContent;\n    }\n\n    public static function wnsHtmlDiffDivision($htmlStr){\n        $htmlMd5 = sha1($htmlStr);\n\n        $headers = getallheaders();\n        $clientTemplateTag = NULL;\n        if(isset($headers['template-tag'])){\n            $clientTemplateTag = $headers['template-tag'];\n        }\n        \n        preg_match('/<title(.*?)<\\/title>/i', $htmlStr, $titleMatchs);\n        $title = '';\n        if(isset($titleMatchs[0])) {\n           $title = $titleMatchs[0];\n        }\n        $templateHtml = preg_replace('/<title(.*?)<\\/title>/i', '{title}', $htmlStr);\n        $templateReplace = new TemplateReplace();\n        $templateHtml = preg_replace_callback('/<!--sonicdiff-?(\\w*)-->[\\s\\S]+?<!--sonicdiff-?\\w*-end-->/i', array($templateReplace, 'callback'),$templateHtml);\n\n        //转换模板为buffer，再获取模板md5，作为template-tag\n        $templateMd5 = sha1($templateHtml);\n        //加个头，告诉客户端，我是一个diff结构的响应\n        //var_dump($clientTemplateTag, $templateMd5); exit;\n        header('template-tag: '.$templateMd5);\n\n        //结构化数据\n        $result = array(\n            'data' =>array(),\n            'template-tag' => $templateMd5\n        );\n        $result['data']['{title}'] = $title;\n        // 设置数据块数据\n        $diffTagNames = TemplateReplace::$diffTagNames;\n        foreach($diffTagNames as $i => $diffTagName) {\n            if(isset($diffTagNames[$i])) {\n                $result['data']['{'.$i.'}'] = $diffTagNames[$i];\n            }\n        }\n        $result['html-sha1'] = $htmlMd5;\n\n        $resultStr = '';\n        if($templateMd5 === $clientTemplateTag){\n            header('template-change: false');\n            //离线模板没有差异，不用更新\n            $result['diff'] = '';\n            $resultStr =  json_encode($result);\n        } else {\n            if($templateMd5 != $clientTemplateTag){\n                header('template-change: true');\n            }\n            \n            //客户端没有带离线版本，直接全量即可\n            $resultStr = $htmlStr;\n        }\n\n        return $resultStr;\n    }\n\t\n}"
  },
  {
    "path": "sonic-react/README.md",
    "content": "## Getting started with React\r\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\r\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\r\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\r\n---\r\n\r\n## How to use the demo\r\n\r\n>This demo will give you a quick start for using Sonic with React.\r\n\r\n### Dependencies\r\nNode Version > 7.0\r\n### Installation\r\n```bash\r\ngit clone https://github.com/Tencent/VasSonic.git <my-project-name>\r\ncd <my-project-name>/sonic-react\r\nnpm install  # Install project dependencies\r\n```\r\n### Usage\r\n```bash\r\nnpm run build  # Builds the application to ./.next\r\nnpm start      # Start the development server\r\n```\r\nNow you can visit http://localhost:3000/demo to view this demo using Mobile Emulation Mode in Chrome dev tools.\r\n\r\n## How to use Sonic on server-side\r\n\r\n>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/).\r\n\r\n1. 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 `<!-- sonicdiff-moduleName -->` and close with `<!-- sonicdiff-moduleName-end -->`(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.\r\n\r\n- Below is the origin html, we will generate comment tags according to the `data-sonicdiff` attribute and the script block including `__NEXT_DATA__`:\r\n\r\n```HTML\r\n<!-- add comment tags to separate template and data blocks from the initial html -->\r\n<!DOCTYPE html>\r\n<html>\r\n  <head></head>\r\n  <body>\r\n    … …\r\n    <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">\r\n    … …\r\n    </div>\r\n    … …\r\n    <script>\r\n      __NEXT_DATA__=xxx\r\n    </script>\r\n  </body>\r\n</html>\r\n```\r\n\r\n- Then, we have a transform function at server side:\r\n\r\n```js\r\nfunction formatHtml(html) {\r\n    const $ = cheerio.load(html);\r\n    $('*[data-sonicdiff]').each(function(index, element) {\r\n        let tagName = $(this).data('sonicdiff');\r\n        return $(this).replaceWith('<!--sonicdiff-' + tagName + '-->' + $(this).clone() + '<!--sonicdiff-' + tagName + '-end-->');\r\n    });\r\n    html = $.html();\r\n    html = html.replace(/<script\\s*>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)<\\/script>/ig, function(data1) {\r\n        return '<!--sonicdiff-initState-->' + data1 + '<!--sonicdiff-initState-end-->';\r\n    });\r\n    return html;\r\n}\r\n```\r\n- After the transform, the latest code user will received will be like:\r\n\r\n```HTML\r\n<!-- add comment tags to separate template and data blocks from the initial html -->\r\n<!DOCTYPE html>\r\n<html>\r\n  <head></head>\r\n  <body>\r\n    … …\r\n+   <!-- sonicdiff-firstScreenHtml -->\r\n    <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">\r\n    … …\r\n    </div>\r\n+   <!-- sonicdiff-firstScreenHtml-end -->\r\n    … …\r\n+   <!-- sonicdiff-initState -->\r\n    <script>\r\n      __NEXT_DATA__=xxx\r\n    </script>\r\n+   <!-- sonicdiff-initState-end -->\r\n  </body>\r\n</html>\r\n```\r\n\r\n2. 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.\r\n\r\n```js\r\nserver.use(async (ctx, next) => {\r\n    await next();\r\n    // only intercept html request\r\n    if (!ctx.response.is('html')) {\r\n        return;\r\n    }\r\n    // process non-sonic mode\r\n    if (!ctx.request.header['accept-diff']) {\r\n        ctx.body = ctx.state.resHtml;\r\n        return;\r\n    }\r\n    // use sonic_differ module to process the response\r\n    let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml));\r\n    if (sonicData.cache) {\r\n        // 304 Not Modified, return nothing.\r\n        ctx.body = '';\r\n    } else {\r\n        // other Sonic status.\r\n        ctx.body = sonicData.data;\r\n    }\r\n});\r\n```\r\n\r\n  For more details please refer to [server.js](https://github.com/Tencent/VasSonic/blob/master/sonic-react/server.js).\r\n\r\n## How to use Sonic on client-side\r\n\r\nHandle the response from mobile client which include Sonic response code and diff data in `componentDidMount()`.\r\n\r\n```js\r\ncomponentDidMount() {\r\n    // handle the response from mobile client which include Sonic response code and diff data.\r\n    this.getSonicData((status, sonicUpdateData) => {\r\n        switch (status) {\r\n            // here, we only process the case when data updates\r\n            case 3:\r\n                // update the Redux store based on changes from the mobile client\r\n                let initState = sonicUpdateData['{initState}'] || '';\r\n                initState.replace(/<!--sonicdiff-initState-->\\s*<script>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)module=/ig, function(matched, $1) {\r\n                    window.__NEXT_DATA__ = JSON.parse($1);\r\n                });\r\n                this.props.initImgArr(window.__NEXT_DATA__.props.initialState.gameArea);\r\n                break;\r\n            default:\r\n                break\r\n        }\r\n        // display sonic status\r\n        this.props.setSonicStatus(status);\r\n    });\r\n}\r\n\r\ngetSonicData(callback) {\r\n    let sonicHadExecute = 0;   // whether the callback is triggered\r\n    const timeout = 3000;      // a timeout to trigger callback\r\n\r\n    // Interacts with mobile client by JavaScript interface to get Sonic diff data.\r\n    window.sonic && window.sonic.getDiffData();\r\n\r\n    function sonicCallback(data) {\r\n        if (sonicHadExecute === 0) {\r\n            sonicHadExecute = 1;\r\n            callback(data['sonicStatus'], data['sonicUpdateData']);\r\n        }\r\n    }\r\n\r\n    setTimeout(function() {\r\n        if (sonicHadExecute === 0) {\r\n            sonicHadExecute = 1;\r\n            callback(0, {});\r\n        }\r\n    }, timeout);\r\n\r\n    // the mobile client will invoke method getDiffDataCallback which can send Sonic response code and diff data to websites.\r\n    window['getDiffDataCallback'] = function (sonicData) {\r\n        /**\r\n         * Sonic status:\r\n         * 0: It fails to get any data from mobile client.\r\n         * 1: It is first time for mobile client to use Sonic.\r\n         * 2: Mobile client reload the whole websites.\r\n         * 3: Websites will be updated dynamically with local refresh.\r\n         * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\r\n         */\r\n        let sonicStatus = 0;\r\n        let sonicUpdateData = {};  // sonic diff data\r\n        sonicData = JSON.parse(sonicData);\r\n        switch (parseInt(sonicData['srcCode'], 10)) {\r\n            case 1000:\r\n                sonicStatus = 1;\r\n                break;\r\n            case 2000:\r\n                sonicStatus = 2;\r\n                break;\r\n            case 200:\r\n                sonicStatus = 3;\r\n                sonicUpdateData = JSON.parse(sonicData['result'] || '{}');\r\n                break;\r\n            case 304:\r\n                sonicStatus = 4;\r\n                break;\r\n        }\r\n        sonicCallback({ sonicStatus: sonicStatus, sonicUpdateData: sonicUpdateData });\r\n    };\r\n}\r\n```\r\nFor more details please refer to [demo.js](https://github.com/Tencent/VasSonic/blob/master/sonic-react/pages/demo.js)\r\n\r\n## Support\r\nAny problem?\r\n\r\n1. Learn more from [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-react).\r\n2. Contact us for help.\r\n\r\n## License\r\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details.\r\n"
  },
  {
    "path": "sonic-react/README_CN.md",
    "content": "基于 [React](https://reactjs.org/) 同构直出的 Sonic 使用示例。[React](https://reactjs.org/) 同构直出使用 [Redux](https://redux.js.org/)/[Next.js](https://github.com/zeit/next.js/)/[Koa2](http://koajs.com/) 实现。\r\n\r\n[![license](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat)](https://github.com/Tencent/VasSonic/blob/master/LICENSE)\r\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/VasSonic/pulls)\r\n[![wiki](https://img.shields.io/badge/Wiki-open-brightgreen.svg)](https://github.com/Tencent/VasSonic/wiki)\r\n\r\n<details>\r\n<summary><strong>目录</strong></summary>\r\n\r\n* [技术栈](#feature)\r\n* [快速开始](#getting-start)\r\n  + [安装](#installation)\r\n  + [启动](#start)\r\n  + [脚本](#script)\r\n* [项目架构](#project-structure)\r\n  + [目录结构](#file-tree)\r\n  + [原理](#principle)\r\n* [技术支持](#support)\r\n* [License](#license)\r\n\r\n</details>\r\n\r\n## <a name=\"feature\">&sect; 技术栈</a>\r\n\r\n- [React](https://reactjs.org/)\r\n- [Redux](https://redux.js.org/)\r\n- [Next.js](https://github.com/zeit/next.js/)\r\n- [Koa2](http://koajs.com/)\r\n- [ES6](http://babeljs.io/learn-es2015/)\r\n\r\n---\r\n\r\n## <a name=\"getting-start\">&sect; 快速开始</a>\r\n\r\n> **推荐升级**到 node 8.x + npm 5.x 环境。\r\n\r\n### <a name=\"installation\">⊙ 安装</a>\r\n\r\n```bash\r\ngit clone https://github.com/Tencent/VasSonic.git <my-project-name>\r\ncd <my-project-name>/sonic-react\r\nnpm install  # 安装项目依赖\r\n```\r\n\r\n### <a name=\"start\">⊙ 启动</a>\r\n\r\n```bash\r\nnpm run build\r\nnpm start\r\n```\r\n![](http://pub.idqqimg.com/pc/misc/files/20171222/1f820357f8de420e8a267040522645d8.png)\r\n\r\n手机端安装 Android 或 iOS 测试用应用程序。（[下载](https://github.com/Tencent/VasSonic/releases)）\r\n\r\n然后将手机与服务器连接在同一局域网下，查看服务器 ip 配置手机代理，并设置测试链接地址为 http://服务器ip:3000/demo\r\n\r\n1：设置手机代理 | 2：设置测试链接\r\n:-------------------------:|:-------------------------:\r\n<img width=\"285\" height=\"500\" src=\"http://pub.idqqimg.com/pc/misc/files/20180103/ef3a88fce92f41a18bacd5d335b4aeef.jpg\" alt=\"设置手机代理\" />  |  <img width=\"285\" height=\"500\" src=\"http://pub.idqqimg.com/pc/misc/files/20180103/c3f3d07093ca42be988ccc5dddce2be7.png\" alt=\"设置测试链接\" />\r\n\r\n3：访问 demo | 4：效果演示\r\n:-------------------------:|:-------------------------:\r\n<img width=\"285\" height=\"500\" src=\"http://pub.idqqimg.com/pc/misc/files/20180103/26302761e2f9465e955b510a69ebd0a9.png\" alt=\"访问demo\" />  |  <img width=\"285\" height=\"500\" src=\"http://pub.idqqimg.com/pc/misc/files/20180103/04a44f93ad454ea5ae51d0e2f2bf319b.jpg\" alt=\"demo\" />\r\n\r\n### <a name=\"script\">⊙ 脚本</a>\r\n\r\n| `npm run <script>`  | 描述                                         |\r\n| ------------------- | ------------------------------------------- |\r\n| `start`             | 启动服务(生产环境，需先执行 npm run build 命令) |\r\n| `dev`               | 启动服务(开发环境，无需执行 npm run build 命令) |\r\n| `build`             | 打包构建到目录 .next                        |\r\n\r\n---\r\n\r\n## <a name=\"project-structure\">&sect; 项目架构</a>\r\n\r\n### <a name=\"file-tree\">⊙ 目录结构</a>\r\n\r\n```bash\r\n.\r\n├── components               # demo 页面视图组件\r\n├── containers               # demo 页面容器组件\r\n├── pages                    # Next.js 用于存放每个页面入口组件的目录\r\n│   └── demo.js              # demo 页面入口 js\r\n├── redux                    # Redux 相关模块\r\n│   └── duck.js              # ducks 模式组织 redux 模块\r\n├── static                   # Next.js 用于存放静态资源的目录\r\n└── server.js                # 服务入口 js\r\n```\r\n\r\n### <a name=\"principle\">⊙ 原理</a>\r\n\r\n我们不去深究 React 直出以及示例中拼图游戏逻辑的实现，主要来说明下示例中是如何在 React 项目中使用 Sonic 的，流程图如下所示：\r\n\r\n![](http://pub.idqqimg.com/pc/misc/files/20180104/e6f7c4331ed441eb88d3c693617d0bf9.png)\r\n\r\n- 服务端拦截 React 渲染出来的HTML字符串，添加 HTML 注释标签来帮助 Sonic 区分模板和数据块。数据块需要通过 `<!-- sonicdiff-moduleName -->` `<!-- sonicdiff-moduleName-end -->` 来标记，剩下的部分称为模版。示例中代码实现如下：\r\n```js\r\n/**\r\n * 添加 Sonic 所需的 HTML 注释标签\r\n *\r\n * 举例:\r\n * <!DOCTYPE html>                                                 <!DOCTYPE html>\r\n * <html>                                                          <html>\r\n * <head></head>                                                   <head></head>\r\n * <body>                                                          <body>\r\n * … …                                                             … …\r\n * <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">      =>        <!-- sonicdiff-firstScreenHtml -->\r\n *     … …                                                         <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">\r\n * </div>                                                              … …\r\n * … …                                                             </div>\r\n * <script>                                                        <!-- sonicdiff-firstScreenHtml-end -->\r\n *     __NEXT_DATA__=xxx                                           … …\r\n * </script>                                                       <!-- sonicdiff-initState -->\r\n * </body>                                                         <script>\r\n *                                                                     __NEXT_DATA__=xxx\r\n *                                                                 </script>\r\n *                                                                 <!-- sonicdiff-initState-end -->\r\n *                                                                 </body>\r\n *\r\n * @param html {string} 原始 HTML 字符串\r\n * @returns {string} 添加注释标签后的 HTML 字符串\r\n */\r\nfunction formatHtml(html) {\r\n    const $ = cheerio.load(html);\r\n    $('*[data-sonicdiff]').each(function(index, element) {\r\n        let tagName = $(this).data('sonicdiff');\r\n        return $(this).replaceWith('<!--sonicdiff-' + tagName + '-->' + $(this).clone() + '<!--sonicdiff-' + tagName + '-end-->');\r\n    });\r\n    html = $.html();\r\n    html = html.replace(/<script\\s*>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)<\\/script>/ig, function(data1) {\r\n        return '<!--sonicdiff-initState-->' + data1 + '<!--sonicdiff-initState-end-->';\r\n    });\r\n    return html;\r\n}\r\n```\r\n\r\n- 服务端使用 [sonic_differ](https://github.com/Tencent/VasSonic/blob/master/sonic-nodejs/common/diff.js) 模块对数据进行处理后输出给浏览器。\r\n```js\r\nserver.use(async (ctx, next) => {\r\n    await next();\r\n\r\n    // 只拦截 html 请求\r\n    if (!ctx.response.is('html')) {\r\n        return;\r\n    }\r\n\r\n    // 非 sonic 模式不做特殊处理\r\n    if (!ctx.request.header['accept-diff']) {\r\n        ctx.body = ctx.state.resHtml;\r\n        return;\r\n    }\r\n\r\n    // 使用 sonic_differ 模块对数据进行处理\r\n    let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml));\r\n\r\n    if (sonicData.cache) {\r\n        // sonic 模式：完全缓存\r\n        ctx.body = '';\r\n    } else {\r\n        // 其它 sonic 状态\r\n        ctx.body = sonicData.data;\r\n    }\r\n});\r\n```\r\n\r\n- 前端在执行到 componentDidMount() 阶段时，通过 js 调用终端接口来获取 sonic 状态和数据，根据终端返回的不同状态，来决定如何渲染页面。\r\n```js\r\ncomponentDidMount() {\r\n    // 获取客户端返回的 sonic 状态和数据，根据终端返回数据做出相应的处理\r\n    this.getSonicData((status, sonicUpdateData) => {\r\n        switch (status) {\r\n            // sonic 状态：数据更新\r\n            case 3:\r\n                // 使用客户端返回的数据更新页面 Store\r\n                let initState = sonicUpdateData['{initState}'] || '';\r\n                initState.replace(/<!--sonicdiff-initState-->\\s*<script>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)module=/ig, function(matched, $1) {\r\n                    window.__NEXT_DATA__ = JSON.parse($1);\r\n                });\r\n                this.props.initImgArr(window.__NEXT_DATA__.props.initialState.gameArea);\r\n                break;\r\n            default:\r\n                break\r\n        }\r\n        // 展示 sonic 状态\r\n        this.props.setSonicStatus(status);\r\n    });\r\n}\r\n\r\ngetSonicData(callback) {\r\n    let sonicHadExecute = 0;   // 判断回调是否触发过的标识\r\n    const timeout = 3000;      // 终端接口 3s 内没有响应，触发超时逻辑\r\n\r\n    // 调用终端接口通知客户端进行 sonic 处理逻辑\r\n    window.sonic && window.sonic.getDiffData();\r\n\r\n    function sonicCallback(data) {\r\n        if (sonicHadExecute === 0) {\r\n            sonicHadExecute = 1;\r\n            callback(data['sonicStatus'], data['sonicUpdateData']);\r\n        }\r\n    }\r\n\r\n    setTimeout(function() {\r\n        if (sonicHadExecute === 0) {\r\n            sonicHadExecute = 1;\r\n            callback(0, {});\r\n        }\r\n    }, timeout);\r\n\r\n    // 终端调用 getDiffDataCallback 方法将数据传递给页面\r\n    window['getDiffDataCallback'] = function (sonicData) {\r\n        /**\r\n         * Sonic 状态:\r\n         * 0: 异常\r\n         * 1: 首次加载（首次和正常页面逻辑一样，前端无需特殊处理）\r\n         * 2: 模板更新（当模版发生变化时，终端会自动刷新当前页面，前端也无需特殊处理）\r\n         * 3: 数据更新（sonic页面模版没有变化，只有数据块发生变化，终端会返回变化的数据块名称和内容，前端只需要把变化的内容替换到页面即可）\r\n         * 4: 完全缓存（sonic页面模版和数据都没有变化，页面无需任何处理）\r\n         */\r\n        let sonicStatus = 0;\r\n        let sonicUpdateData = {};  // 数据更新时终端返回的数据\r\n        sonicData = JSON.parse(sonicData);\r\n        switch (parseInt(sonicData['srcCode'], 10)) {\r\n            case 1000:\r\n                sonicStatus = 1;\r\n                break;\r\n            case 2000:\r\n                sonicStatus = 2;\r\n                break;\r\n            case 200:\r\n                sonicStatus = 3;\r\n                sonicUpdateData = JSON.parse(sonicData['result'] || '{}');\r\n                break;\r\n            case 304:\r\n                sonicStatus = 4;\r\n                break;\r\n        }\r\n        sonicCallback({ sonicStatus: sonicStatus, sonicUpdateData: sonicUpdateData });\r\n    };\r\n}\r\n```\r\n\r\n---\r\n\r\n## <a name=\"support\">&sect; 技术支持</a>\r\n遇到其他问题，可以：\r\n\r\n1. 通过demo来理解 [sample](https://github.com/Tencent/VasSonic/tree/master/sonic-react)。\r\n2. 联系我们。\r\n\r\n## <a name=\"license\">&sect; License</a>\r\nVasSonic is under the BSD license. See the [LICENSE](https://github.com/Tencent/VasSonic/blob/master/LICENSE) file for details."
  },
  {
    "path": "sonic-react/components/GameArea.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nclass GameArea extends React.Component {\n    handleClickImg(index, i) {\n        this.props.onClickImg && this.props.onClickImg(index, i);\n    }\n\n    render() {\n        return (\n            <ul className=\"game-area\">\n                {this.props.imgArr.map((img, i) => {\n                    return (\n                        <li key={img.index} onClick={() => this.handleClickImg(img.index, i)}>\n                            <img src={img.src} alt=\"\" />\n                            {(this.props.selImgIndex.length !== 0 && this.props.selImgIndex[1] === i) ? <div className=\"mask\" ></div> : null}\n                        </li>\n                    );\n                })}\n                <style jsx>{`\n                    .game-area {\n                        position: absolute;\n                        left: 50%;\n                        top: 4.451rem;\n                        width: 8.75rem;\n                        margin-left: -4.7rem;\n                        border: .3rem solid #fff;\n                    }\n                    .game-area li {\n                        position: relative;\n                        width: 4.375rem;\n                        height: 4.375rem;\n                        overflow: hidden;\n                        float: left;\n                    }\n                    .game-area li img {\n                        width: 100%;\n                    }\n                    .game-area .mask {\n                        position: absolute;\n                        left: 0;\n                        top: 0;\n                        width: 100%;\n                        height: 100%;\n                        background: rgba(0,0,0,.6);\n                     }\n                `}</style>\n            </ul>\n        );\n    }\n}\n\nGameArea.propTypes = {\n    onClickImg: PropTypes.func,\n    imgArr: PropTypes.array\n};\n\nexport default GameArea;\n"
  },
  {
    "path": "sonic-react/components/GameFooter.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst GameFooter = (props) => {\n    return (\n        <div className=\"game-footer\">\n            <p>\n                重新打开页面以观察 sonic 状态和效果\n            </p>\n            <style jsx>{`\n                .game-footer {\n                    position: absolute;\n                    top: 14.5rem;\n                    width: 100%;\n                    height: 1.2rem;\n                    margin-left: -0.3rem;\n                }\n                .game-footer p {\n                    margin: 0;\n                    padding: 0;\n                    font-size: .47rem;\n                    font-weight: bold;\n                    line-height: 1.2rem;\n                    color: #fff;\n                    text-align: center;\n                }\n            `}</style>\n        </div>\n    );\n};\n\nexport default GameFooter;\n"
  },
  {
    "path": "sonic-react/components/GameHeader.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\n\nclass GameHeader extends React.Component {\n    render() {\n        return (\n            <div className=\"game-header\">\n                <div className=\"thumbnail\">\n                    <img src=\"/static/img/jigsaw/0.jpg\" alt=\"\" />\n                </div>\n                <div className=\"tag\">\n                    Sonic状态：{this.props.sonicStatus}\n                </div>\n                <style jsx>{`\n                    .game-header .thumbnail{\n                        position: absolute;\n                        left: .969rem;\n                        top: .61rem;\n                        width: 2.734rem;\n                        height: 2.734rem;\n                        border: .2rem solid #fff;\n                    }\n                    .game-header .thumbnail img {\n                        width: 100%;\n                    }\n                    .game-header .tag{\n                        position: absolute;\n                        right: .844rem;\n                        top: 1.456rem;\n                        width: 4.719rem;\n                        height: 1.2rem;\n                        padding-left: .2rem;\n                        font-size: .47rem;\n                        font-weight: bold;\n                        line-height: 1.2rem;\n                        color: #fff;\n                    }\n                `}</style>\n            </div>\n        );\n    }\n}\n\nGameHeader.propTypes = {\n    sonicStatus: PropTypes.string\n};\n\nconst mapStateToProps = ({ sonicStatus }) => ({ sonicStatus });\n\nexport default connect(mapStateToProps, null)(GameHeader);\n"
  },
  {
    "path": "sonic-react/containers/GameContainer.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nimport React from 'react';\nimport Notifications, { notify } from 'react-notify-toast';\nimport { connect } from 'react-redux';\n\nimport GameHeader from '../components/GameHeader';\nimport GameArea from '../components/GameArea';\nimport GameFooter from '../components/GameFooter';\n\nclass GameContainer extends React.Component {\n    constructor(props) {\n        super(props);\n        this.canPlay = true;\n        this.state = {\n            selImgIndex: props.selImgIndex,\n            imgArr: props.imgArr\n        };\n    }\n\n    componentWillReceiveProps(nextProps) {\n        this.setState({\n            imgArr: nextProps.imgArr,\n            selImgIndex: nextProps.selImgIndex\n        }, function() {\n            this.canPlay = true;\n        });\n    }\n\n    handleClickImg(index, i) {\n        if (!this.canPlay) {\n            return;\n        }\n        let selImgIndex = this.state.selImgIndex.slice(0);\n        if (selImgIndex.length === 0) {\n            this.setState({\n                selImgIndex: [index, i]\n            });\n        } else {\n            let imgArr = this.state.imgArr.slice(0);\n            imgArr[selImgIndex[1]] = {\n                src: '/static/img/jigsaw/' + index + '.jpg',\n                index: index\n            };\n            imgArr[i] = {\n                src: '/static/img/jigsaw/' + selImgIndex[0] + '.jpg',\n                index: selImgIndex[0]\n            };\n            this.setState({\n                imgArr,\n                selImgIndex: []\n            }, () => {\n                let newSeqArr = imgArr.map((img) => {\n                    return img.index;\n                });\n                if (newSeqArr.toString() === this.props.initSeqArr.toString()) {\n                    this.canPlay = false;\n                    notify.show('success!', 'success');\n                }\n            });\n        }\n    }\n\n    render() {\n        return (\n            <div>\n                <GameHeader />\n                <GameArea\n                    imgArr={this.state.imgArr}\n                    selImgIndex={this.state.selImgIndex}\n                    onClickImg={this.handleClickImg.bind(this)}\n                />\n                <GameFooter />\n                <Notifications />\n            </div>\n        );\n    }\n}\n\nconst mapStateToProps = (state) => {\n    return {\n        selImgIndex: state.gameArea.selImgIndex,\n        imgArr: state.gameArea.imgArr,\n        initSeqArr: state.gameArea.initSeqArr\n    };\n};\n\nexport default connect(mapStateToProps, null)(GameContainer);\n"
  },
  {
    "path": "sonic-react/package.json",
    "content": "{\n  \"name\": \"custom-server-koa\",\n  \"version\": \"1.0.0\",\n  \"scripts\": {\n    \"dev\": \"node server.js\",\n    \"build\": \"next build\",\n    \"start\": \"cross-env NODE_ENV=production node server.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"^1.0.0-rc.2\",\n    \"koa\": \"^2.0.1\",\n    \"koa-router\": \"^7.1.0\",\n    \"next\": \"latest\",\n    \"next-redux-wrapper\": \"^1.3.5\",\n    \"normalize.css\": \"^7.0.0\",\n    \"react\": \"^16.0.0\",\n    \"react-dom\": \"^16.0.0\",\n    \"react-notify-toast\": \"^0.4.0\",\n    \"react-redux\": \"^5.0.6\",\n    \"redux\": \"^3.7.2\",\n    \"redux-devtools-extension\": \"^2.13.2\",\n    \"redux-thunk\": \"^2.2.0\",\n    \"sonic_differ\": \"^1.0.7\"\n  },\n  \"devDependencies\": {\n    \"cross-env\": \"^5.1.3\"\n  }\n}\n"
  },
  {
    "path": "sonic-react/pages/demo.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nimport React from 'react';\nimport Head from 'next/head';\nimport withRedux from 'next-redux-wrapper';\nimport { bindActionCreators } from 'redux';\n\nimport GameContainer from '../containers/GameContainer';\nimport { initStore, setSonicStatus, initImgArr } from '../redux/duck';\n\nclass App extends React.Component {\n    static async getInitialProps({ store }) {\n        store.dispatch(initImgArr());\n    }\n\n    componentDidMount() {\n        // handle the response from mobile client which include Sonic response code and diff data.\n        this.getSonicData((status, sonicUpdateData) => {\n            switch (status) {\n                // only data updates\n                case 3: {\n                    // update the Redux store based on changes coming from the mobile client\n                    let initState = sonicUpdateData['{initState}'] || '';\n                    initState.replace(/<!--sonicdiff-initState-->\\s*<script>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)module=/ig, function(matched, $1) {\n                        window.__NEXT_DATA__ = JSON.parse($1);\n                    });\n                    this.props.initImgArr(window.__NEXT_DATA__.props.initialState.gameArea);\n                    break;\n                }\n                default:\n                    break;\n            }\n            // display sonic status\n            this.props.setSonicStatus(status);\n        });\n    }\n\n    /**\n     * Handle the response from mobile client which include Sonic response code and diff data\n     *\n     * @param callback {function} It executes until it receives an asynchronous callback from the mobile client.\n     */\n    getSonicData(callback) {\n        let sonicHadExecute = 0;   // whether the callback is triggered\n        const timeout = 3000;      // a timeout value of 3 seconds is specified to trigger callback\n\n        // Interacts with mobile client by JavaScript interface to get Sonic diff data.\n        window.sonic && window.sonic.getDiffData();\n\n        function sonicCallback(data) {\n            if (sonicHadExecute === 0) {\n                sonicHadExecute = 1;\n                callback(data['sonicStatus'], data['sonicUpdateData']);\n            }\n        }\n\n        setTimeout(function() {\n            if (sonicHadExecute === 0) {\n                sonicHadExecute = 1;\n                callback(0, {});\n            }\n        }, timeout);\n\n        // the mobile client will invoke method getDiffDataCallback which can send Sonic response code and diff data to websites.\n        window['getDiffDataCallback'] = function(sonicData) {\n            /**\n             * Sonic status:\n             * 0: It fails to get any data from mobile client.\n             * 1: It is first time for mobile client to use Sonic.\n             * 2: Mobile client reload the whole websites.\n             * 3: Websites will be updated dynamically with local refresh.\n             * 4: The Sonic request of mobile client receives a 304 response code and nothing has been modified.\n             */\n            let sonicStatus = 0;\n            let sonicUpdateData = {};  // sonic diff data\n            sonicData = JSON.parse(sonicData);\n            switch (parseInt(sonicData['srcCode'], 10)) {\n                case 1000:\n                    sonicStatus = 1;\n                    break;\n                case 2000:\n                    sonicStatus = 2;\n                    break;\n                case 200:\n                    sonicStatus = 3;\n                    sonicUpdateData = JSON.parse(sonicData['result'] || '{}');\n                    break;\n                case 304:\n                    sonicStatus = 4;\n                    break;\n            }\n            sonicCallback({ sonicStatus: sonicStatus, sonicUpdateData: sonicUpdateData });\n        };\n    }\n\n    render() {\n        return (\n            <div>\n                <Head>\n                    <meta httpEquiv=\"cache-control\" content=\"no-cache\" />\n                    <link rel=\"shortcut icon\" href=\"/static/favicon.ico\" />\n                    <title>react-sonic demo</title>\n                    <script type=\"text/javascript\" src=\"/static/js/flexible.js\"></script>\n                </Head>\n                <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">\n                    <GameContainer {...this.props} />\n                </div>\n                <style jsx global>{`\n                    body {\n                        background: #059eff;\n                    }\n                    ul, li {\n                        margin: 0;\n                        padding: 0;\n                        list-style: none;\n                    }\n                `}</style>\n            </div>\n        );\n    }\n}\n\nconst mapDispatchToProps = (dispatch) => {\n    return {\n        setSonicStatus: bindActionCreators(setSonicStatus, dispatch), // set sonic status\n        initImgArr: bindActionCreators(initImgArr, dispatch) // initialize image array\n    };\n};\n\nexport default withRedux(initStore, null, mapDispatchToProps)(App);\n"
  },
  {
    "path": "sonic-react/redux/duck.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nimport { createStore, applyMiddleware } from 'redux';\nimport { composeWithDevTools } from 'redux-devtools-extension';\nimport thunkMiddleware from 'redux-thunk';\n\nconst defaultInitialState = {\n    sonicStatus: '--',\n    gameArea: {\n        initSeqArr: [],\n        imgArr: [],\n        selImgIndex: []\n    }\n};\n\n// ------------------------------------\n// Constants\n// ------------------------------------\nexport const actionTypes = {\n    GET_SONIC_STATUS: 'GET_SONIC_STATUS',\n    INIT_IMG_ARR: 'INIT_IMG_ARR'\n};\n\n// ------------------------------------\n// Actions\n// ------------------------------------\nconst setSonicStatusAct = (res) => ({\n    type: actionTypes.GET_SONIC_STATUS,\n    sonicStatus: res\n});\nconst initImgArrAct = (res) => ({\n    type: actionTypes.INIT_IMG_ARR,\n    gameArea: res\n});\n\n// ------------------------------------\n// Specialized Action Creator\n// ------------------------------------\nexport const setSonicStatus = (sonicStatus) => async (dispatch, getState) => {\n    try {\n        let statusWording = '';\n        switch (sonicStatus) {\n            case 0:\n                statusWording = '异常';\n                break;\n            case 1:\n                statusWording = '首次加载';\n                break;\n            case 2:\n                statusWording = '模板更新';\n                break;\n            case 3:\n                statusWording = '数据更新';\n                break;\n            case 4:\n                statusWording = '完全缓存';\n                break;\n            default:\n                statusWording = '异常';\n                break;\n        }\n        await dispatch(setSonicStatusAct(statusWording));\n    } catch (error) {\n        console.log('error: ', error);\n    }\n};\n\nexport const initImgArr = (imgArrState) => async (dispatch, getState) => {\n    try {\n        if (imgArrState) {\n            await dispatch(initImgArrAct(imgArrState));\n            return;\n        }\n        let initSeqArr = [1, 2, 3, 4];\n        let initSeqArrTmp = initSeqArr.slice(0);\n        let initImgArr = [];\n\n        while (initSeqArr.toString() === initSeqArrTmp.toString()) {\n            initSeqArrTmp.sort(() => {\n                return Math.random() - 0.5;\n            });\n        }\n        initSeqArrTmp.forEach((i) => {\n            initImgArr.push({\n                'src': '/static/img/jigsaw/' + i + '.jpg',\n                'index': i\n            });\n        });\n        await dispatch(initImgArrAct({\n            initSeqArr,\n            imgArr: initImgArr,\n            selImgIndex: []\n        }));\n    } catch (error) {\n        console.log('error: ', error);\n    }\n};\n\n// ------------------------------------\n// Reducer\n// ------------------------------------\nexport const reducer = (state = defaultInitialState, action) => {\n    switch (action.type) {\n        case actionTypes.GET_SONIC_STATUS:\n            return {\n                ...state,\n                sonicStatus: action.sonicStatus\n            };\n        case actionTypes.INIT_IMG_ARR:\n            return {\n                ...state,\n                gameArea: action.gameArea\n            };\n        default: return state;\n    }\n};\n\nexport const initStore = (initialState = defaultInitialState) => {\n    return createStore(reducer, initialState, composeWithDevTools(applyMiddleware(thunkMiddleware)));\n};"
  },
  {
    "path": "sonic-react/server.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making VasSonic available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n * 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\n * https://opensource.org/licenses/BSD-3-Clause\n * 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.\n */\n\nconst Koa = require('koa');\nconst next = require('next');\nconst Router = require('koa-router');\nconst cheerio = require('cheerio');\nconst sonicDiff = require('sonic_differ');\n\nconst port = parseInt(process.env.PORT, 10) || 3000;\nconst dev = process.env.NODE_ENV !== 'production';\n\nconst app = next({ dev });\nconst handle = app.getRequestHandler();\n\n/**\n * add comment tags to separate template and data blocks from the initial html\n *\n * Example:\n * <!DOCTYPE html>                                                         <!DOCTYPE html>\n * <html>                                                                  <html>\n * <head></head>                                                           <head></head>\n * <body>                                                                  <body>\n * … …                                                                     … …\n * <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">          =>            <!-- sonicdiff-firstScreenHtml -->\n *     … …                                                                 <div id=\"root\" data-sonicdiff=\"firstScreenHtml\">\n * </div>                                                                      … …\n * … …                                                                     </div>\n * <script>                                                                <!-- sonicdiff-firstScreenHtml-end -->\n *     __NEXT_DATA__=xxx                                                   … …\n * </script>                                                               <!-- sonicdiff-initState -->\n * </body>                                                                 <script>\n *                                                                             __NEXT_DATA__=xxx\n *                                                                         </script>\n *                                                                         <!-- sonicdiff-initState-end -->\n *                                                                         </body>\n *\n * @param html {string} the initial html\n * @returns {string} html with comment tags which help sonic to splits the html to template and data\n */\nfunction formatHtml(html) {\n    const $ = cheerio.load(html);\n    $('*[data-sonicdiff]').each(function(index, element) {\n        let tagName = $(this).data('sonicdiff');\n        return $(this).replaceWith('<!--sonicdiff-' + tagName + '-->' + $(this).clone() + '<!--sonicdiff-' + tagName + '-end-->');\n    });\n    html = $.html();\n    html = html.replace(/<script\\s*>\\s*__NEXT_DATA__\\s*=([\\s\\S]+?)<\\/script>/ig, function(data1) {\n        return '<!--sonicdiff-initState-->' + data1 + '<!--sonicdiff-initState-end-->';\n    });\n    return html;\n}\n\napp.prepare().then(() => {\n    const server = new Koa();\n    const router = new Router();\n\n    // intercept request and render html string only if at a given URL\n    router.get('/demo', async ctx => {\n        ctx.set('Content-Type', 'text/html');\n        ctx.state.resHtml = await app.renderToHTML(ctx.req, ctx.res, ctx.path, ctx.query);\n    });\n\n    router.get('*', async ctx => {\n        ctx.set('Cache-Control', 'max-age:30');\n        await handle(ctx.req, ctx.res);\n    });\n\n    server.use(async (ctx, next) => {\n        await next();\n\n        // only intercept html request\n        if (!ctx.response.is('html')) {\n            return;\n        }\n\n        // process non-sonic mode\n        if (!ctx.request.header['accept-diff']) {\n            ctx.body = ctx.state.resHtml;\n            return;\n        }\n\n        // use sonic_differ module to process the data\n        let sonicData = sonicDiff(ctx, formatHtml(ctx.state.resHtml));\n\n        if (sonicData.cache) {\n            // 304 Not Modified, return nothing.\n            ctx.body = '';\n        } else {\n            // other Sonic status.\n            ctx.body = sonicData.data;\n        }\n    });\n\n    server.use(router.routes());\n\n    server.listen(port, (err) => {\n        if (err) {\n            throw err;\n        }\n        console.log(`> Ready on http://localhost:${port}`);\n    });\n});\n"
  },
  {
    "path": "sonic-react/static/js/flexible.js",
    "content": "!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={}));"
  }
]