This question already has answers here:
How to use flurry in an application?
(3 answers)
Closed 8 years ago.
How can I add flurry into my android studio project, I haven't done this before, so I am not entirely sure where to add the files? I have FlurryAnalytics.jar
and how to use in my app?
thanx
Here is how I added Flurry:
Add FlurryAnalytics_3.3.2.jar (or latest) to libs folder (create this directory if necessary)
Add compile fileTree(dir: 'libs', include: '*.jar') to the dependencies in your project's build.gradle
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
or Gradle + Jcenter compile 'com.flurry.android:analytics:6.2.0'
Add appropriate permissions to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Make sure a versionName attribute is specified in AndroidManifest.xml to have data reported under that version name, such as:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0">
Optionally, add you Flurry API key to a constants file, such as AppConstants.java:
public class AppConstants {
public static final String FLURRY_API_KEY = "YOUR_API_KEY"; // where YOUR_API_KEY is your actual API key from FLURRY similar to 1ABCDE23EFGH4IJKLMN5O
Add the Flurry onStartSession and onEndSession to each activity in your app:
#Override
protected void onStart()
{
super.onStart();
FlurryAgent.onStartSession(this, AppConstants.FLURRY_API_KEY);
}
#Override
protected void onStop()
{
super.onStop();
FlurryAgent.onEndSession(this);
}
I still had some issues at this point and selected a hint recommended by Android Studio while viewing my build.gradle file. It changed gradle-1.8-bin.zip to gradle-1.8-bin.zip to gradle-1.8-all.zip in gradle/wrapper/gradle-wrapper.properties:
distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-all.zip
After this, my project built successfully and started to log Flurry events. FYI, it takes a few hours to see the logs in Flurry.
This is a good reference for Android Studio and gradle
And of course, Flurry provided the details for much of this as well.
Related
I have a project in which I have enabled multidex to avoid 65k limit and also productFlavors (dev API 21 and prod API 19) for customization.
Building my Project on API 21 i.e dev flavor is successful but on API 19 i.e. prod flavor, it is continuously giving me exception in app task shrink{component}MultiDexComponents
Complete Error log:
:app:shrinkProdDebugMultiDexComponents FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:shrinkProdDebugMultiDexComponents'.
> java.io.IOException: Can't read [{Project Path}/app/build/intermediates/multi-dex/prod/debug/allclasses.jar] (Can't process class [com/olivephone/office/a/b/e/p.class] (Unknown verification type [17] in stack map frame))
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.0'
defaultConfig {
applicationId '{Project Name}'
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
productFlavors {
dev {
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the application.
minSdkVersion 19
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:cardview-v7:23.0.1'
compile 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.google.android.gms:play-services:8.1.0'
compile 'com.android.support:multidex:1.0.1'
compile files('libs/linkedin-j-android.jar')
compile files('libs/itsrts-pptviewer.jar')
compile files('libs/signpost-core-1.2.1.1.jar')
compile 'org.twitter4j:twitter4j-core:4.0.2'
compile files('libs/universal-image-loader-1.9.2-SNAPSHOT-with-sources.jar')
compile files('libs/dropbox-android-sdk-1.6.3.jar')
compile files('libs/json_simple-1.1.jar')
compile 'com.joanzapata.pdfview:android-pdfview:1.0.1#jar'
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
}
Any help please anyone ??
Multidex support for Android 5.0 and higher
Android 5.0 and higher uses a runtime called ART which natively
supports loading multiple dex files from application APK files. ART
performs pre-compilation at application install time which scans for
classes(..N).dex files and compiles them into a single .oat file for
execution by the Android device. For more information on the Android
5.0 runtime, see Introducing ART.
This is the reason why your app is working fine on API level 21.
Multidex support prior to Android 5.0
Versions of the platform prior to Android 5.0 use the Dalvik runtime
for executing app code. By default, Dalvik limits apps to a single
classes.dex bytecode file per APK. In order to get around this
limitation, you can use the multidex support library, which becomes
part of the primary DEX file of your app and then manages access to
the additional DEX files and the code they contain.
So, Firstly making sure you have imported correct dependency, which It seems you did it.
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
In your manifest add the MultiDexApplication class from the multidex support library to the application element.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.myapplication">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
Alternative to that, If your app extends the Application class, you can override the attachBaseContext() method and call MultiDex.install(this) to enable multidex.
public void onCreate(Bundle arguments) {
MultiDex.install(getTargetContext());
super.onCreate(arguments);
...
}
I hope it will help you out.
In API 21, :app:shrinkProdDebugMultiDexComponents command is not called as API 21 already uses ART instead of Dalvik. Thus, natively support multidex.
For API below 21, then the command :app:shrinkProdDebugMultiDexComponents is executed.
Checking your build.gradle everything looks fine, which brings me to the following.
Have you setup multidex support properly?
Have you setup your manifest to support Multidex?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.myapplication">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
OR if you actually extending the application class, you can do this:
public class MyApplication extends Application {
...
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
...
}
or use this "pre-built" version
public class MyApplication extends MultiDexApplication{
...
}
I haven't peeped into the logic behind this, but in my case, it was due to version conflicts of compile 'com.android.support:appcompat-v7:25.3.1' and compile 'com.google.android.gms:play-services:10.2.4' in my build.gradle file.
Only enabling multidex didn't work for me. While searching for the other solutions, I found some people complaining about wierd issue of version conflict of play-services. So, I backtracked the code changes and finally changed play-services version from 10.2.4 to 10.2.1 and it worked for me.
Solved above crash issue. I have remove some unused dependency and also removed rx java dependency io.reactivex.rxjava . In replacement of Rx java i have added some dummy classes in my package which is already described here https://realm.io/docs/java/latest.
// File 1
package io.reactivex;
public class Flowable {
}
// File 2
package io.reactivex;
public class Observable {
}
// File 3
package io.reactivex;
public enum BackpressureStrategy {
LATEST;
}
Please change your dependencies as below :
Edited dependencies:
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:cardview-v7:23.0.1'
compile 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.google.android.gms:play-services:8.1.0'
compile 'com.android.support:multidex:1.0.1'
compile 'com.googlecode.linkedin-j:linkedin-j-core:1.0.416'
compile 'oauth.signpost:signpost-core:1.2.1.2'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
compile 'com.googlecode.json-simple:json-simple:1.1'
compile 'org.twitter4j:twitter4j-core:4.0.2'
compile files('libs/itsrts-pptviewer.jar')
compile files('libs/dropbox-android-sdk-1.6.3.jar')
compile 'com.joanzapata.pdfview:android-pdfview:1.0.1#jar'
compile 'com.facebook.android:facebook-android-sdk:4.1.0'
Reason is that 'compile fileTree(dir: 'libs', include: ['*.jar'])' includes all jar file to gradle that is in libs folder..
Thanks.!!
The shrinkProdDebugMultiDexComponents task invokes Proguard, so this error comes from Proguard code.
My guess will be that you're not using the latest version of Olive Office SDK (which is probably obfuscated with buggy or misconfigured Proguard version). If this is the case, get the latest version from SDK developer.
For workaround, check this similar bug. Although it was closed with wontfix status, this blogpost describes how to patch the Proguard code.
Also check this and that answers by Eric Lafortune (Proguard's author) on similar issues.
This was working fine on a Windows machine but I am trying to work on a Mac now and I'm getting DexIndexOverflowException. I have multiDexEnabled true in my build.gradle. I have extended the MultiDexApplication class and that class is in my AndroidManifest file.
compile 'com.android.support:multidex:1.0.1' is in my dependencies
I still get DexIndexOverflowException. I added the following to my MultiDexApplication class and it still didn't work:
#Override
public void attachBaseContext(Context base) {
MultiDex.install(base);
super.attachBaseContext(base);
}
I had the same issue. What worked for me was to selectively compile Google Play service APIs into my app. For example, in my case I was using Google Maps API, I had this in my gradle before:
compile 'com.google.android.gms:play-services:9.6.1'
I had to change to these lines:
compile 'com.google.android.gms:play-services-maps:9.6.1'
compile 'com.google.android.gms:play-services-location:9.6.1'
so that not the whole Play Services API are compiled into my app.
I was following the Firebase guide to adding FCM, and so I added the following dependencies to my app gradle:
compile 'com.google.android.gms:play-services:9.0.0'
apply plugin: 'com.google.gms.google-services'
And this one to my project gradle:
classpath 'com.google.gms:google-services:3.0.0'
After this, I added the google-services.json from the Firebase console settings by downloading it and adding it to my app directory.
Now I'm getting this error:
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
If I follow the instructions and have my application to support multidex, my application crashes as soon as it launches.
Here is the error after adding multidex to my app:
05-20 01:25:32.253 19812-19812/com.cryogenos.pearsonvisionlimousine W/dalvikvm: VFY: unable to resolve static field 8723 (common_google_play_services_unknown_issue) in Lcom/google/android/gms/R$string;05-20 01:25:32.253 19812-19812/com.cryogenos.pearsonvisionlimousine W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x416b5e30)05-20 01:25:32.253 19812-19812/com.cryogenos.pearsonvisionlimousine E/AndroidRuntime: FATAL EXCEPTION: mainProcess: com.cryogenos.pearsonvisionlimousine, PID: 19812java.lang.NoClassDefFoundError: com.google.android.gms.R$stringat com.google.android.gms.common.internal.zzah.<init>
(Unknown Source)
at com.google.firebase.FirebaseOptions.fromResource(Unknown Source)
at com.google.firebase.FirebaseApp.zzbu(Unknown Source)
at com.google.firebase.provider.FirebaseInitProvider.onCreate(Unknown Source)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1609)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1574)
at com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown Source)
at android.app.ActivityThread.installProvider(ActivityThread.java:5643)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:5206)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5143)
at android.app.ActivityThread.access$1500(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1418)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5883)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:688)
at dalvik.system.NativeStart.main(Native Method)
My phone's google play services is 9.0.0+.
I have updated to the latest play services and the repository in SDK manager.
EDIT:
My app build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.cryogenos.pearsonvisionlimousine"
minSdkVersion 19
targetSdkVersion 23
versionCode 3
versionName "2.1"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:9.0.0'
compile 'com.mcxiaoke.volley:library:1.0.19'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:multidex:1.0.0'
compile 'com.google.firebase:firebase-messaging:9.0.0'
}
apply plugin: 'com.google.gms.google-services'
One possible way to avoid 64k Dex error is by including only those APIs which your app needs from Google Play Services.
Selectively compiling APIs into your executable
From version 6.5, you can instead selectively compile Google Play service APIs into your app. For example, to include only the Google Fit and Android Wear APIs, replace the following line in your build.gradle file:
compile 'com.google.android.gms:play-services:9.0.0'
with these lines:
compile 'com.google.android.gms:play-services-fitness:9.0.0'
compile 'com.google.android.gms:play-services-wearable:9.0.0'
UPDATED
Well I read the doc, which says
Apps that rely on the Play Services SDK should always check the device for a compatible Google Play services APK before accessing Google Play services features
So you only need to check Google Play Service is available or not. And to do this you only need Google Actions, Base Client Library API.
compile 'com.google.android.gms:play-services-base:9.0.0'
as explained in documentation use Selectively compiling APIs into your executable which is best approach for you(take it in first priority insted of Multi Dex), because Multi-dex have some limitations check before proceed.
Avoiding the 64K Limit - Proguard will help you
Before configuring your app to enable use of 64K or more method
references, you should take steps to reduce the total number of
references called by your app code, including methods defined by your
app code or included libraries. The following strategies can help you
avoid hitting the dex reference limit:
Review your app's direct and transitive dependencies - Ensure any large library dependency you include in your app is used in a manner
that outweighs the amount of code being added to the application. A
common anti-pattern is to include a very large library because a few
utility methods were useful. Reducing your app code dependencies can
often help you avoid the dex reference limit.
Remove unused code with ProGuard - Configure the ProGuard settings for your app to run ProGuard and ensure you have shrinking enabled for
release builds. Enabling shrinking ensures you are not shipping unused
code with your APKs.
Using these techniques can help you avoid the
build configuration changes required to enable more method references
in your app. These steps can also decrease the size of your APKs,
which is particularly important for markets where bandwidth costs are
high.
So, try to avoid Multi-Dex
one more thing when you use compile 'com.android.support:design:23.1.1' then you not need to use compile 'com.android.support:appcompat-v7:23.1.1' and compile 'com.android.support:support-v4:23.1.1'. so remove v7 & v4 from build.gradle file
First check if the multidex has really worked, you can do that by renaming the apk file to zip and extracting it. There should 2 multiple classes.dex files.
Secondly, it can also happen if earlier to reduce the method you must have used proguard, so just comment the use of proguard and it should work.
Otherwise paste your exception here.
Something wrong.
Checking the doc you only need this dependency
dependencies {
compile 'com.google.firebase:firebase-messaging:9.0.0'
}
So you can remove this dependency
//compile 'com.google.android.gms:play-services:9.0.0'
If it is not enough and you have more than 65536 methods you can use the multidex support.
Just add these lines in the build.gradle:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
Also in your Manifest add the MultiDexApplication class from the multidex support library to the application element
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.multidex.myapplication">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
and override attachBaseContext method:
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
MultiDex.install(this);
}
If you are using a own Application class, change the parent class from Application to MultiDexApplication.
Is there a reasonably simple way for a module's build.gradle file to indicate that certain files from a dependency should be excluded? I am specifically interested in excluding certain resources from an AAR.
LeakCanary is an interesting library for helping to track down memory leaks. However, it has an undocumented requirement of compileSdkVersion of 21 or higher. While most projects should not have a problem with this, it's unseemly for a library to require a certain compileSdkVersion without a good reason. A development team may have frozen their compileSdkVersion as part of a general policy to only change those sorts of settings as part of major version updates of their app or something.
In this case, for v1.3.1 of LeakCanary at least, the only reason compileSdkVersion is required, AFAICT, is because the AAR has a res/values-v21/ directory, containing a theme definition that inherits from Theme.Material. This theme is used by a diagnostic activity. That activity is never seen by end users, only by developers in debug builds. Frankly, what that activity looks like, theme-wise, does not really matter. Forcing a compileSdkVersion of 21 just to have that diagnostic activity have a certain theme is, IMHO, stupid.
It'd be nice if as part of a compile directive we could say "hey, please skip res/values-v21/ from this AAR, m'kay?". Since the -v21 theme is simply providing an alternative definition of a theme defined elsewhere, dropping the -v21 theme will not break the build or break things at runtime, but merely will give us a Holo-themed diagnostic activity.
I fail to see how this answer works with dependencies. I am also uncertain if it is complete, and it certainly does not appear to be supported. It also doesn't really qualify as "simple" — I would not expect somebody to try dropping this in a build.gradle file just to block a single file from a diagnostic library like LeakCanary.
So, is there something simpler than this that works with now-current editions of the Android Plugin for Gradle?
EDIT:
Wrote advanced gradle task for you:
final List<String> exclusions = [];
Dependency.metaClass.exclude = { String[] currentExclusions ->
currentExclusions.each {
exclusions.add("${getGroup()}/${getName()}/${getVersion()}/${it}")
}
return thisObject
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile ('com.android.support:appcompat-v7:20.+')
debugCompile ('com.squareup.leakcanary:leakcanary-android:1.3.1')
.exclude("res/values-v21/values-v21.xml")
releaseCompile ('com.squareup.leakcanary:leakcanary-android-no-op:1.3.1')
}
tasks.create("excludeTask") << {
exclusions.each {
File file = file("${buildDir}/intermediates/exploded-aar/${it}")
println("Excluding file " + file)
if (file.exists()) {
file.delete();
}
}
}
tasks.whenTaskAdded({
if (it.name.matches(/^process.*Resources$/)) {
it.dependsOn excludeTask
}
})
Now you can use method .exclude() on each dependency, providing into list of paths, you want to exclude from specified dependency.
Also, you can stack the .exclude() method calls.
I believe you can solve this problem more elegantly using the PackagingOptions facility of the Android Gradle Plugin DSL.
I was able to use this myself to exclude some native libraries I didn't need introduced by an AAR in my project.
android {
...
packagingOptions {
exclude '/lib/armeabi-v7a/<file_to_exclude>'
}
}
For the case outlined in the question, I believe this would work:
android {
...
packagingOptions {
exclude '/res/values-v21/<file_to_exclude>'
}
}
Try compileOnly keyword to mark the resource is used for compile only.
dependencies {
compileOnly fileTree(include: ['*.jar'], dir: 'libs')
}
I try to make Roboblender work with Roboguice but the compile time processing doesn't seem to do anything, the AnnotationDatabaseImpl class is not generated. (Project builds without error.)
I even created a sample project, please see below. What do I miss?
(I know the gradle task and the second metadata would only be needed for multi module project, but it didn't work without them either).
build.gradle:
project.tasks.withType(JavaCompile) { task ->
options.compilerArgs << "-AguiceAnnotationDatabasePackageName=gk.com.roboguice_compile"
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'org.roboguice:roboguice:3.+'
provided 'org.roboguice:roboblender:3.+'
}
manifest:
<meta-data
android:name="roboguice.modules"
android:value="gk.com.roboguice_compile.RoboguiceBindings" />
<meta-data
android:name="roboguice.annotations.packages"
android:value="gk.com.roboguice_compile" />
activity:
#ContentView(R.layout.activity_main)
public class MainActivity extends RoboActivity {
#Inject
private PresentMaker presentMaker;
bindings:
public class RoboguiceBindings extends AbstractModule {
#Override
protected void configure() {
bind(PresentMaker.class).to(BirthdayPresentMaker.class);
}
}
The AnnotationDatabaseImpl was there but only under the build directory not among the source files.
My bad, probably every annotation processor work like this.
(Although strangely this project has the AnnotationDatabaseImpl generated in the project root..).