Rebuild required after changing xml layout files in Android Studio

前端 未结 4 1199
甜味超标
甜味超标 2020-12-10 16:08

I am developing android applications and I am using Android Studio.

There is a problem though. When I change the source and I run the app it works fine, But

相关标签:
4条回答
  • 2020-12-10 16:22

    First, Thank you Saeed Enterzari above.

    Second, We should care about this: Those res scr dirs in 'res.srcDirs' should exist, otherwise, you have to rebuild your project every time once your changed your xml files.

    This is what Saeed Enterzari said, but we can simply it.

    sourceSets{
         main  {
             manifest.srcFile 'src/main/AndroidManifest.xml'
             java.srcDirs = ['src/main/java', '.apt_generated']
             aidl.srcDirs = ['src/main/aidl', '.apt_generated']
             res.srcDirs = [
                'src/main/res',
                'src/main/test',
                'src/main/login',
                'src/main/main',
                'src/main/includes'
            ]
        }
    }
    

    After

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs'] 
            res.srcDirs = ['src/main/res']
        }
    }
    
    0 讨论(0)
  • 2020-12-10 16:31

    I resolved my problem by not using nested resource folders. I have multiple resource folders though. The workaround is creating your additional resource folders beside your res folder not inside it. My gradle changes like this:

    sourceSets{
         main  {
             manifest.srcFile 'src/main/AndroidManifest.xml'
             java.srcDirs = ['src/main/java', '.apt_generated']
             aidl.srcDirs = ['src/main/aidl', '.apt_generated']
             res.srcDirs = [
                'src/main/res',
                'src/main/test',
                'src/main/login',
                'src/main/main',
                'src/main/includes'
            ]
        }
    }
    

    All the changes in additional resource folders now take effect without cleaning and rebuilding the project. I hope it helps you.

    0 讨论(0)
  • 2020-12-10 16:38

    The solution is not to have nested resources directories. Keep all your layouts under /res/layout/ folder. You can short them using some prefix like test_xxxx, or login_xxxx.

    Anyway, for some reason Gradle is only taking count of the changes in the layout main directory when it makes an incremental build. The changes in any other sub folder will not be noticed until you make a clean and a complete rebuild of the project.

    If anyone knows how to include resources sub-folders and avoid that problem at the same time please let me know...

    0 讨论(0)
  • 2020-12-10 16:44

    Here is an updated way to get the same effect regardless of flavor config:

    android.applicationVariants.all { variant ->
      tasks.named("generate${variant.name.capitalize()}Resources").configure { mergeResourceTask ->
        mergeResourceTask.outputs.upToDateWhen { false }
      }
      tasks.named("merge${variant.name.capitalize()}Resources").configure { mergeResourceTask ->
        mergeResourceTask.outputs.upToDateWhen { false }
      }
    }
    

    This is still an absolutely terrible workaround to the root issue. It nullifies any up to date or task output caching that would otherwise make your non resource changed builds much faster by skipping these tasks.

    The correct fix which is the accepted answer, is to not use nested resource directories as the android gradle plugin originally was designed to support. By not nesting the task inputs should be declared correctly when adding directories to the source sets and gradle will correctly determine when to run the tasks.

    If you still want to nest your resource dirs then please read through this readme: https://github.com/davebren/ResourceNestingExample Specifically this: The quirk is that you can't declare a container resource folder before you declare that folder's child resource folders.

    My original answer:

    A hacky and inefficient workaround is this.

    In your module_dir/build.gradle add the following code.

    afterEvaluate {
      def flavors = []
      def types = []
    
      android.applicationVariants.all { variant ->
        def flyp = variant.name.split("(?=\\p{Upper})")
        if (!flavors.contains(flyp[0]))
        {
            flavors.add(flyp[0])
        }
        if (!types.contains(flyp[1]))
        {
            types.add(flyp[1])
        }
      }
    
      tasks.all { Task task ->
    
        for (String fl : flavors)
        {
          for (String ype : types)
            {
                if (task.name.contains("generate${fl.capitalize()}${ype.capitalize()}Resources") || 
                    task.name.contains("merge${fl.capitalize()}${ype.capitalize()}Resources"))
                {
                    task.outputs.upToDateWhen { false }
                }
            }
        }
    }
    

    This will make the gradle build regenerate and merge the resources for every build. This loss of incremental generation on top of being a loop that is three levels deep makes this a terrible blob of code.

    Before adding this in my project with a single java line changed builds in ~31 seconds and ~35 after adding it in.

    Hope they fix the plugin soon.

    0 讨论(0)
提交回复
热议问题