如何避免在源代码中使用应用程序的包名?

时间:2015-10-05 15:23:22

标签: java android

我的Android应用源代码包含以下行:

import lfreytag.TideNowOR.R;

为了在不同的项目中使用这个源代码,我想 从导入中删除包名称,因为我必须每次更改它 项目。我正在使用Android Studio。在基于此源代码的其他应用程序中,包名称的最后部分会有所不同,例如TideNowOR,TideNowWA,TideNowCA等。

作为背景,我试图将所有特定于版本的信息放在RAW目录中作为简单的文本文件。所以我可以生成一个新版本,只需更改清单并转储到新的文本文件集合中。感谢。

6 个答案:

答案 0 :(得分:4)

您可以将其打包成Android Library Project(AAR)。这样您就可以在不同的程序中共享代码和资源。

答案 1 :(得分:4)

Android Studio Flavors 打招呼!

您不仅可以使用一个命令创建多个版本,而且对于每个版本,您可以指定自己的包名称和文件夹结构。

我会更多地谈论这一点,但已经有很多人在整个网站上做过这个。

这是一个很棒的链接:Using Build Flavors - Structuring source folders and build.gradle correctly

答案 2 :(得分:3)

长话短说,不要担心更改Java包名称。实际上,我会删除它中的任何特定标识符,以便它是通用的,如com.lfreytag.tidenow。

当引入新的Gradle构建系统时,他们增加了将包名拆分为两种用途的可能性。一个是Java包名称:这是您在import语句中的所有Java代码中引用的名称,它构成了保存.java文件的目录结构。另一个用途是为Android包管理器标识您的应用程序的名称,现在称为applicationId。两者可以不同,因此您可以使用相同的代码。

根据您在AndroidManifest.xml中设置的“package”生成R文件。这应该是您更通用的Java包名称。在app的build.gradle中,将applicationId设置为您希望Android操作系统了解的特定标识符,其中可能包含您正在构建的状态的名称。有关这方面的更多信息,请访问:http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename

Gradle很酷的一点是你可以使用flavor来为你设置applicationId,如果你设置正确的话,它可以足够聪明地在构建过程中包含正确的文件。

例如,在build.gradle中,在android.productFlavors节点中定义不同的风格,如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.lfreytag.tidenow"
        minSdkVersion 7
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    productFlavors {
        wa {
            applicationId "com.lfreytag.tidenow.wa"
        }

        or {
            applicationId "com.lfreytag.tidenow.or"
        }

        ca {
            applicationId "com.lfreytag.tidenow.ca"
        }

        ... etc ...
    }

    buildTypes {
        ...
    }
}

dependencies {
    ...
}

然后,在您的src目录中,创建名称与flavor相同的新子目录,例如src / wa,src /或src / ca等。在每个目录中,放置特定于flavor的java,资源,资产和其他目录。

当您选择要构建的风格时,无论是通过Android Studio中的Build Variants面板还是通过gradle,例如./gradlew assembleWaDebug,Gradle将足够智能地覆盖src / main中的值和文件您的风味目录中的特定内容。

答案 3 :(得分:2)

使用java时,请记住该包是实际允许程序员保持代码组织的命名空间。请检查this oracle's link以了解它是什么以及为什么需要它。

现在,是否可以在源代码中不使用该包? 可能是,但肯定不是很方便,因为你必须告诉编译器在哪里找到你需要的所有类,这意味着要设置一个非常繁重的类路径(了解类路径here)。

你可能会为非常简单的Java应用程序执行此操作,但是谁知道你需要为更复杂的应用程序做什么样的工作,比如Android应用程序。

总之.. 如果没有破坏,请不要尝试修复

答案 4 :(得分:0)

首先,创建一个将遍历您的文件并更改包名称的脚本并不困难。因此,如果你真的只想更改软件包名称,我会运行一个脚本来更改软件包名称和中提琴,你有一个新的应用程序。

