TL;DR – Boring and monotonous, find & replace process. If someone has some tips to reduce the manual nature of the below process, please shout!
As part of an effort to add backwards compatibility to a project, (reducing the minimum Android version from 21 to 16), one of the hurdles was adding support for the old
After resolving all of the lint warnings due to the old margins (left & right) that were used by other developers, I was now kicking myself. However, this increase in backwards compatibility could not be foreseen and until this point, supporting only one type of margin was the right thing to do; it was a light kick.
Where do I begin sorting all of these margins?
ConstraintLayout is heavily used in the app and margins play a big part. Regex; the thing I forget immediately after using it for what I need it for and have to relearn every time.
So I tested my little regex snippet in a file of my on-boarding flow (the first I reach):
Cmd + Rin my layout
- In the top box (find), entered
- In the bottom box (replace), entered
- Make sure the Regex checkbox is selected and hit Replace.
I won’t go into detail on the workings of Regex, but suffice it to say, I am capturing the amount of space at the beginning of the original line and also the value of the
marginStart property. These captured properties are then referenced in the replace as
Lo and behold, it worked. I then got cocky and used the Replace all button for that file and carried on even further, modifying my inputs for
paddingEnd. With one file down, I was starting to get optimistic.
Before doing something drastic, which I already had planned, I decided I should probably commit the change to fix that build issue just in case something goes wrong with this. I’ve been stung by things like this before and not easily been able to recover!
Without further ado,
Find & Replace All!
Cmd + Shift + R
- Follow exactly the same approach as above with the separate input boxes.
Replaceif you’re feeling boring,
Replace Allif you like to live dangerously.
I of course had some errors, just like this one:
Execution failed for task ‘:app:mergeAppDevelopDebugResources’.
> java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource compilation failed
/Users/stustirling/Projects/app-android/app/src/main/res/layout/item_pay_activity_header.xml:10: error: duplicate attribute.
This was, of course, due to there already being an
android:layout_marginLeft in the layout file which I expected there to be some occurrences of. Just removing one of the attributes did the trick but was monotonous removing them manually. This led me to looking into conditionally matching
marginStart only if
marginLeft wasn’t already present in the XML object.
I am not a Regex wizard and I struggled with this, so I turned to trusty StackOverflow and asked the question. Whilst I was initially met some very unhelpful close requests, which I did not agree with, a nice chap went to the effort to explain his solution and gave me an online demo. Armed with this new regex, I discarded all my changes so far and tried again with the following Find.
This is great for finding if the
marginLeft occurs after the
marginStart however it could be present before. Therefore I went back to the original poster to ask for some additional assistance when I couldn’t work it out. Very helpfully he gave me the following.
The problem was
\K is not a valid character in Java regex. I was stumped and again, after looking around for the solution and not finding it I decided to move forward with just the forward check. Something is better than nothing and at this point I had wasted enough time!
When trying to implement the first regex given, I noticed that it didn’t cater for
marginStart attributes on a different line to the closing tag
/>. In all honesty, I’d had enough, couldn’t work it out and in the grand scheme of things, spent more time than if I’d just stuck with the original method. Regex, you win again! Scrap that.
Back on Track
So back to the initial method. I tried to find how to run through the entire module in one go and for it to report all of the errors but for some reason I couldn’t nail it down. So, it was the manual, monotonous approach.
To attempt to reduce the amount of jumping between files, I decided to run each of the
Find & Replaces at once and fix each of them as I jumped into a file.
Then it was a case of the following steps, over and over again. To be honest it only took 20 minutes 🤦♂️
CMD + F9or
Build > Make Project.
- Find the
.xmlfile listed as the cause of the compilation failure. This is listed in the
- Search for the file –
CMD + Shift + O
- Delete any duplicate attributes.
If my regex knowledge was up to scratch, or if I had time to learn it myself I could have probably avoided the process of removing all of the duplicate attributes manually. However, as it was, without the tangent of trying to find the complicated find regex, the process probably would have taken around 30 minutes.
Hope this helps someone. If you have some suggestions or know how to do some of the things I didn’t please comment below.