Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
bradp
Active Participant

As a follow up to my previous blog: Mobile Workflow using SAP Netweaver Gateway-Part 1, I will be going into more detail about my experience and lessons learned while building a native Android version of this app. Most of this blog is around the data consumption part of the app, and not necessarily specific to Android.

The starting point

As mentioned in my previous blog, I used the SAP Netweaver Gateway Productivity Accelerator tools and the Workflow template starter app as a starting point. The truth is, it’s a great starting point, but to achieve my goals and get the app to the quality and functionality I was aiming for, it did require an entire refactor/rewrite of most of the UI Generated code. It was definitely a great reference to assist in understanding how the OData SDK functions, and is probably advisable to use either as a reference or starting point for your first Gateway consuming app. For the next Android app I write, I will probably just use the proxy generation tool and manually write the code for the UI, as it ends up being a lot of rework to change things to how you want it.

Building offline capabilities


As OData is predominantly designed for online scenarios. This meant that the app generated would connect each time to the gateway server, and re-download the same data every time the app was loaded. As this is highly inefficient, I needed to figure out a way to persist the data so that it is saved between sessions, and then only delta updates are performed. I also wanted to include offline capabilities so the user can view and action work items while offline, and sync them when back online.


I tried experimenting with the use of MBO’s which consumed the OData services, but this approach did not work very well. I felt as if all the benefits and great features you get from the OData SDK were lost.

I then started considering building a SQL lite database. This process would have worked, but would have been quite time consuming, especially considering my intent to build an iOS version as well, it would require me to rebuild the data model for each platform.

I started using a different approach, which I wrote a blog about a few months ago, see Building offline native apps with Gateway and LBO’s

The approach of using LBO's has really worked great, you still get all the benefits of the Object API generated code that you would get from MBO's, excluding the synchronization to the backend, as that is done using the OData SDK. It did require manual mapping of the gateway service proxy objects to the LBO's, however this really wasn't too much effort . I also had to handle the delta updates manually.

I think the greatest benefit comes in now that I am building an iOS version of the app. I can just generate the Object API code for iOS or other supported platform without needing to redesign the data model.


However, with the talk of OData potentially offering offline capabilities in future, this use of LBO’s may become redundant, at which time I will revisit this approach.


Dealing with delta updates

OData Delta Query Support is a feature in SAP Netweaver Gateway. But due to the fact that delta support requires handling of the delta token on the server side, which I don’t believe the Workflow Services is using, in addition to the current constraint that is mentioned in the SAP Help: “Deleted records are not supported at present”, I opted to build custom logic for the handling of delta updates.

As a workflow inbox has the possibility of new items as well as items being removed from a person’s inbox, I opted for a checklist approach. After the initial inbox load, which retrieves the entire inbox, the subsequent calls use the $select query parameter to only return a checklist of keys of work items for the user. The checklist is then compared against the local database. Removing any keys for work items that no longer exist and creating a list of new work items that don’t yet exist on the device. If there are no new items, it will not do anything further, If there are new items, it will do subsequent query with a $filter for the work items it needs to retrieve, so only the required data is downloaded.

Although I do not necessarily believe this approach is ideal, it definitely does work well for this scenario. Going forward I intend to use push notifications for better delta support.

In other scenarios, it would probably be advisable to try and use the OData Delta Query Support for delta updates.

Performance Considerations

By using the $select query parameter, I am only retrieving the properties that are required by the client, thereby reducing the response size.


For data that is needed upfront, $expand is being used to retrieve data from navigational properties in one single call, instead of retrieving it individually. For all other details such as work item details, they are retrieved only when the user clicks on the item, but are then persisted so they are read from the local database subsequent times, only checking for new updates of comments and attachments from then on.


JSON support is not yet available in OData SDK 2.3. I have heard that it will probably be available later this year, and when it is I intend to convert the $format from Atom XML to JSON.

I have recently been running some tests to see the difference between the response size for the exact same query of a really large result set in XML vs JSON. The XML response was 6.82MB and the same response in JSON was 3.64MB, which is around 54% of the size of the Atom XML. So it’s very apparent that JSON is undoubtedly the best choice.

Then by adding in content-encoding gzip compression, you would be able to get the response down to around 240KB for XML and 130KB for JSON for the above scenario.


Compression is king

After initially not doing anything about compressing the response data, I decided to do some investigation and noticed how incredibly important compression of the data really is. By default, the code generated by the Gateway Productivity accelerator and the SDMConnectivityHelper class it generates, does not add in “Content-Encoding”.

When running a test on a read request without compression, the response size was 278KB. After compressing the response by adding in “ContentEncoding=gzip, deflate” to the header of the request, the response size was decreased to a mere 10KB. That’s 3.5% of the original response size, making this absolutely essential to reduce network traffic and increase performance.


The amount that the response is compressed by will be determined by the content type. Plain text will compress at a higher ratio than an already compressed image.

I ran 3 tests comparing the size of the XML response body, for a small, medium and large scenario:


No compression

With GZIP Compression

Compression ratio

Test 1 – Small response

24.8KB

1.25KB

95%

Test 2 – Medium response

278KB

10KB

96.4%

Test 3 – Large response

1290KB

31.88KB

97.5%

Complexities encountered

One of the biggest complexities I had was around how to display detailed information for the work item, considering each work item type would require different information. The description returned contains the work item text as setup in the workflow definition, however it is returned unformatted text and isn’t really very useful.

After investigating, I decided to make use of the Workflow Services Extensible Elements Customer Properties (XPROPS) to store the items details and use a metadata driven dynamic content population approach in the app. The Workflow Services framework offers a Badi which can be used to populate the Extensible Elements XPROPS as name value pairs. By populating this with the data as well as special tags, the app is able to read the data and format it properly using dynamically created native UI elements. 

See screenshot of dynamically generated work item details.

Native Android UI/UX Design

With UI/UX being something I am absolutely passionate about, I believe that one of the greatest benefits of native is in the superior UI/UX. I also believe it is of utmost importance to abide by the specific platforms design patterns and best practices.

Android users do not like to use native apps which look and behave like an iOS app.


With Android having such a massive developer ecosystem, one of the greatest things is the abundance of resources, open source libraries and tools to use in assisting with your development.

I thought I would mention some that I found most useful:

13 Comments
Labels in this area