但是,我会根据您的情况建议这种方法:

  1. 创建Android Studio项目
  2. 让您现在的“应用程序”成为“库”模块
  3. 拥有尽可能多的“应用程序”模块,您可以继承该库
  4. “applications”中的strings.xml将覆盖库中的strings.xml。
  5. 因此,不要试图将字符串放入Raw目录,而是使用strings.xml作为Android的设计。 Android Gradle编译器非常智能。如果您在库模块和app模块的strings.xml中定义了相同的字符串,它将选择应用程序模块的字符串。这样,您就可以使用不同的字符串实现多个应用程序。

    编辑:

    另一种可能的解决方案是在项目中包含所有文件,然后根据标准切换为每个应用程序显示的文件 - 例如应用程序的名称或包名称。有Context.getPackageName()但不能在import语句中使用。

    另一个编辑:

    基本上,通过选择将文件放入“原始”目录,您将文件绑定到package.R import。如果你使用了资产文件夹,你就可以解决这个问题。

答案 5 :(得分:0)

我并不是100%肯定你在问什么,但我认为这个问题是基于一些我想消除的误解。

import lfreytag.TideNowOR.R;

导入对特定模块(http://developer.android.com/sdk/installing/create-project.html#SettingUpLibraryModule)中定义的资源的引用。这些资源包括res文件夹中的所有内容(字符串,ID,绘图,布局等)。

此导入必须包含程序包名称,因为该名称是代码的名称空间。命名空间是所有现代编程语言的基本元素,可避免多个共享同一名称的标识符之间发生名称冲突。

在不同项目中使用公共代码的方法(假设您使用Android Studio和Gradle构建)是:

  1. 创建一个单独的项目,并将该项目作为依赖项添加到您的不同应用中,例如,这里:Android studio add external project to build.gradle
  2. 创建一个库模块并在app模块中引用该模块: http://developer.android.com/sdk/installing/create-project.html#SettingUpLibraryModule
  3. 使用flavor来使用不同的包名称和"特定于版本的信息"
  4. 在前两种情况下,构建工具将处理"转换"您的库lfreytag.TideNowOR包名称为您的应用包名称lfreytag.TideNowWA或您需要的任何内容。它基本上会创建一个aar包,以便在其他项目/模块中重用。

    从您的说明选项3看起来似乎是最好的选择,我想解释一下如何构建项目以便能够拥有公共代码和不同的应用程序"。

    enter image description here

    屏幕截图显示了我的一个项目,其中有一个主节点,您希望在不同的"应用程序中重复使用您的lfreytag.TideNowOR代码。它可以包含典型Android项目的所有元素,例如资源文件夹中的实际Java代码,资源文件和文件。

    该应用程序有不同的口味,这些口味映射到你所指的" apps" (在屏幕截图中,风味是免费的,pro和pro_amazon节点)。

    flavor是您应用的变体,可以定义自己的包名,拥有自己的清单,设置要在清单中使用的变量(例如应用名称或ContentProvider权限)或代码(用于区分不同的标志)味道,味道特定的字符串等。)。

    要在清单中为不同的口味(或您的" apps")使用不同的包名称,您可以在构建文件中定义applicationId,如下所示:

        defaultConfig {
            applicationId "lfreytag.TideNowOR"
        }
    
        productFlavors {
            wa {
                applicationId "lfreytag.TideNowWA"
            }
            ca {
                applicationId 'lfreytag.TideNowCA'
            }
    // .. more flavors
        }
    

    为您拥有的不同口味使用不同的应用名称:

    defaultConfig {
        manifestPlaceholders = [appName: "Tide Now Oregon"]
    }
    wa {
        manifestPlaceholders = [appName: "Tide Now Washington"]
    }
    

    在构建文件和以下清单中:

    <application
        android:name="MyApp"
        android:label="${appName}"
    

    如前所述,你可以做更多的事情,但这应该足以作为一个例子。 Quintessential是构建文件放置味道的地方或者#34; app&#34;特定配置,而所有特定于风味的文件都进入相应的文件夹(原始文件,资产文件,资源文件,代码,清单)。 构建应用程序时,每个风格都内置到apk中,因此风味确实成为您的应用程序&#34;。