WEEX + HTTPDNS best practices on Android

Lee toothbrush son
Alibaba Cloud ApsaraMobile

Android Java HTTPS LOG Path Code Request String URL void

Abstract: Since ‘WebView’ does not expose the DNS interface, there are many limitations on the use of ‘HttpDns’ in the’ WebView ‘scenario, but if connected to’ WEEX ‘, it can be better implanted ‘HttpDns’. This article mainly introduces the details of the scheme to access HTTPDNS in the WEEX scenario.

Because the DNS interface is not configured on the WebView, there are many limitations on the Use of HttpDns in the WebView scenario. However, if the WEEX is connected, the HttpDns can be implanted. This article describes the solution details for accessing HttpDns in the WEEX scenario.

Under the WEEX Runtime environment, all logic is eventually converted to the Native Runtime for execution, including network requests. WEEX also provides an interface for customizing the corresponding implementation. By rewriting the network request adapter, we can easily access HTTPDNS. In the WEEX environment, there are two types of network requests:

  • A network request made through Stream
  • Tag specifies the network request to load an image

1 StreamNetwork request + HTTPDNS

Stream network requests on Android end through DefaultWXHttpAdapter, and WEEX also provides the corresponding interface to customize the network request adapter. The specific logic is as follows:

Step 1: Create a custom network request adapter that implements the IWXHttpAdapter interface

public class WXHttpdnsAdatper implements IWXHttpAdapter { @Override public void sendRequest(final WXRequest request, final OnHttpListener listener) { ...... }}Copy the code

This interface needs to implement the sendRequest method, which passes in an instance of a WXRequest object that provides the following information:

public class WXRequest {
  // The request parameter
  public Map<String, String> paramMap;
  // The request URL
  public String url;
  // The request method
  public String method;
  // The request body
  public String body;
  // The request time out
  public int timeoutMs = WXRequest.DEFAULT_TIMEOUT_MS;
  // The default timeout
  public static final int DEFAULT_TIMEOUT_MS = 3000;
}
Copy the code

From this object we can get the request header, URL, method, and body.

Step 2: Register a custom network adapter during WEEX initialization and replace the default adapter:

InitConfig config=new initconfig.builder ().sethttPAdapter (new WXHttpdnsAdatper()) // Register a custom network request adapter...... .build(); WXSDKEngine.initialize(this,config);Copy the code

WXHttpdnsAdatper (WXHttpdnsAdatper, WXHttpdnsAdatper, WXHttpdnsAdapter, WXHttpdnsAdapter)

