Android,Gradle,产品风味和清单(Android, Gradle, product flavors and the manifest)
在
build.gradle
,我设置了产品口味:productFlavors { AlternateFlavour { applicationId "com.myapp.alternateflavour" } }
然后在sourceSets部分,我为这些风格使用不同的资源,资产和清单目录:
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } AlternateFlavour { manifest.srcFile 'manifest-tmp/AlternateFlavour/AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res-tmp/AlternateFlavour'] assets.srcDirs = ['assets-tmp/AlternateFlavour'] } }
好吧,至今。
在那种部分自动生成的风味中使用的清单中,我有:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp.myapp" android:versionCode="1010001" android:versionName="V1.1.0.1" >
但在根项目中的原始清单如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp.myapp" android:versionCode="1010000" android:versionName="V1.1.0.DEBUG" >
这会导致Gradle失败:
Error: Attribute manifest@versionCode value=(1010001) from AndroidManifest.xml:4:5-28 is also present at AndroidManifest.xml:4:5-28 value=(1010000). Attributes of <manifest> elements are not merged.
为什么它试图与原始的清单合并,当我指定它应该看别处?
我怎样才能阻止呢?
我希望有人会质疑为什么我这样做,或者为什么我不使用建议的风味项目结构。 那么,我需要一个正常的清单,在Gradle之外使用,例如从Eclipse进行部署(请一次一个!),并且我还需要通过构建过程注入的版本。
In
build.gradle
, I have product flavors set up:productFlavors { AlternateFlavour { applicationId "com.myapp.alternateflavour" } }
Then in the sourceSets section, I use different resource, assets and manifest directories for those flavours:
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } AlternateFlavour { manifest.srcFile 'manifest-tmp/AlternateFlavour/AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res-tmp/AlternateFlavour'] assets.srcDirs = ['assets-tmp/AlternateFlavour'] } }
OK so far.
In that manifest being used by the flavor, which is in part automatically generated, I have:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp.myapp" android:versionCode="1010001" android:versionName="V1.1.0.1" >
but in the original manifest in the root project is as follows:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp.myapp" android:versionCode="1010000" android:versionName="V1.1.0.DEBUG" >
This causes Gradle to fail:
Error: Attribute manifest@versionCode value=(1010001) from AndroidManifest.xml:4:5-28 is also present at AndroidManifest.xml:4:5-28 value=(1010000). Attributes of <manifest> elements are not merged.
Why is it trying to merge with the original manifest at all, when I've specified it should look elsewhere?
And how can I stop this?
I expect some will question why I'm doing it this way at all, or indeed why I'm not using the suggested flavor project structure. Well, I need a normal manifest to use outside of Gradle, e.g. for deploying from Eclipse (one thing at a time please!) and I also need versions to be injected by the build process.
原文:https://stackoverflow.com/questions/35796317
最满意答案
正如其他人所说,问题是存储到数组中的内存位置:
x[i][j]
。 这里有一些洞察力为什么:你有一个二维阵列,但计算机内存本身就是一维的。 所以当你想像这样你的阵列:
0,0 | 0,1 | 0,2 | 0,3 ----+-----+-----+---- 1,0 | 1,1 | 1,2 | 1,3 ----+-----+-----+---- 2,0 | 2,1 | 2,2 | 2,3
您的计算机将其作为单行存储在内存中:
0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3
在第二个例子中,您可以首先循环访问第二个数组,即:
x[0][0] x[0][1] x[0][2] x[0][3] x[1][0] etc...
意思是你按顺序击中他们。 现在看第一版。 你在做:
x[0][0] x[1][0] x[2][0] x[0][1] x[1][1] etc...
由于C在内存中布置了2-d阵列,所以你要求它跳过这个地方。 但现在为踢球者:为什么这么重要? 所有内存访问是一样的,对吗?
否:因为缓存。 来自您的内存的数据将以小块(称为“高速缓存线”)传递给CPU,通常为64字节。 如果你有4个字节的整数,那就意味着你在一个整齐的小包中连续16个整数。 获取这些内存块实际上相当慢; 您的CPU可以在单个缓存行加载所需的时间内进行大量工作。
现在回顾一下访问顺序:第二个例子是(1)抓取16个int的块,(2)修改它们,(3)重复4000 * 4000/16次。 这很好,快,CPU总是有一些工作。
第一个例子是(1)抓住16个int的块,(2)只修改其中一个,(3)重复4000 * 4000次。 这将要求内存中“提取”数量的16倍。 您的CPU实际上必须花时间坐在等待这个记忆显示,而当它坐在你周围浪费宝贵的时间。
重要的提示:
现在你有答案,这里有一个有趣的注释:没有固有的原因,你的第二个例子必须是快速的。 例如,在Fortran中,第一个例子是快速的,第二个例子是缓慢的。 这是因为,不要将事情扩展到像C这样的概念“行”,Fortran扩展成“列”,即:
0,0 | 1,0 | 2,0 | 0,1 | 1,1 | 2,1 | 0,2 | 1,2 | 2,2 | 0,3 | 1,3 | 2,3
C的布局叫做“row-major”,Fortran被称为“column-major”。 您可以看到,知道您的编程语言是排行还是列主要都非常重要! 以下是更多信息的链接: http : //en.wikipedia.org/wiki/Row-major_order
As others have said, the issue is the store to the memory location in the array:
x[i][j]
. Here's a bit of insight why:You have a 2-dimensional array, but memory in the computer is inherently 1-dimensional. So while you imagine your array like this:
0,0 | 0,1 | 0,2 | 0,3 ----+-----+-----+---- 1,0 | 1,1 | 1,2 | 1,3 ----+-----+-----+---- 2,0 | 2,1 | 2,2 | 2,3
Your computer stores it in memory as a single line:
0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | 1,3 | 2,0 | 2,1 | 2,2 | 2,3
In the 2nd example, you access the array by looping over the 2nd number first, i.e.:
x[0][0] x[0][1] x[0][2] x[0][3] x[1][0] etc...
Meaning that you're hitting them all in order. Now look at the 1st version. You're doing:
x[0][0] x[1][0] x[2][0] x[0][1] x[1][1] etc...
Because of the way C laid out the 2-d array in memory, you're asking it to jump all over the place. But now for the kicker: Why does this matter? All memory accesses are the same, right?
No: because of caches. Data from your memory gets brought over to the CPU in little chunks (called 'cache lines'), typically 64 bytes. If you have 4-byte integers, that means you're geting 16 consecutive integers in a neat little bundle. It's actually fairly slow to fetch these chunks of memory; your CPU can do a lot of work in the time it takes for a single cache line to load.
Now look back at the order of accesses: The second example is (1) grabbing a chunk of 16 ints, (2) modifying all of them, (3) repeat 4000*4000/16 times. That's nice and fast, and the CPU always has something to work on.
The first example is (1) grab a chunk of 16 ints, (2) modify only one of them, (3) repeat 4000*4000 times. That's going to require 16 times the number of "fetches" from memory. Your CPU will actually have to spend time sitting around waiting for that memory to show up, and while it's sitting around you're wasting valuable time.
Important Note:
Now that you have the answer, here's an interesting note: there's no inherent reason that your second example has to be the fast one. For instance, in Fortran, the first example would be fast and the second one slow. That's because instead of expanding things out into conceptual "rows" like C does, Fortran expands into "columns", i.e.:
0,0 | 1,0 | 2,0 | 0,1 | 1,1 | 2,1 | 0,2 | 1,2 | 2,2 | 0,3 | 1,3 | 2,3
The layout of C is called 'row-major' and Fortran's is called 'column-major'. As you can see, it's very important to know whether your programming language is row-major or column-major! Here's a link for more info: http://en.wikipedia.org/wiki/Row-major_order
相关问答
更多-
TCP/IP模型是一个________。[2023-05-19]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
第一种方法稍好一些,因为细胞被分配给彼此相邻。 第一种方法: [ ][ ][ ][ ][ ] .... ^1st assignment ^2nd assignment [ ][ ][ ][ ][ ] .... ^101st assignment 第二种方法: [ ][ ][ ][ ][ ] .... ^1st assignment ^101st assignment [ ][ ][ ][ ][ ] .... ^2nd assignment The first method is slight ...
-
为什么在迭代2D数组时循环的顺序会影响性能?(Why does the order of the loops affect performance when iterating over a 2D array?)[2023-05-30]
正如其他人所说,问题是存储到数组中的内存位置: x[i][j] 。 这里有一些洞察力为什么: 你有一个二维阵列,但计算机内存本身就是一维的。 所以当你想像这样你的阵列: 0,0 | 0,1 | 0,2 | 0,3 ----+-----+-----+---- 1,0 | 1,1 | 1,2 | 1,3 ----+-----+-----+---- 2,0 | 2,1 | 2,2 | 2,3 您的计算机将其作为单行存储在内存中: 0,0 | 0,1 | 0,2 | 0,3 | 1,0 | 1,1 | 1,2 | ... -
在Java中迭代数组(从2D数组中推导出1D)(Iterating through array in Java (deducing a 1D from a 2D array))[2023-04-11]
除非我忽略了一些细节,否则如果没有子路径,问题就相当微不足道了。 你只需要一个非常具体的for循环。 for (int i = 0; i < columns; i++) { Path path = new Path(array[i][0], array[i][1], array[i][2]); pathsArray.Add(path); } 那当然是伪代码,但基本上我是这样做的。 我会把每条路都变成三元组。 我仍然不太明白你打算如何存储数据,如果你把所有值都放在1D int数 ... -
在迭代简单的2D阵列时提高缓存性能?(Improving cache performance while iterating through a simple 2D array?)[2022-12-28]
如果要一次访问行的所有单元格,只需反转两个循环: for (d = 0; d < 50; d++) for (c = 0; c < 50; c++) ary[d][c] = ary[d][c] + 1; 甚至 for (d = 0; d < 50; d++) int[] array = ary[d]; for (c = 0; c < 50; c++) array[c] = array[c] + 1; 但我怀疑它有任何重大影响,甚至任何影响,特别是在 ... -
Numpy功能: 那么在这种情况下,因为dct是一个numpy函数,所以它具有内置的功能以将其应用于特定的轴。 几乎所有的numpy函数都可以在完整的数组上运行,或者可以被告知在特定的轴(行或列)上运行。 所以只需利用dct函数的axis参数即可: dct( X, axis=2) 你会得到同样的结果: >>> ( dct(X, axis=2) == np.array(map(dct, X)) ).all() True 这比在我们的(625,4,4)矩阵中使用map函数快了35倍以上: %timeit d ...
-
你有3个循环,但你只需要两个。 从文件读取的每个输入行将成为2-D数组的一行: for(int r = 0; r < 7; r++){ tempString = scnr.nextLine().split(" "); temp[r] = new double[tempString.length]; for(int c = 0; c < tempString.length; c++){ temp[r][c] = Double.pa ...
-
我怀疑的第一件事是对齐。 您可能想要尝试: __attribute__ ((align (16))) float ...[maxsize]; 或者确保maxsize是16的倍数。如果在一个配置中你是对齐的,那么肯定会导致10%的命中率,而在另一个配置中你不是。 矢量操作对此非常敏感。 你可能遇到的下一个主要问题是一个巨大的堆栈(假设maxsize相当大)。 ARM可以处理小于4k的数字,而不是处理大于4k的数字(因为它只能处理12位立即数)。 因此,根据编译器对其进行优化的方式,将amparray推向堆栈 ...
-
选项1:尝试以矢量化方式重写代码。 您可以使用这样的3x3掩码进行卷积: import numpy as np from scipy.signal import convolve2d image = np.random.random((100,100)) nbCameras = np.abs(np.random.normal(size=(100,100)).round()) maskWidth = 3 mask = np.ones((maskWidth, maskWidth)) visibilityM ...