终端接入指引-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 {
  2.  
  3.  
  4. public final static String PARAM_URL = "param_url";
  5.  
  6. public final static String PARAM_MODE = "param_mode";
  7.  
  8. private SonicSession sonicSession;
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. Intent intent = getIntent();
  14. String url = intent.getStringExtra(PARAM_URL);
  15.  
  16. getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
  17.  
  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. }
  22.  
  23. SonicSessionClientImpl sonicSessionClient = null;
  24.  
  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. }
  36.  
  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);
  40.  
  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. }
  51.  
  52. @TargetApi(21)
  53. @Override
  54. public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
  55. return shouldInterceptRequest(view, request.getUrl().toString());
  56. }
  57.  
  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. });
  66.  
  67. WebSettings webSettings = webView.getSettings();
  68.  
  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");
  77.  
  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);
  87.  
  88.  
  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. }
  97.  
  98. @Override
  99. public void onBackPressed() {
  100. super.onBackPressed();
  101. }
  102.  
  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. }