Skip to Content

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.

/wp-content/uploads/2013/10/small_web2013_10_10_05_35_49_299449.png

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:

To report this post you need to login first.

13 Comments

You must be Logged on to comment or reply to a post.

  1. Ricky Symonds

    Both of your blogs about this project have been excellent, well done and thank you for taking the time. I look forward to trying out some of these ideas for myself.

    (0) 
    1. Brad Pokroy Post author

      Thanks Ricky, happy to hear that they are useful to people. There are so many great blogs that have helped me along the way, its good to be able to contribute back.

      (0) 
    1. Brad Pokroy Post author

      Thanks Raj, I was was quite surprised at how big a difference the compression made, I suppose its the same as when you zip a text/xml file on your computer, its compresses at around 97% ratio.

      (0) 
  2. Muzaffar Fazel Hussain

    Wow Thanks Brad Pokroy! Well detailed series and what proves really useful is the additional resources you have shared which reduces the overhead of “resource-searching” while developing Native apps based on NWGW. So shall we wait for your experience on iOS next? 😉

    (0) 
    1. Brad Pokroy Post author

      Thanks Muzaffar, happy to hear you found it useful. The iOS version is still a few months away. But there will definitely be another blog about that 🙂

      (0) 
  3. Mark Teichmann

    Great blog. Especially the details on offline and performance are very interesting.

    I stumbled upon this blog because I am migrating a HWC workflow app from SMP 2.3 to SMP 3.0 currently. While the data flow via DCN and RFC worked quite well I am aware now that I have to rewrite the app completely in order to change it to OData WFSERVICE and Kapsel.

    Now OData Offline support is not available for Kapsel in Version 3.0. But offline approval and having the attachments available offline is very important. Now I do not knw what alternative I should choose. I definitely do not want to use deprecated features like MBO, LBO etc. But I also do not like to build native apps as well. But maybe building offline support manually into Kapsel would take so much time that it would be faster to build an Android and iOS native app in the same time?

    Or I wait until SMP 3.1 where Kapsel may include offline support? Really hard to decide here 🙁

    (0) 
    1. Brad Pokroy Post author

      Hi Mark,

      Thanks for your feedback. Interesting dilemma you face there.

      I do agree with you about not wanting to use deprecated technologies such as MBO’s and LBO’s. I am currently busy on the iOS version of this app and have moved away from LBO’s and have started using the SMP3.0 SDK’s which include offline support. Unfortunately I haven’t done enough with the offline capabilities yet to speak about it. Im still hoping it meets all my requirements.

      I’m not sure if you have used the Gateway Productivity Accelerator Tools yet, but they are a great way to kickstart the development, and by generating a starter app, even if completely change it and do your own thing, it gives you a good idea and example on how to use the OData SDK’s. I have only used it for Android and iOS, not UI5 yet.

      Sounds like your best option right now would be a custom plugin for Kapsel per platform, which would require native development. But as you said, it makes you wonder whether its more worthwhile doing the whole thing native as in that case, a huge part of the app will end up being platform dependent. What platforms is the HWC workflow app currently running on?

      Good luck with this, would be interested to know how you eventually end up building it.

      (0) 

Leave a Reply