将google-play-services库导入到Intellij IDEA 12(和13)中

36
我想将Google Play服务库导入(并使用)现有的Android项目,但我遇到了一个依赖问题。
所有由Google编写的文档都基于Eclipse。我们使用IntelliJ IDEA。
我知道以下几件事情:
- 我知道如何在IntelliJ中导入模块、库、添加依赖等。 - 我也知道根据Google的入门指南,你必须将google-play-services-lib作为“项目”(通过将现有代码导入工作区)添加到(Eclipse)中,在IntelliJ中可以通过从现有代码添加新模块来完成。这是相同的过程,只是名称不同。 - 我也理解Eclipse中Order and Export选项卡的作用(IntelliJ也有类似功能)。
我已经完成的工作:
  • 出于安全考虑,我将Android SDK中的google-play-services_lib文件夹复制到了我的项目根目录。所以,我在同一层级下有/myprj和/google-play-services_lib(我还有/facebooksdk和/actionbarsherlock在同一层级下),然后进行了“导入模块”(从现有源)的操作。然后点击下一步,下一步,下一步……(它起作用了,被识别了)。

项目结构看起来像这样(名称故意模糊):

Project Structure

  • 这正确地添加了一个模块(如上面的截图所示)。现在我需要添加依赖项,以便我的主项目知道这个模块。我进入我的模块列表,选择我的主模块,然后选择依赖项选项卡。我可以看到几个库(Joda time、android-query、gson等),以及两个模块FacebookSDKactionbarsherlock。到目前为止一切正常。这时事情就变得奇怪了。

我尝试添加的依赖项.

注意:在大多数情况下,我尝试勾选和取消导出复选框,并同时尝试将其添加到sherlockbar模块中进行测试。我知道这些是很多组合,但没办法。

1)添加一个JAR或目录(知道这是错误的,我还是试了试),并指向Google Play Module / libs中的.jar文件,名为:google-play-services.jar。

2)添加一个(然后将其添加到项目中)。

3) 添加模块依赖项,(同时选择我的主要项目)。 这将显示一个弹出窗口,如下图所示:

add dependency

问题

虽然我可以引用PlusClient并且我的导入是正确的,但是当我尝试在我的布局XML中添加一个SignInButton时,我会收到一个错误。

没有必要贴上整个XML布局,因为它没有任何奇怪的地方,只是一个RelativeLayout和一些textviews。我像这样添加了g+按钮:

  <com.google.android.gms.common.SignInButton
    android:id="@+id/sign_in_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/logo_login"
    android:layout_marginBottom="30dip" />

就像谷歌所说的那样。

第一个迹象表明可能有问题的是,IntelliJ警告您该元素“在此处无效”,但我认为这是视觉设计师的限制而不是真正的问题。

然而,当我运行项目时,我得到了这个:

07-30 17:50:44.854: ERROR/ActivityThread(22324): Failed to inflate
    android.view.InflateException: Binary XML file line #22: Error inflating class com.google.android.gms.common.SignInButton
    at android.view.LayoutInflater.createView(LayoutInflater.java:606)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
    at com.actionbarsherlock.internal.ActionBarSherlockNative.setContentView(ActionBarSherlockNative.java:134)
    at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:262)
    at com.myapp.ui.activities.LoginSignupActivity.onCreate(LoginSignupActivity.java:64)
    at android.app.Activity.performCreate(Activity.java:4465)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2033)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2104)
    at android.app.ActivityThread.access$600(ActivityThread.java:132)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1157)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4575)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    at android.view.LayoutInflater.createView(LayoutInflater.java:586)
    ... 24 more
    Caused by: java.lang.NoClassDefFoundError: com.google.android.gms.R$drawable
    at com.google.android.gms.internal.aa.b(Unknown Source)
    at com.google.android.gms.internal.aa.a(Unknown Source)
    at com.google.android.gms.common.SignInButton.c(Unknown Source)
    at com.google.android.gms.common.SignInButton.d(Unknown Source)
    at com.google.android.gms.common.SignInButton.setStyle(Unknown Source)
    at com.google.android.gms.common.SignInButton.<init>(Unknown Source)
    at com.google.android.gms.common.SignInButton.<init>(Unknown Source)
    ... 27 more

以下是引起我注意的代码行:

Caused by: java.lang.NoClassDefFoundError: com.google.android.gms.R$drawable

下一个异常如下:

07-30 17:50:44.870: ERROR/AndroidRuntime(22324): FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.ui.activities.LoginSignupActivity}: android.view.InflateException: Binary XML file line #22: Error inflating class com.google.android.gms.common.SignInButton
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2079)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2104)
    at android.app.ActivityThread.access$600(ActivityThread.java:132)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1157)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4575)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: android.view.InflateException: Binary XML file line #22: Error inflating class com.google.android.gms.common.SignInButton
    at android.view.LayoutInflater.createView(LayoutInflater.java:606)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
    at com.actionbarsherlock.internal.ActionBarSherlockNative.setContentView(ActionBarSherlockNative.java:134)
    at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:262)
    at com.myapp.ui.activities.LoginSignupActivity.onCreate(LoginSignupActivity.java:64)
    at android.app.Activity.performCreate(Activity.java:4465)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2033)
    ... 11 more
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    at android.view.LayoutInflater.createView(LayoutInflater.java:586)
    ... 24 more
    Caused by: java.lang.NoClassDefFoundError: com.google.android.gms.R$drawable
    at com.google.android.gms.internal.aa.b(Unknown Source)
    at com.google.android.gms.internal.aa.a(Unknown Source)
    at com.google.android.gms.common.SignInButton.c(Unknown Source)
    at com.google.android.gms.common.SignInButton.d(Unknown Source)
    at com.google.android.gms.common.SignInButton.setStyle(Unknown Source)
    at com.google.android.gms.common.SignInButton.<init>(Unknown Source)
    at com.google.android.gms.common.SignInButton.<init>(Unknown Source)
    ... 27 more