public class WXHttpdnsAdatper implements IWXHttpAdapter { ...... private void execute(Runnable runnable){ if(mExecutorService==null){ mExecutorService = Executors.newFixedThreadPool(3);  } mExecutorService.execute(runnable); } @Override public void sendRequest(final WXRequest request, final OnHttpListener listener) { if (listener ! = null) { listener.onHttpStart(); } Log.e(TAG, "URL:" + request.url); execute(new Runnable() { @Override public void run() { WXResponse response = new WXResponse(); WXHttpdnsAdatper.IEventReporterDelegate reporter = getEventReporterDelegate(); HttpURLConnection connection = openConnection(request, listener); reporter.preConnect(connection, request.body); . } catch (IOException |IllegalArgumentException e) { ...... }}}); } private HttpURLConnection openConnection(WXRequest request, OnHttpListener listener) throws IOException { URL url = new URL(request.url); HttpURLConnection connection = openHttpDnsConnection(request, request.url, listener, null); return connection; } private HttpURLConnection openHttpDnsConnection(WXRequest request, String path, OnHttpListener listener, String reffer) { HttpURLConnection conn = null; URL url = null; try { url = new URL(path); conn = (HttpURLConnection) url.openConnection(); HttpURLConnection tmpConn = httpDnsConnection(url, path); . int code = conn.getResponseCode(); // Network block Log.e(TAG, "code:" + code); If (needRedirect(code)) {log.e (TAG, "need redirect"); if (needRedirect(code)) {log.e (TAG, "need redirect"); String location = conn.getHeaderField("Location"); if (location == null) { location = conn.getHeaderField("location"); } if (location ! = null) { if (! (the location. The startsWith (" http:// ") | | the location. The startsWith (" https:// "))) {/ / some time will omit the host, only to return to the back of the path, OriginalUrl = new URL(path); location = originalUrl.getProtocol() + "://" + originalUrl.getHost() + location; } Log.e(TAG, "code:" + code + "; location:" + location + "; path" + path); return openHttpDnsConnection(request, location, listener, path); } else { return conn; } } else { // redirect finish. Log.e(TAG, "redirect finish"); return conn; }}... return conn; } private HttpURLConnection httpDnsConnection(URL url, String path) { HttpURLConnection conn = null; / / by HTTPDNS SDK interface to get IP String IP = HttpDnsManager. GetInstance () getHttpDnsService () getIpByHostAsync (url. The getHost ()); if (ip ! Log.d(TAG, "Get IP: "+ IP +" for HOST: " + url.getHost() + " from HTTPDNS successfully!" ); String newUrl = path.replaceFirst(url.getHost(), ip); try { conn = (HttpURLConnection) new URL(newUrl).openConnection(); } catch (IOException e) { return null; } // Set the HTTP header Host field conn.setrequestProperty ("Host", url.gethost ()); Conn instanceof HttpsURLConnection {final HttpsURLConnection HttpsURLConnection = (HttpsURLConnection)conn; WXTlsSniSocketFactory sslSocketFactory = new WXTlsSniSocketFactory((HttpsURLConnection) conn); / / SNI scenario, create SSLScocket to solve the problem of the certificate of the SNI Settings conn. SetInstanceFollowRedirects (false); httpsURLConnection.setSSLSocketFactory(sslSocketFactory); // In HTTPS scenarios, Certificate of calibration httpsURLConnection. SetHostnameVerifier (new HostnameVerifier () {@ Override public Boolean verify (String hostname, SSLSession session) { String host = httpsURLConnection.getRequestProperty("Host"); Log.e(TAG, "verify host:" + host); if (null == host) { host = httpsURLConnection.getURL().getHost(); } return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session); }}); } } else { Log.e(TAG, "no corresponding ip found, return null"); return null; } return conn; }}Copy the code

1.2 <image>Network request + HTTPDNS

WEEX does not provide the default image adapter implementation, so users must implement the image request logic by themselves. The steps are as follows:

Step 1: customize the image request adapter to implement the IWXImgLoaderAdapter interface

public class HttpDnsImageAdapter implements IWXImgLoaderAdapter { @Override public void setImage(final String url, final ImageView view, WXImageQuality quality, final WXImageStrategy strategy) { ...... }}Copy the code

Step 2: Register the image adapter during WEEX initialization:

private void initWeex() { InitConfig config=new InitConfig.Builder() .setImgAdapter(new HttpDnsImageAdapter()) .build();  WXSDKEngine.initialize(this,config); . }Copy the code

So as with WXHttpdnsAdatper, we just need to embed the HTTPDNS logic into the HttpDnsImageAdapter. For specific codes, please refer to:

/** * Created by liyazhou on 2017/10/22. */ public class WXHttpDnsImageAdapter implements IWXImgLoaderAdapter { @Override public void setImage(final String url, final ImageView view, WXImageQuality quality, final WXImageStrategy strategy) { Log.e(TAG, "img url:" + url); execute(new Runnable() { @Override public void run() { ...... HttpURLConnection conn = null; try { conn = createConnection(url); . InputStream is = conn.getinputStream (); / / convert InputStream into Bitmap final Bitmap Bitmap. = BitmapFactory decodeStream (is); WXSDKManager.getInstance().postOnUiThread(new Runnable() { @Override public void run() { view.setImageBitmap(bitmap); }}, 0); . }}); } protected HttpURLConnection createConnection(String originalUrl) throws IOException { mHttpDnsService = HttpDnsManager.getInstance().getHttpDnsService(); if (mHttpDnsService == null) { URL url = new URL(originalUrl); return (HttpURLConnection) url.openConnection(); } else { return httpDnsRequest(originalUrl, null); } } private HttpURLConnection httpDnsRequest(String path, String reffer) { HttpURLConnection httpDnsConn = null; HttpURLConnection originalConn = null; URL url = null; try { url = new URL(path); originalConn = (HttpURLConnection) url.openConnection(); / / asynchronous interfaces for IP String IP = HttpDnsManager getInstance () getHttpDnsService () getIpByHostAsync (url. The getHost ()); if (ip ! Log.d(TAG, "Get IP: "+ IP +" for HOST: " + url.getHost() + " from HTTPDNS successfully!" ); String newUrl = path.replaceFirst(url.getHost(), ip); httpDnsConn = (HttpURLConnection) new URL(newUrl).openConnection(); . / / set the HTTP request header Host domain httpDnsConn setRequestProperty (" Host ", url. GetHost ()); // HTTPS if (httpDnsConn instanceof HttpsURLConnection) {final HttpsURLConnection HttpsURLConnection = (HttpsURLConnection)httpDnsConn; WXTlsSniSocketFactory sslSocketFactory = new WXTlsSniSocketFactory((HttpsURLConnection) httpDnsConn); / / sni scenario, create SSLScocket solve the sni certificate problem under the scenario httpsURLConnection. SetSSLSocketFactory (sslSocketFactory); // In HTTPS scenarios, Certificate of calibration httpsURLConnection. SetHostnameVerifier (new HostnameVerifier () {@ Override public Boolean verify (String hostname, SSLSession session) { String host = httpsURLConnection.getRequestProperty("Host"); if (null == host) { host = httpsURLConnection.getURL().getHost(); } return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session); }}); } } else { return originalConn; }... int code = httpDnsConn.getResponseCode(); // Network block if (needRedirect(code)) { String location = httpDnsConn.getHeaderField("Location"); if (location == null) { location = httpDnsConn.getHeaderField("location"); } if (location ! = null) { if (! (the location. The startsWith (" http:// ") | | the location. The startsWith (" https:// "))) {/ / some time will omit the host, only to return to the back of the path, OriginalUrl = new URL(path); location = originalUrl.getProtocol() + "://" + originalUrl.getHost() + location; } Log.e(TAG, "code:" + code + "; location:" + location + "; path" + path); return httpDnsRequest(location, path); } else { return originalConn; } } return originalConn; }}Copy the code

The above scheme detailed code construction: WeexAndroid

Use the cloud habitat community APP, comfortable ~

For details, please click
Review articles (1)

Related articles

The net friend comment on