- 浏览: 5097017 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
silence19841230:
先拿走看看
SpringBoot2.0开发WebSocket应用完整示例 -
wallimn:
masuweng 写道发下源码下载地址吧!三个相关文件打了个包 ...
SpringBoot2.0开发WebSocket应用完整示例 -
masuweng:
发下源码下载地址吧!
SpringBoot2.0开发WebSocket应用完整示例 -
masuweng:
SpringBoot2.0开发WebSocket应用完整示例 -
wallimn:
水淼火 写道你好,我使用以后,图标不显示,应该怎么引用呢,谢谢 ...
前端框架iviewui使用示例之菜单+多Tab页布局
转自:http://www.cnblogs.com/chenjie0949/p/4778042.html
引言:经过上两篇的论述,我们已经从代码到架构都简单的熟悉了一遍,理论上,只要知道android app的编译过程,我们大可以自己写一份用gradle编译app的插件,插件内将将整个流程用Task的依赖串联起来。现在我们看看gradle是怎么做的。
复习,android 编译流程
面试中经常出现的问题,android的编译流程。这个问题十分简单和好记。android是用java来开发的,所以最基本的流程和java一致:.java -> .class。android有着自己独特的虚拟机环境dalvik,毕竟arm架构寄存器比较多,而是内存较小,所以要转换一下.class -> .dex。再说资源那条线,第一件事当然是生成R.java文件了,这个java文件和我们一般的java文件并没有区别,不然我们代码怎么用呢,然后是将资源文件和dex文件打包成apk:rec+.dex=.apk。有了.apk,签名.signed.apk,压缩.aligned.signed.apk。当然还有其他的分支,比如 .aidl,可以理解成一种特殊的资源文件,同样生成.java文件和我们的代码对接,jni也是同样,只是生成顺序是我们写java端的,当然这无关紧要,符合接口约定就可以。
主线: .java --(java)-->.class--(dex)-->.dex +rec --(apkbuild)-->.apk--(jarSigne)-->.Singed.apk--(zipalign)-->.aligned.signed.apk
设置属性即可
我们用android studio 创建一个android app程序,打开他的build.gradle。
android studio的好处是我们能方便的看到源码,鉴于上两篇把整个代码组织流程已经推敲过,所以整个脚本并没有什么难以理解的地方。
开头第一句导入 com.android.application 的编译插件,下面则是对整个编译的参数进行设置(和第二篇的最后一个例子如出一辙,不过例子上的代码很简化)。我们按住ctr,鼠标左击第三行的android,就可以进入这个属性的源码:AppExtension.groovy,它继承于TestedExtension.groovy,又继承于BaseExtension.groovy。看这一长串的extension,结合我们上一篇的例子,不难猜出这是需要绑定在project里的extension 属性。我们看下BaseExtension的源码:
在整个android app的编译流程用的工具,在这个类中基本都可以设置属性,设置的方式当然是我们一直用的闭包。随便举个例子,我们想设置下apk签名,工具当然是jarSign,搜索下jarSign,没有,换个sign,就能找到import com.android.build.gradle.internal.dsl.SigningConfig,进入SigningConfig类,所有和签名有关的代码一目了然了。用闭包的方法设置就是:
建议把BaseExtension的代码大致浏览下,基本的编译设置都能找到。
我认为学习技术开始无需太过关注细节,主流程通了,实现技术了然于心,下面的事查下帮助文档就可以了。额,贴个帮助文档的地址把:
http://avatarqing.github.io/Gradle-Plugin-User-Guide-Chinese-Verision/
引言:经过上两篇的论述,我们已经从代码到架构都简单的熟悉了一遍,理论上,只要知道android app的编译过程,我们大可以自己写一份用gradle编译app的插件,插件内将将整个流程用Task的依赖串联起来。现在我们看看gradle是怎么做的。
复习,android 编译流程
面试中经常出现的问题,android的编译流程。这个问题十分简单和好记。android是用java来开发的,所以最基本的流程和java一致:.java -> .class。android有着自己独特的虚拟机环境dalvik,毕竟arm架构寄存器比较多,而是内存较小,所以要转换一下.class -> .dex。再说资源那条线,第一件事当然是生成R.java文件了,这个java文件和我们一般的java文件并没有区别,不然我们代码怎么用呢,然后是将资源文件和dex文件打包成apk:rec+.dex=.apk。有了.apk,签名.signed.apk,压缩.aligned.signed.apk。当然还有其他的分支,比如 .aidl,可以理解成一种特殊的资源文件,同样生成.java文件和我们的代码对接,jni也是同样,只是生成顺序是我们写java端的,当然这无关紧要,符合接口约定就可以。
主线: .java --(java)-->.class--(dex)-->.dex +rec --(apkbuild)-->.apk--(jarSigne)-->.Singed.apk--(zipalign)-->.aligned.signed.apk
设置属性即可
我们用android studio 创建一个android app程序,打开他的build.gradle。
apply plugin: 'com.android.application' android { compileSdkVersion 21 buildToolsVersion "23.0.0 rc2" defaultConfig { applicationId "suning.com.myapplication" minSdkVersion 15 targetSdkVersion 21 versionCode 1 versionName "1.0" } sourceSets{ } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.2.0' }
android studio的好处是我们能方便的看到源码,鉴于上两篇把整个代码组织流程已经推敲过,所以整个脚本并没有什么难以理解的地方。
开头第一句导入 com.android.application 的编译插件,下面则是对整个编译的参数进行设置(和第二篇的最后一个例子如出一辙,不过例子上的代码很简化)。我们按住ctr,鼠标左击第三行的android,就可以进入这个属性的源码:AppExtension.groovy,它继承于TestedExtension.groovy,又继承于BaseExtension.groovy。看这一长串的extension,结合我们上一篇的例子,不难猜出这是需要绑定在project里的extension 属性。我们看下BaseExtension的源码:
/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.build.gradle import com.android.SdkConstants import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.api.BaseVariant import com.android.build.gradle.api.TestVariant import com.android.build.gradle.api.VariantFilter import com.android.build.gradle.internal.CompileOptions import com.android.build.gradle.internal.ExtraModelInfo import com.android.build.gradle.internal.LoggingUtil import com.android.build.gradle.internal.SdkHandler import com.android.build.gradle.internal.SourceSetSourceProviderWrapper import com.android.build.gradle.internal.coverage.JacocoExtension import com.android.build.gradle.internal.dsl.AaptOptions import com.android.build.gradle.internal.dsl.AdbOptions import com.android.build.gradle.internal.dsl.AndroidSourceSetFactory import com.android.build.gradle.internal.dsl.BuildType import com.android.build.gradle.internal.dsl.DexOptions import com.android.build.gradle.internal.dsl.GroupableProductFlavor import com.android.build.gradle.internal.dsl.LintOptions import com.android.build.gradle.internal.dsl.PackagingOptions import com.android.build.gradle.internal.dsl.ProductFlavor import com.android.build.gradle.internal.dsl.SigningConfig import com.android.build.gradle.internal.dsl.Splits import com.android.build.gradle.internal.dsl.TestOptions import com.android.builder.core.AndroidBuilder import com.android.builder.core.BuilderConstants import com.android.builder.model.SourceProvider import com.android.builder.sdk.TargetInfo import com.android.builder.testing.api.DeviceProvider import com.android.builder.testing.api.TestServer import com.android.sdklib.repository.FullRevision import com.google.common.collect.Lists import groovy.transform.CompileStatic import org.gradle.api.Action import org.gradle.api.GradleException import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.gradle.api.tasks.SourceSet import org.gradle.internal.reflect.Instantiator /** * Base 'android' extension for all android plugins. * * <p>This is never used directly. Instead, *<ul> * <li>Plugin <code>com.android.application</code> uses {@link AppExtension}</li> * <li>Plugin <code>com.android.library</code> uses {@link LibraryExtension}</li> * </ul> */ public abstract class BaseExtension { private String target private FullRevision buildToolsRevision /** Default config, shared by all flavors. */ final ProductFlavor defaultConfig /** Options for aapt, tool for packaging resources. */ final AaptOptions aaptOptions /** Lint options. */ final LintOptions lintOptions /** Dex options. */ final DexOptions dexOptions /** Options for running tests. */ final TestOptions testOptions /** Compile options */ final CompileOptions compileOptions /** Packaging options. */ final PackagingOptions packagingOptions /** JaCoCo options. */ final JacocoExtension jacoco /** * APK splits options. * * <p>See <a href="http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits">APK Splits</a>. */ final Splits splits /** All product flavors used by this project. */ final NamedDomainObjectContainer<GroupableProductFlavor> productFlavors /** Build types used by this project. */ final NamedDomainObjectContainer<BuildType> buildTypes /** Signing configs used by this project. */ final NamedDomainObjectContainer<SigningConfig> signingConfigs private ExtraModelInfo extraModelInfo protected Project project /** Adb options */ final AdbOptions adbOptions; /** A prefix to be used when creating new resources. Used by Studio */ String resourcePrefix List<String> flavorDimensionList private String defaultPublishConfig = "release" private boolean publishNonDefault = false private Closure<Void> variantFilter private final List<DeviceProvider> deviceProviderList = Lists.newArrayList(); private final List<TestServer> testServerList = Lists.newArrayList(); private final AndroidBuilder androidBuilder private final SdkHandler sdkHandler protected Logger logger private boolean isWritable = true; /** * The source sets container. */ final NamedDomainObjectContainer<AndroidSourceSet> sourceSetsContainer BaseExtension( @NonNull ProjectInternal project, @NonNull Instantiator instantiator, @NonNull AndroidBuilder androidBuilder, @NonNull SdkHandler sdkHandler, @NonNull NamedDomainObjectContainer<BuildType> buildTypes, @NonNull NamedDomainObjectContainer<GroupableProductFlavor> productFlavors, @NonNull NamedDomainObjectContainer<SigningConfig> signingConfigs, @NonNull ExtraModelInfo extraModelInfo, boolean isLibrary) { this.androidBuilder = androidBuilder this.sdkHandler = sdkHandler this.buildTypes = buildTypes this.productFlavors = productFlavors this.signingConfigs = signingConfigs this.extraModelInfo = extraModelInfo this.project = project logger = Logging.getLogger(this.class) defaultConfig = instantiator.newInstance(ProductFlavor, BuilderConstants.MAIN, project, instantiator, project.getLogger()) aaptOptions = instantiator.newInstance(AaptOptions) dexOptions = instantiator.newInstance(DexOptions) lintOptions = instantiator.newInstance(LintOptions) testOptions = instantiator.newInstance(TestOptions) compileOptions = instantiator.newInstance(CompileOptions) packagingOptions = instantiator.newInstance(PackagingOptions) jacoco = instantiator.newInstance(JacocoExtension) adbOptions = instantiator.newInstance(AdbOptions) splits = instantiator.newInstance(Splits, instantiator) sourceSetsContainer = project.container(AndroidSourceSet, new AndroidSourceSetFactory(instantiator, project, isLibrary)) sourceSetsContainer.whenObjectAdded { AndroidSourceSet sourceSet -> ConfigurationContainer configurations = project.getConfigurations() createConfiguration( configurations, sourceSet.getCompileConfigurationName(), "Classpath for compiling the ${sourceSet.name} sources.") String packageConfigDescription if (isLibrary) { packageConfigDescription = "Classpath only used when publishing '${sourceSet.name}'." } else { packageConfigDescription = "Classpath packaged with the compiled '${sourceSet.name}' classes." } createConfiguration( configurations, sourceSet.getPackageConfigurationName(), packageConfigDescription) createConfiguration( configurations, sourceSet.getProvidedConfigurationName(), "Classpath for only compiling the ${sourceSet.name} sources.") createConfiguration( configurations, sourceSet.getWearAppConfigurationName(), "Link to a wear app to embed for object '${sourceSet.name}'.") sourceSet.setRoot(String.format("src/%s", sourceSet.getName())) } sourceSetsContainer.create(defaultConfig.name) } /** * Disallow further modification on the extension. */ public void disableWrite() { isWritable = false } protected checkWritability() { if (!isWritable) { throw new GradleException( "Android tasks have already been created.\n" + "This happens when calling android.applicationVariants,\n" + "android.libraryVariants or android.testVariants.\n" + "Once these methods are called, it is not possible to\n" + "continue configuring the model.") } } protected void createConfiguration( @NonNull ConfigurationContainer configurations, @NonNull String configurationName, @NonNull String configurationDescription) { logger.info("Creating configuration ${configurationName}.") Configuration configuration = configurations.findByName(configurationName) if (configuration == null) { configuration = configurations.create(configurationName) } configuration.setVisible(false); configuration.setDescription(configurationDescription) } /** * Sets the compile SDK version, based on full SDK version string, e.g. * <code>android-21</code> for Lollipop. */ void compileSdkVersion(String version) { checkWritability() this.target = version } /** * Sets the compile SDK version, based on API level, e.g. 21 for Lollipop. */ void compileSdkVersion(int apiLevel) { compileSdkVersion("android-" + apiLevel) } void setCompileSdkVersion(int apiLevel) { compileSdkVersion(apiLevel) } void setCompileSdkVersion(String target) { compileSdkVersion(target) } void buildToolsVersion(String version) { checkWritability() buildToolsRevision = FullRevision.parseRevision(version) } /** * <strong>Required.</strong> Version of the build tools to use. * * <p>Value assigned to this property is parsed and stored in a normalized form, so reading it * back may give a slightly different string. */ String getBuildToolsVersion() { return buildToolsRevision.toString() } void setBuildToolsVersion(String version) { buildToolsVersion(version) } /** * Configures the build types. */ void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) { checkWritability() action.execute(buildTypes) } /** * Configures the product flavors. */ void productFlavors(Action<? super NamedDomainObjectContainer<GroupableProductFlavor>> action) { checkWritability() action.execute(productFlavors) } /** * Configures the signing configs. */ void signingConfigs(Action<? super NamedDomainObjectContainer<SigningConfig>> action) { checkWritability() action.execute(signingConfigs) } public void flavorDimensions(String... dimensions) { checkWritability() flavorDimensionList = Arrays.asList(dimensions) } /** * Configures the source sets. Note that the Android plugin uses its own implementation of * source sets, {@link AndroidSourceSet}. */ void sourceSets(Action<NamedDomainObjectContainer<AndroidSourceSet>> action) { checkWritability() action.execute(sourceSetsContainer) } /** * All source sets. Note that the Android plugin uses its own implementation of * source sets, {@link AndroidSourceSet}. */ NamedDomainObjectContainer<AndroidSourceSet> getSourceSets() { sourceSetsContainer } /** * The default configuration, inherited by all build flavors (if any are defined). */ void defaultConfig(Action<ProductFlavor> action) { checkWritability() action.execute(defaultConfig) } /** * Configures aapt options. */ void aaptOptions(Action<AaptOptions> action) { checkWritability() action.execute(aaptOptions) } /** * Configures dex options. * @param action */ void dexOptions(Action<DexOptions> action) { checkWritability() action.execute(dexOptions) } /** * Configure lint options. */ void lintOptions(Action<LintOptions> action) { checkWritability() action.execute(lintOptions) } /** Configures the test options. */ void testOptions(Action<TestOptions> action) { checkWritability() action.execute(testOptions) } /** * Configures compile options. */ void compileOptions(Action<CompileOptions> action) { checkWritability() action.execute(compileOptions) } /** * Configures packaging options. */ void packagingOptions(Action<PackagingOptions> action) { checkWritability() action.execute(packagingOptions) } /** * Configures JaCoCo options. */ void jacoco(Action<JacocoExtension> action) { checkWritability() action.execute(jacoco) } /** * Configures adb options. */ void adbOptions(Action<AdbOptions> action) { checkWritability() action.execute(adbOptions) } /** * Configures APK splits. */ void splits(Action<Splits> action) { checkWritability() action.execute(splits) } void deviceProvider(DeviceProvider deviceProvider) { checkWritability() deviceProviderList.add(deviceProvider) } @NonNull List<DeviceProvider> getDeviceProviders() { return deviceProviderList } void testServer(TestServer testServer) { checkWritability() testServerList.add(testServer) } @NonNull List<TestServer> getTestServers() { return testServerList } public void defaultPublishConfig(String value) { setDefaultPublishConfig(value) } public void publishNonDefault(boolean value) { publishNonDefault = value } /** * Name of the configuration used to build the default artifact of this project. * * <p>See <a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Referencing-a-Library"> * Referencing a Library</a> */ public String getDefaultPublishConfig() { return defaultPublishConfig } public void setDefaultPublishConfig(String value) { defaultPublishConfig = value } /** * Whether to publish artifacts for all configurations, not just the default one. * * <p>See <a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Referencing-a-Library"> * Referencing a Library</a> */ public boolean getPublishNonDefault() { return publishNonDefault } void variantFilter(Closure<Void> filter) { setVariantFilter(filter) } void setVariantFilter(Closure<Void> filter) { variantFilter = filter } /** * A variant filter to control which variants are excluded. * <p>The filter is a closure which is passed a single object of type * {@link com.android.build.gradle.internal.api.VariantFilter}. It should set the * {@link VariantFilter#setIgnore(boolean)} flag to filter out the given variant. */ public Closure<Void> getVariantFilter() { return variantFilter; } void resourcePrefix(String prefix) { resourcePrefix = prefix } abstract void addVariant(BaseVariant variant) public void registerArtifactType(@NonNull String name, boolean isTest, int artifactType) { extraModelInfo.registerArtifactType(name, isTest, artifactType) } public void registerBuildTypeSourceProvider( @NonNull String name, @NonNull BuildType buildType, @NonNull SourceProvider sourceProvider) { extraModelInfo.registerBuildTypeSourceProvider(name, buildType, sourceProvider) } public void registerProductFlavorSourceProvider( @NonNull String name, @NonNull ProductFlavor productFlavor, @NonNull SourceProvider sourceProvider) { extraModelInfo.registerProductFlavorSourceProvider(name, productFlavor, sourceProvider) } @CompileStatic public void registerJavaArtifact( @NonNull String name, @NonNull BaseVariant variant, @NonNull String assembleTaskName, @NonNull String javaCompileTaskName, @NonNull Collection<File> generatedSourceFolders, @NonNull Iterable<String> ideSetupTaskNames, @NonNull Configuration configuration, @NonNull File classesFolder, @NonNull File javaResourceFolder, @Nullable SourceProvider sourceProvider) { extraModelInfo.registerJavaArtifact(name, variant, assembleTaskName, javaCompileTaskName, generatedSourceFolders, ideSetupTaskNames, configuration, classesFolder, javaResourceFolder, sourceProvider) } public void registerMultiFlavorSourceProvider( @NonNull String name, @NonNull String flavorName, @NonNull SourceProvider sourceProvider) { extraModelInfo.registerMultiFlavorSourceProvider(name, flavorName, sourceProvider) } @NonNull public SourceProvider wrapJavaSourceSet(@NonNull SourceSet sourceSet) { return new SourceSetSourceProviderWrapper(sourceSet) } /** * <strong>Required.</strong> Compile SDK version. * * <p>Your code will be compiled against the android.jar from this API level. You should * generally use the most up-to-date SDK version here. Use the Lint tool to make sure you don't * use APIs not available in earlier platform version without checking. * * <p>Setter can be called with a string like "android-21" or a number. * * <p>Value assigned to this property is parsed and stored in a normalized form, so reading it * back may give a slightly different string. */ public String getCompileSdkVersion() { return target } public FullRevision getBuildToolsRevision() { return buildToolsRevision } public File getSdkDirectory() { return sdkHandler.getSdkFolder() } public File getNdkDirectory() { return sdkHandler.getNdkFolder() } public List<File> getBootClasspath() { ensureTargetSetup() return androidBuilder.getBootClasspath() } public File getAdbExe() { return sdkHandler.getSdkInfo().adb } public File getDefaultProguardFile(String name) { File sdkDir = sdkHandler.getAndCheckSdkFolder() return new File(sdkDir, SdkConstants.FD_TOOLS + File.separatorChar + SdkConstants.FD_PROGUARD + File.separatorChar + name); } // --------------- // TEMP for compatibility // STOPSHIP Remove in 1.0 // by default, we do not generate pure splits boolean generatePureSplits = false; void generatePureSplits(boolean flag) { if (flag) { logger.warn("Pure splits are not supported by PlayStore yet.") } this.generatePureSplits = flag; } private boolean enforceUniquePackageName = true public void enforceUniquePackageName(boolean value) { if (!value) { LoggingUtil.displayDeprecationWarning(logger, project, "Support for libraries with same package name is deprecated and will be removed in 1.0") } enforceUniquePackageName = value } public void setEnforceUniquePackageName(boolean value) { enforceUniquePackageName(value) } public getEnforceUniquePackageName() { return enforceUniquePackageName } private void ensureTargetSetup() { // check if the target has been set. TargetInfo targetInfo = androidBuilder.getTargetInfo() if (targetInfo == null) { sdkHandler.initTarget( getCompileSdkVersion(), buildToolsRevision, androidBuilder) } } }
在整个android app的编译流程用的工具,在这个类中基本都可以设置属性,设置的方式当然是我们一直用的闭包。随便举个例子,我们想设置下apk签名,工具当然是jarSign,搜索下jarSign,没有,换个sign,就能找到import com.android.build.gradle.internal.dsl.SigningConfig,进入SigningConfig类,所有和签名有关的代码一目了然了。用闭包的方法设置就是:
android{ signingConfigs { releaseConfig { keyAlias 'stone' keyPassword 'mypwd' storeFile file('/Users/stone/Documents/project_AS/myapplication/stone.keystore') storePassword 'mypwd' } } }
建议把BaseExtension的代码大致浏览下,基本的编译设置都能找到。
我认为学习技术开始无需太过关注细节,主流程通了,实现技术了然于心,下面的事查下帮助文档就可以了。额,贴个帮助文档的地址把:
http://avatarqing.github.io/Gradle-Plugin-User-Guide-Chinese-Verision/
发表评论
-
gradle编译错误:Could not find method compile() for arguments
2020-09-19 10:50 18174编译(IDEA+Gradle)一个别人的工程,出现一个 ... -
netty心跳检查之UDP篇
2019-09-15 08:50 2099部分UDP通信场景中,需要客户端定期发送心跳信息,以获取终 ... -
解决tomcat部署两个SpringBoot应用提示InstanceAlreadyExistsException
2019-06-30 11:49 3159两个SpringBoot应用部署在一个Tomcat中,单独 ... -
Eclipse配置MyBatis代码自动化功能
2019-06-29 10:16 16321.安装插件 Eclipse中,Help->Ecli ... -
vue.js中使用qrcode生成二维码
2019-05-20 00:00 7553一、安装包 npm install qrcodejs2 --s ... -
MySQL插入数据报错: Incorrect string value: '\xFD\xDE'
2019-03-31 23:19 1168我MySQL数据库用的uft-8字符集,插入数据一直很正常 ... -
vue自定义组件并双向绑定属性
2019-03-08 22:46 3201做了两个子组件,原理基本一样,一个是使用原生的select ... -
vue-router简单示例
2019-03-05 00:32 1083写个基本完整、稍有借鉴意义的示例,防止自己忘记。 &l ... -
“联通充值系统繁忙”轻松应对
2019-02-06 11:03 3893大过年的,联通充个值一直报“充值系统繁忙”。昨天晚上试了几 ... -
electron.js数据库应用---导航菜单(element-ui+mysql)
2019-02-05 21:33 2290一、环境搭建 略, ... -
electron.js数据库应用---入门(mysql+element-ui)
2019-01-27 23:19 7298我的机器:Windows10,64 ... -
SpringMVC 在controller层中注入成员变量request,是否线程安全
2018-12-17 21:17 2684@RestController public class ... -
VueJS 组件参数名命名与组件属性转化
2018-12-03 00:00 1999转自:https://www.cnblogs.com/meiy ... -
vue-resource拦截器实现token发送及检验自动化
2018-11-16 22:38 3034用了很长时间vue-resource,最近思考$http发 ... -
element-ui试用手记
2018-10-29 20:25 1678element-ui、iviewui都以vue.js为基础 ... -
iviewui中表格控件中render的使用示例
2018-07-07 16:46 9707示例了如何在表格中显示按钮,如何将代码转化为文字。 i ... -
Tomcat错误“Alias name tomcat does not identify a key entry”解决
2018-07-05 21:39 6163申请到了阿里云的证书后,下载、按照说明生成jks格式证书、 ... -
阿里云免费证书“fileauth.txt内容配置错误”解决
2018-07-05 20:43 5188最近研究微信小程序开发,上阿里云申请了个证书,使用文件验证 ... -
springboot2.0跨域配置
2018-07-04 22:11 5229springboot2.0跨域配置: 一、代码 ... -
微信小程序使用code换openid的方法(JAVA、SpringBoot)
2018-07-01 21:52 10288微信小程序序的代码中提示,使用code换取openid,但 ...
相关推荐
3.进入一堆乱码的文件夹,比如bzyivzo6n839fup2jbap0tjew 4.不要删除里面的.lck和.part等文件,直接拷贝下载的gra dle-3.3-all.zip文件到该目录 5.重启android studio即可。(官方下载地址:...
Android Studio运行项目时出现 Download https://services.gradle.org/distributions/gradle-3.3-all.zip 21 s 147 ms 是因为这个文件处在外网服务器,下载很慢所以连接总是中断,因此可以自行下载,然后 打开C盘...
1,官网下载地址https\://services.gradle.org/distributions/gradle-3.3-all,不同版本更改版本号即可,官网下载不成功的,嫌官网下载速度慢的,可以直接在这里下载 2,更多版本gradle*.zip资源包参见...
1,官网下载地址https\://services.gradle.org/distributions/gradle-3.3-all,不同版本更改版本号即可,官网下载不成功的,嫌官网下载速度慢的,可以直接在这里下载 2,更多版本gradle*.zip资源包参见...
1,官网下载地址https://services.gradle.org/distributions/gradle-3.3-all,不同版本更改版本号即可,官网下载不成功的,嫌官网下载速度慢的,可以直接在这里下载 2,更多版本gradle*.zip资源包参见...
Android 开发配置studio gradle 插件文件:pom、jar; 该资源包含gradle-2.2.3的插件文件;
Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章。 APK包是一个ZIP...
下载的离线包,没有实在太慢了,分享给大家。 原文件下载地址 https://services.gradle.org/distributions/gradle-4.10.1-all.zip
官网下载不成功的,可以直接在这里下载。 官网原下载地址:https://services.gradle.org/distributions/
官网下载不成功的,可以直接在这里下载。 原地址:https://services.gradle.org/distributions/
官网下载不成功的,可以直接在这里下载。 官网原下载地址:https://services.gradle.org/distributions/
官网下载速度慢,可以来自己下载,快速通道,无需等待,官网的链接https://services.gradle.org/distributions/
官网下载不成功的,可以直接在这里下载。 官网原下载地址:https://services.gradle.org/distributions/
官网下载不成功的,嫌官网下载速度慢的,可以直接在这里下载。 官网原下载地址:https://services.gradle.org/distributions/
gradle-6.7-all.zip https://code.aliyun.com/kar/gradle-all-zip/raw/master/gradle-6.7-all.zip gradle-6.6.1-all.zip https://code.aliyun.com/kar/gradle-all-zip/raw/master/gradle-6.6.1-all.zip gradle-6.6-...
官网下载不成功的,嫌官网下载速度慢的,可以直接在这里下载。 官网原下载地址:https://services.gradle.org/distributions/
android studio 配置gradle 使用android.mk进行编译jni,简单的jni调用,使用android.mk进行编译,注意事项:app下的gradle,以及编译生成的 .h文件,复制修改为 .cpp时,里面的文件的宏逻辑,最好去掉这个宏(#...
打开目录 ~/.gradle/wrapper/dists 查看当前已经下载了什么版本的 gradle 修改项目的 gradle/wrapper/gradle-wrapper.properties 文件 distributionUrl=https\://services.gradle.org/distributions/gradle
gradle-4.6-all下载 gradle-4.6-all下载 gradle-4.6-all下载 gradle-4.6-all下载
= JMH Gradle Plugin :jmh-version: 1.21 :plugin-version: 0.4.8 image:http://img.shields.io/travis/melix/jmh-gradle-plugin/master.svg["Build Status (travis)", link=...