如果我从布局中删除代码,它就能正常工作。 我的想法是这与Android处理资源的方式有关,因此它可能找不到按钮的资源。 有人成功地使用过:Intellij Idea(12+)与ActionbarSherlock和Google+图书馆吗? 如果有,怎么做? :)

3
请查看:https://dev59.com/seo6XIcBkEYKwwoYORwV#15826818。 - Hesam
谢谢!我已经搜索过了,但大多数帖子都是关于旧版本或Eclipse的。 - Martin Marconcini
可能是重复问题:java.lang.noclassdeffounderror:com.google.android.gms.R$styleable - Martin Marconcini
1个回答

95

基于历史原因,我将重现我的做法,取自这里。非常感谢@Hesam发现了它。我会投票关闭整个问题。

注意:这些快捷键适用于OS X和Intellij 12和13。

确保您拥有最新的SDK / ADT工具和播放服务。它们不断更改并且通常不向后兼容。

更新我不得不再次这样做,所以这是我所做的内容的精细版本。

您需要复制一份(而不是直接从SDK文件夹中使用它),因为如果Google更新它,当您更新SDK时,事情将会破裂,将其保留副本更安全(尽管更繁琐,因为您必须手动更新新版本发布时)。 我发现决定何时更新比惊讶于加密编译错误更好。

考虑到这一点,请将库与您的项目一起复制。 您应该有一个看起来像这样的文件夹结构:

/something/yourmainmodule/

/something/any_other_module/

/something/modules.xml

/something/README.md(如果您使用github):)

该库位于

"ANDROID-SDK"/extras/google/google_play_services/lib_project/google-play-services_lib

ANDROID-SDK是您下载SDK时存储的位置。 Google会不时更改此内容,因此只需找到它即可。

将整个文件夹复制到您的项目中,因此现在您的项目看起来像这样:

/something/yourmainmodule/

/something/any_other_module/

/something/google-play-services_lib/ <-- 这是新的

/something/modules.xml

/something/README.md

好的,现在让我们以正确的方式将其导入到IntelliJ-IDEA中:

1)从项目面板(⌘ 1)中选择您的项目/主模块,然后按⌘↓以打开项目结构窗口,或者只需执行"File -> Project Structure"。

2)从左侧面板中选择模块,然后点击+按钮(或⌘ N),然后选择"导入模块",并导航到刚刚复制到项目模块文件夹旁边的google-play-services_lib(/something/)。

向导会询问一系列问题,只需点击下一步,默认值即可,但要阅读正在发生的事情,了解正在发生的事情,这是Java、Android和Intellij的核心概念。如果不知道每个对话框在说什么(或者为什么有些可能为空),可以进行实验。

完成后,Google Play项目将添加到模块中,与您的项目一起。

不要关闭此窗口(或者如果您关闭了它请再次打开)。

3)在模块中,仍然选择您的项目/模块,然后从右侧面板(它是一个选项卡)选择"依赖项",最后点击底部的+按钮(或者如果您在此选项卡上具有焦点,则可以使用⌘ N),然后从弹出窗口中选择"3个模块依赖项…",并选择您在上一步添加的"google-play-services_lib"。它应该在那里。如果不在,说明您没有在步骤2中添加该模块。

4)最后,再次点击+按钮(或⌘ N),但这次选择"1个jar或目录…",导航到上面路径的"/libs"文件夹,并选择"google-play-services.jar"。

5) 点击“确定”并关闭项目结构窗口。

如果您完成了此操作,您的主模块应该有一个类似于这样的依赖项:

Dependencies

还要确保在项目结构窗口的 FACETS 选项卡中,Google Play Services已经被勾选为“库模块”,因为它是一个库模块。

注意: 确保您没有将“google-play-services_lib”项目添加到“库”(在“模块”下的左面板)。如果您已经添加了它,可以去“库”中简单地将其删除。Google Play库不应出现在库中

来源: 此文本来自这个StackOverflow答案


嗨@Martin,我按照您在IntelliJ 12上的指示操作。 但是在第2步,我无法选择“导入模块”。 IntelliJ提示我选择要导入的项目,我浏览到文件夹并选择了Eclipse“外部模型”,然后点Next,再下一步=> 错误:没有要导入的内容。 通常导入外部项目应该会显示一些模块。 有什么想法吗? 谢谢。 - EyeQ Tech
@TungMaiLe 我不确定发生了什么。你是否选择了正确的文件夹(.../libproject/google-play-services_lib)? - Martin Marconcini
3
嘿,更新:如果我选择“从源代码创建”而不是选择Eclipse的“外部模型”,那么一切都很好。感谢您对上面发帖者的回答。 - EyeQ Tech
在IntelliJ中的google_play_services模块中,我还需要将google_play_services.jar作为该模块的库添加,并选择“导出”复选框 - 这样,这个依赖模块就会将jar(其中包含所有代码,其余部分为空)贡献给我的模块。 - Andrew Mackenzie
@Andrew 我本来不需要这样做,很奇怪。你应该将那个 jar 文件作为你模块的库添加进去(参见步骤 3 和 4)。 - Martin Marconcini
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接