Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Studio stale APK for build variant after xml changes

This is a very strange one. Today AS (1.4) stopped correctly re-creating the debug apk in my project:

  • Any XML changes are not reflected in the code when running the project
  • Changes to Java code are propagating, even when the XML changes are not
  • Cleaning and then hitting run seems to fix it, an updated APK is successfully created every time.
  • I have two build variants in my project, this problem only affects one of them.
  • I am using Genymotion, but the problem exists on the regular emulator and hardware as well.
  • I suspect there is some kind of lock being placed on the xml files. For example if I rename a file and hit run, the changes propagate. But inspecting the R.java shows entries for both the old file name and the new one - the old one is simply not being cleared / refreshed.
  • The xml layout I'm testing this with has now been stripped back to a blank relative layout with a background color. The color is not being updated when it should be.

I don't really know much about the build process, so all I have tried is deleting the build folder, re-importing the project and the old restart / invalidate cache on Android Studio. Any suggestions as to what might cause this strange behavior or how to fix it?

Edit: It's very difficult to pin down the behavior behind this - sometimes I've noticed it consistently affecting only certain xml files. Looks like this guy has the same issue: Android Studio project build issue

I've spent a couple hours reinstalling Android Studio from scratch and the issue remains..

like image 902
Daniel Wilson Avatar asked Oct 25 '15 00:10

Daniel Wilson


2 Answers

Daniel, I've definitely noticed this issue myself as well. It seems that some changes simply won't propagate unless ADB detects that the app isn't currently installed on a target device.

Disclaimer: This is a workaround, rather than an explanation of the behavior, but it works for me. To fix the issue, I configured my Run Configurations to uninstall the package in question before installing again. Be mindful that uninstalling an APK will obviously affect things such as databases, persistent data from preferences, etc, so don't use this if you're development process relies on those.

Steps: (from here)

  1. In Android Studio, click the drop down list to the left of Run button, and select Edit configurations...
  2. Click on app under Android Application, and in General Tab, find the heading 'Before Launch'
  3. Click the + button, select Run external tool, click the + button in the popup window.
  4. Give some name (Eg adb uninstall) and description, and type adb in Program: and uninstall <your-package-name> in Parameters:. Make sure that the new item is selected when you click Ok in the popup window.

Note: If you do not have adb in your PATH environment variable, give the full path to adb in Program: field (eg /home/user/android/sdk/platform-tools/adb).

Again, sorry that's not an explanation of the issue itself, but this definitely fixes the issue for me.

Let me know how it works for you.

like image 163
stack_overflow_user Avatar answered Oct 12 '22 21:10

stack_overflow_user


I actually figured out the issue here a while ago and it was pretty subtle. My project has build variants with a main source set as well as a source set for each variant. It was defined somewhat like this:

sourceSets {

    def defaultDirectory = "src/main/"
    def flavorADirectory = "src/flavor_a/"

    flavor_a {
        java.srcDirs = [defaultDirectory + 'java', flavorADirectory + 'java']
        res.srcDirs = [defaultDirectory + 'res', flavorADirectory + 'res']
        manifest.srcFile flavorADirectory + 'AndroidManifest.xml'
    }

    def flavorBDirectory = "src/flavor_b/"

    flavor_b{
        java.srcDirs = [defaultDirectory + 'java', flavorBDirectory + 'java']
        res.srcDirs = [defaultDirectory + 'gift', flavorBDirectory + 'res']
        manifest.srcFile flavorBDirectory + 'AndroidManifest.xml'
    }
}

So the variants compiled fine, but every xml change was triggering a complete rebuild. I'm not sure the exact reasoning behind it, but I believe the main sourceset must be specified as a separate entity. Android Studio must see the main keyword and know better what to do with it. That means there is no need to specify the default directory as part of the build variant source sets Removing that like so, makes the problem go away and no more constant rebuilds occur:

 sourceSets {

    def defaultDirectory = "src/main/"

    main {
        java.srcDirs = [defaultDirectory + 'java']
        res.srcDirs = [defaultDirectory + 'res']
    }

    def flavorADirectory = "src/flavor_a/"

    flavor_a {
        java.srcDirs = [flavorADirectory + 'java']
        res.srcDirs = [flavorADirectory + 'res']
        manifest.srcFile flavorADirectory + 'AndroidManifest.xml'
    }

    def flavorBDirectory = "src/flavor_b/"

    flavor_b{
        java.srcDirs = [flavorBDirectory + 'java']
        res.srcDirs = [flavorBDirectory + 'res']
        manifest.srcFile flavorBDirectory + 'AndroidManifest.xml'
    }
}
like image 44
Daniel Wilson Avatar answered Oct 12 '22 21:10

Daniel Wilson