📜 ⬆️ ⬇️

Crosswalk Project - replacement of Android WebView. Integration issues

Crosswalkproject

In this article I will finish my story about the Crosswalk Project (you can find the first part here ). I will tell you in more detail about my Crosswalk integration experience, some of the intricacies of working with it, the problems encountered and their possible solutions.

The first and perhaps most obvious solution to all questions is to change the Crosswalk code to fit your needs. This is possible because the project is open and you can even help its authors. However, this is not always necessary and may cause additional difficulties. In the examples described, I do not consider this option, but it is useful to study the code of the base classes.

Control page loading in XWalkView.


Perhaps the second most important thing in the Crosswalk, after the speed of its work, is the predictability of the call to Kalbeks. The ability to focus on call logic and have a single algorithm for all versions of Android is just fine. The difficulties with load control in the system WebView are well described in this article .
')
As well as the system class, XWalkView has two helper classes that can receive calls while loading and working with XWalkView - these are XWalkUIClient and XWalkResourceClient. As I wrote earlier, they have no direct correspondence with the system WebChromeClient and WebViewClient, the methods in them are distributed somewhat differently. However, for myself, I set the approximate correspondence as WebChromeClient == XWalkUIClient and WebViewClient == XWalkResourceClient.

XWalkUIClient also contains methods:

and:

As you can see, there are methods included in both the WebViewClient interface and WebChromeClient, but, in general, the XWalkUIClient contains methods that are of importance to the UI.

XWalkResourceClient including contains:

The sequence of calling the main callbacks is as follows:

This sequence will be the same as for the url loaded using the WXalkView method, and to follow the link on the page and even when loading is stopped using stopLoading ().

The sequence for downloading a page with a redirect looks almost the same:

As you can see, during the transition through the redirect, we received additional calls for the same start-up callbacks and, in fact, the logic in this case also did not break.

Additionally, you can specify that the onPageLoadStopped method has the following signature:
onPageLoadStopped(XWalkView view, java.lang.String url, XWalkUIClient.LoadStatus status); 

The additional parameter of the XWalkUIClient.LoadStatus type gives quite important information about how the download ended and has 3 options:

It was not without a couple of oddities in the behavior of Crosswalk. For example, the onLoadFinished method is called only once after loading the entire page and even after onPageLoadStopped. The logic assumes that the onLoadFinished call should correspond to the onLoadStarted call that occurs for each resource, but this is not the case now.

It is also possible that a pair of final methods onPageLoadStopped and onLoadFinished will be called twice. I found mention of such behavior even for Crosswalk of the 11th version, but apparently this problem has not been solved so far.

Handling events from the screen and buttons.


One of the first problems you will encounter when integrating XWalkView will be the handling of screen and keyboard events (specifically the Back buttons). In XWalkView, as well as onActivityResult and onNewIntent methods, the following method is implemented: dispatchKeyEvent (KeyEvent event). It intercepts events from the Back button to switch from full-screen mode and navigate through the browser history. Accordingly, you cannot receive this event if you use the methods:
 public boolean onKeyUp(int keyCode, KeyEvent event); public void onBackPressed(); 

A solution may be to handle this event also in a dispatchKeyEvent (KeyEvent event). It is also useful to know if you want to make your own navigation through the navigation history.

A similar problem awaits you if you want to use the onTouchEvent listener for your XWalkView. The solution is similar to the one above - implement event handling in a dispatchTouchEvent (MotionEvent event).

Examples added to the test project available on GitHub .

Work with cookie storage.


An important point in the browser and WebView is the handling of cookies. For example, you want to load some page not through XWalkView, but display it in it and allow the user to work with it. The page can set its own cookies and for normal operation they will be needed in the XWalkView.

In Crosswalk, there is a special component XWalkCookieManager , which actually deals with the storage and handling of cookies. Very strange, but it is not described in Javadoc, although it is public and available for use. Implementation and comments on class methods can be found here.

XWalkCookieManager, like the Crosswalk cache, is the same for all XWalkView instances in your application. The class is quite simple to use and allows you to add and receive cookies for a specific address, clear the vault, and so on. Example of initialization:
 mXCookieManager = new XWalkCookieManager(); mXCookieManager.setAcceptCookie(true); mXCookieManager.setAcceptFileSchemeCookies(true); 

However, the simplicity of its implementation has some problems. For example, the method for setting a cookie looks like this:
 public void setCookie(String url, String value); 

Accordingly, you will not be able to specify the lifetime for the cookie, and the domain and path for the cookie will be obtained from the specified url, but with some unpleasant nuances.

For example, you want to set a cookie for m.vk.com and assume that the cookie will be valid for login.vk.com , but in this case it is not. In order for XWalkCookieManager to adequately work out this point, you must set a cookie for the address .vk.com .

It is also stated that XWalkCookieManager should update the cookie if you install an existing one in the repository, but I have observed that it sometimes duplicates the values. Obviously some problems in parsing the value when installing. Therefore, it is worth once again to check the correctness of the work of this class, if you use it.

As a simple example of working with XWalkCookieManager, the test project implements the synchronization method with CookieManager.

Getting WebSettings and installing them.


As I wrote earlier, WebSettings are not available when working with the XWalkView and have predefined parameters. More precisely in Crosswalk there is an analogue of this class - XWalkSettings , you can learn its methods here. For some parameters, an exception was made and they are placed in the interface of the XWalkView class itself. For example, now you can install the User-Agent you need.

However, it may be necessary to fine tune. It may also be necessary, as in my case, to get the User-Agent used by the XWalkView itself. In this case, you can take the opportunity to get it through reflection.

Actually, the XWalkView class itself is a superstructure over the XWalkViewInternal implementation and is connected to it via bridge through reflection. XWalkViewInternal also has a public getSettings () method, which we can use:
 Method ___getBridge = XWalkView.class.getDeclaredMethod("getBridge"); ___getBridge.setAccessible(true); XWalkViewBridge xWalkViewBridge = null; xWalkViewBridge = (XWalkViewBridge) ___getBridge.invoke(webView); XWalkSettings xWalkSettings = xWalkViewBridge.getSettings(); 

As an example of getting XWalkSettings and working with it, the test project has a method for getting a User-Agent.

Get the XWalkView image.


Since XWalkView uses SurfaceView or TextureView for drawing, it’s not possible to get its image using standard methods. For example, this option works for the system WebView, but does not work for XWalkView:
 View view = mWebView.getRootView(); view.setDrawingCacheEnabled(true); Bitmap b = Bitmap.createBitmap(view.getDrawingCache()); view.setDrawingCacheEnabled(false); 

It happens because standard view methods, such as getDrawingCache () or draw (), work with the software layer, while the XWalkView uses the hardware layer. That is why developers are asked to set the android: hardwareAccelerated = “true” flag for applications using Crosswalk. By the way, now it is set by default and there is no need to prescribe it separately.

An XWalkView image is possible when using TextureView as the base, where there is a getBitmap () method. In short, you need to find the target TextureView in the tree and call this method in it. An example implementation is also available in the test project.

Small nuances.


In the appendage there are several minor points that you may also encounter during the integration process:


findings


Using Crosswalk in the development is quite simple and convenient, especially considering the open source code. A good community and a fairly large spread of the project will solve most problems.

If you support Android 4.0+ and want more predictable work of your code on all versions of Android, then I definitely recommend Crosswalk.

If you support Android from version 4.4 and especially 5.0, then I would think about using Crosswalk in your projects. The lack of some new features of the system WebView can make life difficult for you.

I hope my experience will help you decide what to use as a WebView for your project :).

Source: https://habr.com/ru/post/263655/


All Articles