终端接入指引-Android版本


1.Sdk引入配置

在模块的build.gradle文件里面加入

1. compile 'com.tencent.sonic:sdk:3.0.0-alpha'

2.代码接入

(1).创建一个类继承SonicRuntime

SonicRuntime类主要提供sonic运行时环境,包括Context、用户UA、ID(用户唯一标识,存放数据时唯一标识对应用户)等等信息。以下代码展示了SonicRuntime的几个方法。

1. public class HostSonicRuntime extends SonicRuntime {
2. public HostSonicRuntime(Context context) {
3. super(context);
4. }
5. /**
6. * 获取用户UA信息
7. * @return
8. */
9. @Override
10. public String getUserAgent() {
11. return "";
12. }
13. /**
14. * 获取用户ID信息
15. * @return
16. */
17. @Override
18. public String getCurrentUserAccount() {
19. return "";
20. }
21. /**
22. * 创建sonic文件存放的路径
23. * @return
24. */
25. @Override
26. public File getSonicCacheDir() {
27. String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator         + "sonic/";
28. File file = new File(path.trim());
29. if(!file.exists()){
30. file.mkdir();
31. }
32. return file;
33. }
34. }

(2).创建一个类继承SonicSessionClient

SonicSessionClient主要负责跟webView的通信,比如调用webView的loadUrl、loadDataWithBaseUrl等方法。

1. public class SonicSessionClientImpl extends SonicSessionClient {
2. private WebView webView;
3. public void bindWebView(WebView webView) {
4. this.webView = webView;
5. }
6. /**
7. * 调用webView的loadUrl
8. */
9. @Override
10. public void loadUrl(String url, Bundle extraData) {
11. webView.loadUrl(url);
12. }
13. /**
14. * 调用webView的loadDataWithBaseUrl方法
15. */
16. @Override
17. public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding,
18. String historyUrl) {
19. webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
20. }
21. }

(3).新建包含webView的Activity(或者Fragment等),在activity中完成sonic的接入。这里通过简单的demo展示如何接入

1. public class SonicTestActivity extends Activity {

4. public final static String PARAM_URL = "param_url";

6. public final static String PARAM_MODE = "param_mode";

8. private SonicSession sonicSession;

10. @Override
11. protected void onCreate(Bundle savedInstanceState) {
12. super.onCreate(savedInstanceState);
13. Intent intent = getIntent();
14. String url = intent.getStringExtra(PARAM_URL);

16. getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

18. // init sonic engine if necessary, or maybe u can do this when application created
19. if (!SonicEngine.isGetInstanceAllowed()) {
20. SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());
21. }

23. SonicSessionClientImpl sonicSessionClient = null;

25. // if it's sonic mode , startup sonic session at first time
26. SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();
27. // create sonic session and run sonic flow
28. sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());
29. if (null != sonicSession) {
30. sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());
31. } else {
32. // this only happen when a same sonic session is already running,
33. // u can comment following code to feedback for default mode to
34. throw new UnknownError("create session fail!");
35. }

37. // start init flow ... in the real world, the init flow may cost a long time as startup
38. // runtime、init configs....
39. setContentView(R.layout.activity_browser);

41. // init webview
42. WebView webView = (WebView) findViewById(R.id.webview);
43. webView.setWebViewClient(new WebViewClient() {
44. @Override
45. public void onPageFinished(WebView view, String url) {
46. super.onPageFinished(view, url);
47. if (sonicSession != null) {
48. sonicSession.getSessionClient().pageFinish(url);
49. }
50. }

52. @TargetApi(21)
53. @Override
54. public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
55. return shouldInterceptRequest(view, request.getUrl().toString());
56. }

58. @Override
59. public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
60. if (sonicSession != null) {
61. return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);
62. }
63. return null;
64. }
65. });

67. WebSettings webSettings = webView.getSettings();

69. // add java script interface
70. // note:if api level if lower than 17(android 4.2), addJavascriptInterface has security
71. // issue, please use x5 or see https://developer.android.com/reference/android/webkit/
72. // WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)
73. webSettings.setJavaScriptEnabled(true);
74. webView.removeJavascriptInterface("searchBoxJavaBridge_");
75. intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis());
76. webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic");

78. // init webview settings
79. webSettings.setAllowContentAccess(true);
80. webSettings.setDatabaseEnabled(true);
81. webSettings.setDomStorageEnabled(true);
82. webSettings.setAppCacheEnabled(true);
83. webSettings.setSavePassword(false);
84. webSettings.setSaveFormData(false);
85. webSettings.setUseWideViewPort(true);
86. webSettings.setLoadWithOverviewMode(true);

89. // webview is ready now, just tell session client to bind
90. if (sonicSessionClient != null) {
91. sonicSessionClient.bindWebView(webView);
92. sonicSessionClient.clientReady();
93. } else { // default mode
94. webView.loadUrl(url);
95. }
96. }

98. @Override
99. public void onBackPressed() {
100. super.onBackPressed();
101. }

103. @Override
104. protected void onDestroy() {
105. if (null != sonicSession) {
106. sonicSession.destroy();
107. sonicSession = null;
108. }
109. super.onDestroy();
110. }
111. }

SonicTestActivity是一个含有webView的demo代码,里面展示了sonic的整体流程。主要分为6个步骤:

Step1:在activity onCreate的时候创建SonicRuntime并且初始化SonicEngine。为sonic初始化运行时需要的环境

1. if (!SonicEngine.isGetInstanceAllowed()) {
2. SonicEngine.createInstance(new SonicRuntimeImpl(getApplication()), new SonicConfig.Builder().build());
3. }

Setp2:通过SonicEngine.getInstance().createSession来为要加载的url创建一个SonicSession对象,同时为session绑定client。session创建之后sonic就会异步加载数据了。

1. SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();
2. // create sonic session and run sonic flow
3. sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());
4. if (null != sonicSession) {
5. sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());
6. }

Step3:设置javascript,这个主要是设置页面跟终端的js交互方式。按照sonic的规范,webView打开页面之后页面会通过js来获取sonic提供的一些数据(比如页面需要刷新的数据)。Demo里使用的是标准的js交互代码,第三方可以替换为自己的js交互实现方式(比如提供jsbridge伪协议等)。

1. webSettings.setJavaScriptEnabled(true);
2. webView.removeJavascriptInterface("searchBoxJavaBridge_");
3. webView.addJavascriptInterface(new SonicJavaScriptInterface(sonicSessionClient, intent), "sonic");

Step4:为clinet绑定webview,在webView准备发起loadUrl的时候通过SonicSession的onClientReady方法通知sonicSession: webView ready可以开始loadUrl了。这时sonic内部就会根据本地的数据情况执行webView相应的逻辑(执行loadUrl或者loadData等)。

1. if (sonicSessionClient != null) {
2. sonicSessionClient.bindWebView(webView);
3. sonicSessionClient.clientReady();
4. }

Step5:在webView资源拦截的回调中调用session.onClientRequestResource(url)。通过这个方法向sonic获取url对应的WebResourceResponse数据。这样内核就可以根据这个返回的response的内容进行渲染了。(如果sonic在webView ready的时候执行的是loadData的话,是不会走到资源拦截这里的)

1. public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
2. if (sonicSession != null) {
3. return (WebResourceResponse) sonicSession.getSessionClient().requestResource(url);
4. }
5. return null;
6. }