mixpanel / mixpanel-android Goto Github PK
View Code? Open in Web Editor NEWOfficial Android Tracking Library for Mixpanel Analytics
Home Page: http://mixpanel.com/
License: Apache License 2.0
Official Android Tracking Library for Mixpanel Analytics
Home Page: http://mixpanel.com/
License: Apache License 2.0
We're using 4.0.0 and seeing some very strange crashes in various places on certain devices, but not others.
The most reproducible crashing device is the incredibly slow Sony Xperia U running Android 4.0.4.
If we ever call MixpanelAPI.getInstance(context, MIXPANEL_TOKEN) then our app crashes in different places, in our network request callbacks with this:
...
FATAL EXCEPTION: com.mixpanel.android.AnalyticsWorker
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
...
An example of the rest of a stack trace is at the bottom.
This is without ever tracking any events. As soon as we stop grabbing an instance of MixpanelAPI we don't see any crashes.
...
E/AndroidRuntime(14649): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4043)
E/AndroidRuntime(14649): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:722)
E/AndroidRuntime(14649): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:771)
E/AndroidRuntime(14649): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4112)
E/AndroidRuntime(14649): at android.view.View.invalidate(View.java:8639)
E/AndroidRuntime(14649): at android.view.View.invalidate(View.java:8590)
E/AndroidRuntime(14649): at android.widget.TextView.updateTextColors(TextView.java:2901)
E/AndroidRuntime(14649): at android.widget.TextView.drawableStateChanged(TextView.java:2911)
E/AndroidRuntime(14649): at android.view.View.refreshDrawableState(View.java:11695)
E/AndroidRuntime(14649): at android.view.View.setEnabled(View.java:4711)
E/AndroidRuntime(14649): at android.widget.TextView.setEnabled(TextView.java:1230)
[removed... our app code]
E/AndroidRuntime(14649): at android.os.AsyncTask.finish(AsyncTask.java:602)
E/AndroidRuntime(14649): at android.os.AsyncTask.access$600(AsyncTask.java:156)
E/AndroidRuntime(14649): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
E/AndroidRuntime(14649): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(14649): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(14649): at android.os.HandlerThread.run(HandlerThread.java:60)
...
We send our Mixpanel tracking to a proxy server by using the BASE_ENDPOINT and FINAL_ENDPOINT values. In 3.3.2, the URI we supply, however, is trashed by AnalyticsMessages sendAllData().
For example, if we set the endpoint as follows:
MPConfig.BASE_ENDPOINT = "http://ourcompany.com/loggingproxy?action=sendmsg";
MPConfig.FALLBACK_ENDPOINT = MPConfig.BASE_ENDPOINT;
mOurLogger = MixpanelAPI.getInstance(OurApp.getInstance(), Constants.OUR_TOKEN);
... the sendAllData() method will trash the URL, causing it to become:
http://ourcompany.com/loggingproxy?action=sendmsg/track?ip=1
Instead of what we intend:
http://ourcompany.com/loggingproxy?action=sendmsg
I suspect there will be similar problems with the addition of the "/engage" string.
I would suggest having the code set a flag if a custom BASE and/or FALLBACK endpoint are being used. If this flag is set, the library should not do anything with the URLs and instead honor them fully as they have been supplied.
Using something like Travis CI with maven and robolectric you can unit and functional test your library.
Symptom
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
W/System.err( 1153): at android.os.Handler.<init>(Handler.java:121)
W/System.err( 1153): at android.bluetooth.BluetoothAdapter$1.<init>(BluetoothAdapter.java:961)
W/System.err( 1153): at android.bluetooth.BluetoothAdapter.<init>(BluetoothAdapter.java:961)
W/System.err( 1153): at android.bluetooth.BluetoothAdapter.getDefaultAdapter(BluetoothAdapter.java:308)
W/System.err( 1153): at com.mixpanel.android.mpmetrics.MixpanelAPI.getDefaultEventProperties(MixpanelAPI.java:973)
W/System.err( 1153): at com.mixpanel.android.mpmetrics.MixpanelAPI.track(MixpanelAPI.java:239)
* See Also*
Might be related to #8
Problem
Your MixpanelAPI.getDefaultEventProperties()
method can call BluetoothAdapter.getDefaultAdapter()
for the first time, from the context of a worker thread. This causes a bug in the Android OS to present as the runtime exception noted above.
We have seen this bug present on HTC Nexus One (Android OS 2.3.6). The Stack Overflow article (see below) implies the problem exists up to at least Android OS 4.0.
Solution
To get around this issue, you need to ensure that your library is calling the getDefaultAdapter()
API for the first time in a main UI thread -- and specifically, it is NOT called for the first time from a background thread.
Please see this StackOverflow article:
http://stackoverflow.com/a/15036421/260559
Since we discovered this a day before we are to ship, our workaround was simply to modify the Mixpanel library code directly and rebuild it, and hard-code the bluetooth status and avoid calling this code, since our tracking code isn't too concerned about bluetooth status.
This work is more appropriate to the Mixpanel work thread. Shared preferences are very fast, but accesses appear when users are auditing their applications in StrictMode.
Stack trace donated by a user follows (in Strict Mode):
08-28 12:25:19.209: E/StrictMode(16388): A resource was acquired at
attached stack trace but never released. See java.io.Closeable for
information on avoiding resource leaks.
08-28 12:25:19.209: E/StrictMode(16388): java.lang.Throwable: Explicit
termination method 'close' not called
08-28 12:25:19.209: E/StrictMode(16388): at
dalvik.system.CloseGuard.open(CloseGuard.java:184)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:267)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getSession(OpenSSLSocketImpl.java:703)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
08-28 12:25:19.209: E/StrictMode(16388): at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.HttpPoster.postHttpRequest(HttpPoster.java:53)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.HttpPoster.postData(HttpPoster.java:43)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.sendData(AnalyticsMessages.java:276)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.sendAllData(AnalyticsMessages.java:267)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.handleMessage(AnalyticsMessages.java:215)
08-28 12:25:19.209: E/StrictMode(16388): at
android.os.Handler.dispatchMessage(Handler.java:99)
08-28 12:25:19.209: E/StrictMode(16388): at
android.os.Looper.loop(Looper.java:137)
08-28 12:25:19.209: E/StrictMode(16388): at
com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$1.run(AnalyticsMessages.java:161)
It's possible that this can be addressed by using AndroidHttpClient instead of DefaultHttpClient- if not, consider the implications of shutting down the connection manager associated with the HttpClient (and do some serious testing and soul searching)
JSON creation is fairly inefficient. Data is already stored as json in DB. You parse it first, then add all of them to a JSONArray and serialize it to string again. You could probably just use a string builder and append them to eachother using []. Dalvik VM is pretty bad w/ temporary objects, especially on gingerbread. When events pile up, this turns into a GC trigger.
I know that is a non related bug with mixpanel, but just for your information:
I have an app with fiksu + mobiletracker + facebook SDK + mixpanel 3.x , when I updated mixpanel to 4.0, fiksu shows this error:
Caused by: com.fiksu.asotracking.FiksuIntegrationError: Multiple receivers declared for: com.android.vending.INSTALL_REFERRER
at com.fiksu.asotracking.InstallTracking.checkForFiksuReceiver(InstallTracking.java:172)
at com.fiksu.asotracking.FiksuTrackingManager.initialize(FiksuTrackingManager.java:24)
I will send a ticket to fiksu, but maybe that could be a generic error with others tracking system.
Caused by java.lang.RuntimeException
Can't create handler inside thread that has not called Looper.prepare()
MixpanelAPI.java line 972
com.mixpanel.android.mpmetrics.MixpanelAPI.getDefaultEventProperties
Hi,
I am trying to generate MPMetrics_v2.1.jar by running the following command:
ANDROID_HOME=/my/path/to/android/sdk ant library
I receive the following error log:
buildfile: /Users/achentir/Documents/programming/libraries/mixpanel-android/build.xml
-setup:
[mkdir] Created dir: /Users/achentir/Documents/programming/libraries/mixpanel-android/bin
[mkdir] Created dir: /Users/achentir/Documents/programming/libraries/mixpanel-android/bin/classes
compile:
[javac] Compiling 11 source files to /Users/achentir/Documents/programming/libraries/mixpanel-android/bin/classes
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:7: package org.json does not exist
[javac] import org.json.JSONObject;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:9: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:10: package android.os does not exist
[javac] import android.os.Handler;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:11: package android.os does not exist
[javac] import android.os.Looper;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:12: package android.os does not exist
[javac] import android.os.Message;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:13: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:27: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] /* package */ AnalyticsMessages(Context context) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:39: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] public static AnalyticsMessages getInstance(Context messageContext) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:57: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] public void eventsMessage(JSONObject eventsJson) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:65: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] public void peopleMessage(JSONObject peopleJson) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:98: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] protected MPDbAdapter makeDbAdapter(Context context) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:5: package org.json does not exist
[javac] import org.json.JSONArray;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:6: package org.json does not exist
[javac] import org.json.JSONException;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:7: package org.json does not exist
[javac] import org.json.JSONObject;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:9: package android.content does not exist
[javac] import android.content.ContentValues;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:10: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:11: package android.database does not exist
[javac] import android.database.Cursor;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:12: package android.database.sqlite does not exist
[javac] import android.database.sqlite.SQLiteDatabase;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:13: package android.database.sqlite does not exist
[javac] import android.database.sqlite.SQLiteException;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:14: package android.database.sqlite does not exist
[javac] import android.database.sqlite.SQLiteOpenHelper;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:15: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:7: package org.apache.http does not exist
[javac] import org.apache.http.HttpEntity;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:8: package org.apache.http does not exist
[javac] import org.apache.http.HttpResponse;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:9: package org.apache.http does not exist
[javac] import org.apache.http.NameValuePair;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:10: package org.apache.http.client does not exist
[javac] import org.apache.http.client.HttpClient;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:11: package org.apache.http.client.entity does not exist
[javac] import org.apache.http.client.entity.UrlEncodedFormEntity;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:12: package org.apache.http.client.methods does not exist
[javac] import org.apache.http.client.methods.HttpPost;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:13: package org.apache.http.impl.client does not exist
[javac] import org.apache.http.impl.client.DefaultHttpClient;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:14: package org.apache.http.message does not exist
[javac] import org.apache.http.message.BasicNameValuePair;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:16: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:338: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages
[javac] private static final Map<Context, AnalyticsMessages> sInstances = new HashMap<Context, AnalyticsMessages>();
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:65: cannot find symbol
[javac] symbol : class SQLiteOpenHelper
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter
[javac] private static class MPDatabaseHelper extends SQLiteOpenHelper {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:104: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter
[javac] public MPDbAdapter(Context context) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:108: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter
[javac] public MPDbAdapter(Context context, String dbName) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:121: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter
[javac] public int addJSON(JSONObject j, Table table) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/HttpPoster.java:46: cannot find symbol
[javac] symbol : class NameValuePair
[javac] location: class com.mixpanel.android.mpmetrics.HttpPoster
[javac] private PostResult postHttpRequest(String endpointUrl, List<NameValuePair> nameValuePairs) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:120: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker
[javac] public Worker(Context context) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:128: cannot find symbol
[javac] symbol : class Message
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker
[javac] public void runMessage(Message msg) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:143: cannot find symbol
[javac] symbol : class Handler
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker
[javac] private Handler restartWorkerThread() {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:315: cannot find symbol
[javac] symbol : class Handler
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker
[javac] private Handler mHandler;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:66: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter.MPDatabaseHelper
[javac] MPDatabaseHelper(Context context, String dbName) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:80: cannot find symbol
[javac] symbol : class SQLiteDatabase
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter.MPDatabaseHelper
[javac] public void onCreate(SQLiteDatabase db) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java:90: cannot find symbol
[javac] symbol : class SQLiteDatabase
[javac] location: class com.mixpanel.android.mpmetrics.MPDbAdapter.MPDatabaseHelper
[javac] public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:176: cannot find symbol
[javac] symbol : class Handler
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker
[javac] private class AnalyticsMessageHandler extends Handler {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java:178: cannot find symbol
[javac] symbol : class Message
[javac] location: class com.mixpanel.android.mpmetrics.AnalyticsMessages.Worker.AnalyticsMessageHandler
[javac] public void handleMessage(Message msg) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:3: package android.content does not exist
[javac] import android.content.BroadcastReceiver;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:4: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:5: package android.content does not exist
[javac] import android.content.Intent;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:14: cannot find symbol
[javac] symbol: class BroadcastReceiver
[javac] public class GCMReceiver extends BroadcastReceiver {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:16: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.GCMReceiver
[javac] public void onReceive(Context context, Intent intent) {}
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/GCMReceiver.java:16: cannot find symbol
[javac] symbol : class Intent
[javac] location: class com.mixpanel.android.mpmetrics.GCMReceiver
[javac] public void onReceive(Context context, Intent intent) {}
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:7: package org.json does not exist
[javac] import org.json.JSONArray;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:8: package org.json does not exist
[javac] import org.json.JSONException;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:9: package org.json does not exist
[javac] import org.json.JSONObject;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:11: package android.app does not exist
[javac] import android.app.PendingIntent;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:12: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:13: package android.content does not exist
[javac] import android.content.Intent;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:14: package android.content does not exist
[javac] import android.content.SharedPreferences;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:15: package android.os does not exist
[javac] import android.os.Build;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:16: package android.provider does not exist
[javac] import android.provider.Settings;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:17: package android.util does not exist
[javac] import android.util.DisplayMetrics;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:18: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:90: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] MixpanelAPI(Context context, String token) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:117: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] public static MixpanelAPI getInstance(Context context, String token) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:140: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] public static void setFlushInterval(Context context, long milliseconds) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:187: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] public void track(String eventName, JSONObject properties) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:278: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] public void registerSuperProperties(JSONObject superProperties) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:318: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] public void registerSuperPropertiesOnce(JSONObject superProperties) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:6: package android does not exist
[javac] import android.Manifest;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:7: package android.content does not exist
[javac] import android.content.Context;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:8: package android.content.pm does not exist
[javac] import android.content.pm.PackageInfo;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:9: package android.content.pm does not exist
[javac] import android.content.pm.PackageManager;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:10: package android.content.pm.PackageManager does not exist
[javac] import android.content.pm.PackageManager.NameNotFoundException;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:11: package android.net does not exist
[javac] import android.net.ConnectivityManager;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:12: package android.net does not exist
[javac] import android.net.NetworkInfo;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:13: package android.telephony does not exist
[javac] import android.telephony.TelephonyManager;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:14: package android.util does not exist
[javac] import android.util.DisplayMetrics;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:15: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:16: package android.view does not exist
[javac] import android.view.Display;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:17: package android.view does not exist
[javac] import android.view.WindowManager;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:770: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] private JSONObject getDefaultEventProperties()
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:771: cannot find symbol
[javac] symbol : class JSONException
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] throws JSONException {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:891: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] private final Context mContext;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:899: cannot find symbol
[javac] symbol : class SharedPreferences
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] private final SharedPreferences mStoredPreferences;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:902: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI
[javac] private JSONObject mSuperProperties;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:7: package org.json does not exist
[javac] import org.json.JSONException;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:8: package org.json does not exist
[javac] import org.json.JSONObject;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:10: package android.util does not exist
[javac] import android.util.Log;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:440: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: interface com.mixpanel.android.mpmetrics.MixpanelAPI.People
[javac] public void set(JSONObject properties);
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:26: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.SystemInformation
[javac] public SystemInformation(Context context) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:84: cannot find symbol
[javac] symbol : class DisplayMetrics
[javac] location: class com.mixpanel.android.mpmetrics.SystemInformation
[javac] public DisplayMetrics getDisplayMetrics() { return mDisplayMetrics; }
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:138: cannot find symbol
[javac] symbol : class Context
[javac] location: class com.mixpanel.android.mpmetrics.SystemInformation
[javac] private final Context mContext;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/SystemInformation.java:143: cannot find symbol
[javac] symbol : class DisplayMetrics
[javac] location: class com.mixpanel.android.mpmetrics.SystemInformation
[javac] private final DisplayMetrics mDisplayMetrics;
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:611: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI.PeopleImpl
[javac] public void set(JSONObject properties) {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:742: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI.PeopleImpl
[javac] public JSONObject stdPeopleMessage(String actionType, JSONObject properties)
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:742: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI.PeopleImpl
[javac] public JSONObject stdPeopleMessage(String actionType, JSONObject properties)
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/MixpanelAPI.java:743: cannot find symbol
[javac] symbol : class JSONException
[javac] location: class com.mixpanel.android.mpmetrics.MixpanelAPI.PeopleImpl
[javac] throws JSONException {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:24: cannot find symbol
[javac] symbol : class JSONObject
[javac] location: class com.mixpanel.android.mpmetrics.WaitingPeopleRecord
[javac] public void setOnWaitingPeopleRecord(JSONObject sets)
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:25: cannot find symbol
[javac] symbol : class JSONException
[javac] location: class com.mixpanel.android.mpmetrics.WaitingPeopleRecord
[javac] throws JSONException {
[javac] ^
[javac] /Users/achentir/Documents/programming/libraries/mixpanel-android/src/com/mixpanel/android/mpmetrics/WaitingPeopleRecord.java:53: cannot find symbol
[javac] symbol : class JSONException
[javac] location: class com.mixpanel.android.mpmetrics.WaitingPeopleRecord
[javac] throws JSONException {
[javac] ^
[javac] 100 errors
BUILD FAILED
/Users/achentir/Documents/programming/libraries/mixpanel-android/build.xml:95: Compile failed; see the compiler error output for details.
I tried to generate a local.properties file by using:
android update project -p .
But I got an error message due to the absence of the AndroidManifest.xml file. So I generated one manually containing the following line:
local.properties=/my/path/to/android/sdk
But same problem.
Thanks!
Allow users to query for the distinct_id currently in use by the event tracking library. Use an id that isn't related to the device id/android account id if reasonable.
Some apps sleep and resume very frequently and it'd be beneficial not to keep checking for surveys every second or so.
Automatic bluetooth analytics don't work if track() is called from a thread other than the main thread.
In MixpanelAPI.java, the below piece of code in trackCharge function has a logical error.
if (null != metaData) {
for (Iterator<?> iter = metaData.keys(); iter.hasNext();) {
String key = (String) iter.next();
transactionValue.put(key, transactionValue.get(key));
}
transactionValue.put(key, transactionValue.get(key));
should be transactionValue.put(key, metaData.get(key));
I think I am facing issues because of this.
It would be nice to add the information about whether or not the device is connected to a mobile network. Similar to the Wifi-information. Shouldn't be that hard looking at SystemInformation.java and AnalyticsMessages.java
Hi,
When i disable network and use the app, I see lots of Mixpanel HTTP request errors.
it sadly keeps trying to send all data. This is being triggered periodically + when I dispatch new events (probably because client reached MPConfig.BULK_UPLOAD_LIMIT
).
There are a couple of problems:
what do you think? can these be added to roadmap or should we try to change it ourselves or is there sth I am missing?
Thanks.
Users report that survey prompts end with ellipsis after a single line using the Xperia U (Android 2.3/Gingerbread).
Turns out that DateFormat is stateful and not thread safe, for no apparent reason. Make sure each instance of MixpanelAPI has it's own instance.
It would be great if you guys offered a Maven artifact to make it easier to use this with Android projects that are managed by Maven.
This may need more work than just the Android lib (I havent looked)
But an unidentify()
api would be good, as if a user forceably logs out we dont really want to associate a logged out user OR another user with that install. (well at least until they/someone else logs in)
In the mean time, a workaround is present here: #43
We send our Mixpanel tracking to a proxy server. In order to do this, we must modify MPConfig's BASE_ENDPOINT
and FALLBACK_ENDPOINT
members.
This is not currently possible because:
com.mixpanel.android.mpmetrics.MPConfig
is not declared as a public
class.MPConfig.BASE_ENDPOINT
and MPConfig.FALLBACK_ENDPOINT
are declared as final
, so we are not able to change them.We have modified these accordingly in our own copy of the library. I haven't had time to fork & submit a pull request yet -- I will try soon. So now this is how we can affect the custom endpoints:
MPConfig.BASE_ENDPOINT = "http://" + OurClass.getProxyURI();
MPConfig.FALLBACK_ENDPOINT = "http://" + OurClass.getProxyURI();
mOurLogger = MixpanelAPI.getInstance(OurClass.getInstance(), Constants.OUR_TOKEN);
It would also be nice to have an alternate way of supplying the custom ENDPOINT values in the MixpanelAPI.getInstance()
constructor.
MPMetrics#clearSuperProperties method null's the super parameters object instead of setting it to a fresh JSONObject.
Because track and registerSuperProperties methods does not check if mSuperProperties is null or not, this causes a crash.
Steps to reproduce:
MPMetrics mpm = new MPMetrics(context);
mpm.clearSuperProperties();
mpm.registerSuperProperties(newSuperParameters); //crash happens on MPMetrics line 100
Either post a workaround here, or add a capability to construct events/people messages with appropriate timestamps and auto-properties before sending them into the Mixpanel pipeline. This is a related issue to #28 - for tracking in resource constrained or time-sensitive environments
Right now, DB initialization happens in the main activity thread, when a worker is constructed. This should happen in the worker thread to improve performance.
The iOS library currently caches responses and sends them all at once when the survey activity is dismissed- this means that a user can change their mind, and still record only a single response to a survey. Bring the android library into parity with the iOS behavior
When we fall back to HTTP, it puts a stack trace in the logs, and it freaks people out. Don't show the stacktrace if the event is not log-worthy.
Proguard (http://developer.android.com/tools/help/proguard.html) throws warnings that prevent building Mixpanel Android v4.0.0 (see log below).
Hopefully, a specific Proguard configuration correct this rather than changes to the lib itself.
Example error log:
[proguard] Warning: com.mixpanel.android.surveys.CardCarouselLayout:
can't find referenced class com.mixpanel.android.R$layout
[proguard] Warning: com.mixpanel.android.surveys.CardCarouselLayout:
can't find referenced class com.mixpanel.android.R$layout
[proguard] Warning: com.mixpanel.android.surveys.CardCarouselLayout:
can't find referenced class com.mixpanel.android.R
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$layout
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$layout
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$layout
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$layout
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$id
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R$id
[proguard] Warning:
com.mixpanel.android.surveys.CardCarouselLayout$ChoiceAdapter: can't
find referenced class com.mixpanel.android.R
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$layout
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$layout
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R$id
[proguard] Warning: com.mixpanel.android.surveys.SurveyActivity:
can't find referenced class com.mixpanel.android.R
BUILD FAILED/Users/build/android/sdk/tools/ant/build.xml:868: Please
correct the above warnings first.
Existing BackgroundCapture class can interfere with rendering listviews in parent app. For now, this feature is disabled (all surveys display with a neutral background) but we'd like to re-introduce the blurring.
Permissions ACCESS_NETWORK_STATE
and BLUETOOTH
should be removed from AndroidManifest.xml
because they are optional and therefore should not be automatically added when using gradle with maven dependencies.
In it's current form, the Mixpanel library uses a given, user activity to display popup dialogs and notifications. This can cause problems if the user activities have unexpected properties (like being preemptively finished, for example.) A more stable approach would be to launch an activity that then manages the dialogs. Thanks to @cristizmf for the idea!
In a more than one question survey scenario if the user (at the mobile side) navigate forward and backward changing his/her choice then at mixpanel dashboard it shows a lot of responses, when actually what happened is that just one user change his/her
mind.
i have two memory dumps from our app when it crashed because of an "out of memory" issue and after analyzing both dumps with Eclipse Mat, I see that Mixpanel is leaking a lot of android.os.Message objects.
I took a quick look at your source code, looks like 'for whatever reason' mixpanel stops handling track messages. (it is leaking around 20 MB).
one information I heard from dump owners is that they left the app open for night and in the morning they saw the OOM report (app detects if it crashed because of an OOM, saves a heap dump and notifies user to send the dump to us on next open).
you can see a screenshot from eclipse mat here:
I cannot share the memory dump here but please contact me at yigit [a t] path com so that we can work together to resolve the issue.
Will involve changes to the queuing of events before identification
Related to #46 - this will require a different mechanism of caching updates before people identify
The documentation for com.mixpanel.android.mpmetrics.MPMetrics.sendRequest() describes a data field that doesn't exist.
If I choose any Android SDK below 4.0.0, I get the following error message:
~/Development/Libraries:SDKs/mixpanel-android-latest4.0.0/src/main/res/layout/com_mixpanel_android_question_card.xml:43: error: No resource identifier found for attribute 'requiresFadingEdge' in package 'android'
This would make it easier for folks to use the Mixpanel API from different threads. Any synchronized handle should be optional/opt-in, but some folks might want to use the Mixpanel API from multiple threads without having to worry about a particular threading model.
Includes moving build to Gradle.
it's my app that uses a lot of memory but the OOM it caused probably indicate the MixPanel SDK has a room for optimization.
Exception:
java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at org.json.JSONStringer.string(JSONStringer.java:303)
at org.json.JSONStringer.value(JSONStringer.java:252)
at org.json.JSONObject.writeTo(JSONObject.java:667)
at org.json.JSONStringer.value(JSONStringer.java:237)
at org.json.JSONObject.writeTo(JSONObject.java:667)
at org.json.JSONStringer.value(JSONStringer.java:237)
at org.json.JSONArray.writeTo(JSONArray.java:572)
at org.json.JSONArray.toString(JSONArray.java:544)
at com.mixpanel.android.mpmetrics.MPDbAdapter.generateDataString(SourceFile:244)
at com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.sendData(SourceFile:304)
at com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.sendAllData(SourceFile:299)
at com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$AnalyticsMessageHandler.handleMessage(SourceFile:269)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at com.mixpanel.android.mpmetrics.AnalyticsMessages$Worker$1.run(SourceFile:187)
I looked at:
https://github.com/mixpanel/mixpanel-android/blob/master/src/com/mixpanel/android/mpmetrics/MPDbAdapter.java
https://github.com/mixpanel/mixpanel-android/blob/master/src/com/mixpanel/android/mpmetrics/AnalyticsMessages.java
private void sendData(MPDbAdapter.Table table, String endpointUrl)
could it not to prepare the String[] but use InputStream or Writer instead? Allocating those String in Android cause more GC than necessary
Modifying things such as the endpoint currently require rebuilding the library. Allow modification of endpoint (and possibly other values currently stored as MPConfig constants) without violating the thread safety of the library.
This means there is a possible (but rare) race condition that could result in a user seeing a survey they've already seen.
I would suggest that 0 will autoFlush when event(..) is fired.
<= -1 will disabled autoFlushing requiring the user to flush the data manually so we can handle deferred loading correctly.
If it does this already, add it to the JavaDoc.
This should simply decline to show surveys rather than throw.
Generating the blurred background for a survey will prevent running UI from rendering.
We have our Mixpanel tracking sent to a proxy server for processing, via the BASE_ENDPOINT and FALLBACK_ENDPOINT properties in MPConfig.
Our proxy server requires a custom HTTP header -- specifically, "RDP" -- on all inbound requests.
We have modified HttpPoster.postHttpRequest() to affect this:
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// ADD OUR CUSTOM HTTP HEADER:
httppost.setHeader("RDP", "true");
HttpResponse response = httpclient.execute(httppost);
However, it would be nice to have a mechanism where we can simply supply this to the library, so that we don't have to tweak & build our own version of the lib.
if the first call to Mixpanel.getInstance() is made on a background thread, it fails to initialize because it tries to create a handler (which requires Looper)
here is the exception:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at com.mixpanel.android.mpmetrics.MPMetrics$UniqueHandler.(MPMetrics.java:74)
at com.mixpanel.android.mpmetrics.MPMetrics$UniqueHandler.(MPMetrics.java:74)
at com.mixpanel.android.mpmetrics.MPMetrics.(MPMetrics.java:112)
at com.mixpanel.android.mpmetrics.MPMetrics.getInstance(MPMetrics.java:508)
at com.mixpanel.android.mpmetrics.MPMetrics$UniqueHandler.(MPMetrics.java:74)
at com.mixpanel.android.mpmetrics.MPMetrics$UniqueHandler.(MPMetrics.java:74)
at com.mixpanel.android.mpmetrics.MPMetrics.(MPMetrics.java:112)
at com.mixpanel.android.mpmetrics.MPMetrics.getInstance(MPMetrics.java:508)
The following stack trace:
02-25 14:33:18.420: E/AndroidRuntime(17364): FATAL EXCEPTION: main
02-25 14:33:18.420: E/AndroidRuntime(17364): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@41909088 is not valid; is your activity running?
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.view.ViewRootImpl.setView(ViewRootImpl.java:517)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:301)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.view.Window$LocalWindowManager.addView(Window.java:539)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.app.Dialog.show(Dialog.java:288)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.app.AlertDialog$Builder.show(AlertDialog.java:932)
02-25 14:33:18.420: E/AndroidRuntime(17364): at com.mixpanel.android.mpmetrics.MixpanelActivityLifecycleCallbacks$1$3.run(MixpanelActivityLifecycleCallbacks.java:122)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.os.Handler.handleCallback(Handler.java:605)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.os.Handler.dispatchMessage(Handler.java:92)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.os.Looper.loop(Looper.java:137)
02-25 14:33:18.420: E/AndroidRuntime(17364): at android.app.ActivityThread.main(ActivityThread.java:4493)
02-25 14:33:18.420: E/AndroidRuntime(17364): at java.lang.reflect.Method.invokeNative(Native Method)
02-25 14:33:18.420: E/AndroidRuntime(17364): at java.lang.reflect.Method.invoke(Method.java:511)
02-25 14:33:18.420: E/AndroidRuntime(17364): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
02-25 14:33:18.420: E/AndroidRuntime(17364): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
02-25 14:33:18.420: E/AndroidRuntime(17364): at dalvik.system.NativeStart.main(Native Method)
A proposed fix is present in release 4.0.1-RC1 but has yet to be confirmed as a fix:
https://github.com/mixpanel/mixpanel-android/releases/tag/v4.0.1-RC1
Related:
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/U4mOUI-rRPY
Google recommends generating a UUID yourself and using that, see
http://android-developers.blogspot.com/2011/03/identifying-app-installations.html
During an audit of an Android app we found this statistics library leaking semi-sensitive data over an unencrypted connection when we shut off port 443.
This was the HTTP fallback kicking in. We believe that vendors are unaware of this behavior and it should be disabled by default.
/cc @c3c, @ConnorDillon, @xureal, @PTVB
Edit:
The library now falls back to HTTP communication if HTTPS communication is unavailable. In particular, this may occur in early versions of Android that only support a small set of certificate authorities.
If this behavior was intended for compatibility with older Android versions, a better solution would be to use certificate pinning.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.