I am building an application with android platform. Will like to design a server side akka application that will provide services in a distributed manner to the android application. Both systems are designed as separate applications. Will it be possible to connect the akka remote server with the android application. Please help me out cos I am new to both akka and android.
You can do this, but you will suffer.
You must somehow be able to access the class definitions for akka-remote and dependencies (netty, scala) from your android app. This can be problematic, since the sum of dependencies has more than 65536 methods which is Dalviks cap. (That is - your classes.dex file inside the apk cannot have more method definitions than 65536).
AFAIK, there's three main approaches:
Split up the dependencies into separate apklibs and make your apk depend on these.
I can't really recommend this since I haven't tried it.
Split up the dependencies into separate classes.dex files that you load programmatically from your app.
Probably doable. Never tried it.
Run proguard before packing your classes.dex
You'll have to battle with proguard to get the config right, and you may get strange runtime failures. My config is posted below.
Once you get akka-remote up and running on your android device you can connect to the server like in the examples in the docs. However, keep in mind that:
The IP of your Android device may or may not be available at boot time, so you may wan't to keep that part of your akka config dynamic (haven't done this myself).
The IP of your Android device may not be reachable from the server. So if you get into a state where the server needs to call the client back, it will never succeed.
My proguard.cfg (some lines are not needed - haven't bothered figure out which ones):
-dontoptimize
#-optimizationpasses 2
-dontobfuscate
-dontpreverify
-dontskipnonpubliclibraryclassmembers
-dontskipnonpubliclibraryclasses
-dontnote **
-verbose
-keep class com.typesafe.config.Config { *; }
-keep class com.typesafe.config.ConfigFactory { *; }
-keep class org.slf4j.Logger { *; }
-keep class org.slf4j.LoggerFactory { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#Scala
-dontwarn scala.**
-keepclassmembers class * {
** MODULE$;
}
-keep class scala.Option
-keep class scala.Function1
-keep class scala.PartialFunction
#https://issues.scala-lang.org/browse/SI-5397
-keep class scala.collection.SeqLike {
public protected *;
}
-keep class scala.Tuple*
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-keep class * implements org.xml.sax.EntityResolver
-keepclassmembers class * {
** MODULE$;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool { *; }
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
int base;
int sp;
int runState;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
int status;
}
-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue { *; }
#Akka
-dontwarn org.jboss.netty.logging.**
-dontwarn org.osgi.**
-dontwarn javax.servlet.**
#-dontwarn org.jboss.netty.channel.socket.http.**
## Unsafe is there at runtime
-dontwarn sun.misc.Unsafe
-keep class sun.misc.Unsafe{
*;
}
-keep class akka.** { *; }
-keep class com.google.protobuf.GeneratedMessage {
*;
}
-keep class org.javatuples.** { *; }
-keep class org.jboss.**
-dontwarn org.jboss.netty.handler.codec.marshalling.**
-dontwarn org.jboss.netty.channel.socket.nio.**
-dontwarn org.jboss.netty.handler.codec.compression.JdkZlibEncoder
-dontwarn org.jboss.netty.handler.codec.spdy.SpdyHeaderBlockZlibCompressor
-dontwarn org.jboss.netty.channel.socket.http.HttpTunnelingServlet
-dontwarn org.jboss.modules.**
-dontwarn __redirected.**
-dontwarn org.slf4j.LoggerFactory
-dontwarn org.slf4j.MarkerFactory
-dontwarn org.slf4j.MDC
-dontwarn org.slf4j.impl.AndroidLogger
-dontwarn org.slf4j.impl.AndroidLoggerFactory
Good luck.
I'm not sure if you were thinking of using the Akka remoting protocol, but if it were me, I would consider looking into the excellent HTTP+REST library Spray (http://spray.io/). I've played around with this library and it is very slick. It is well integrated with Akka and would allow you to provide REST APIs for your services. As a bonus, going REST also allows you to have services that will easily integrate with things other than your Android frontend.
I've included a couple of links as a starting point. The Google 2010 I/O talk on writing REST clients for Android apps is especially interesting:
http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
http://www.techrepublic.com/blog/app-builder/calling-restful-services-from-your-android-app/1076
Related
I am using IBM's mobilefirst worklight version 6.3 for push notification. Everything works fine when i dont apply proguard.
When i apply proguard and run the build while subscribing for the push notification only i get the following exception.
java.lang.RuntimeException: Failed to find the icon resource. Add the icon file under the /res/drawable folder.
I have the push.png named file in the drawable folder.
Any suggestions on how to handle that on the proguard or is it a worklights bug?
had the same issue with another third party library but it was resolved when i added keep class com.classname.** {*;} i did the same for worklight as well -keep class com.worklight.** {*;} but it is of no use.
below is the proguard configuration that i have used
-keepclassmembers class * {
#android.webkit.JavascriptInterface <methods>;
}
-keep class com.google.gson.Gson
-keep class com.billdesk.** {*;}
-keep public class com.worklight.** {*;}
-dontwarn com.worklight.**
-dontwarn com.auth0.jwt.**
-dontwarn com.squareup.picasso.**
-dontwarn com.viewpagerindicator.**
-dontwarn org.bouncycastle.**
MobileFirst 6.3 does not officially support obfuscation using Proguard.
Even so, an Android project obfuscated using Proguard works fine without issues in most cases.
I am not able to recreate the issue you mention.I tested the MFP 6.3 Eventsource notifications sample after obfuscating with Proguard and the application worked fine. No runtime exceptions were seen.
Android SDK Tools : 25.1.1
Target API Level : 19
Proguard version : 4.7
To begin with:
Ensure that push.png is present in all drawable folders and not just the generic one.
Check the proguard obfusction logs to see if "push.png" is being crunched in all folders and look for error messages.
Modify the proguard configuration to contain-
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin
-keep class com.worklight.androidgap.push.** { *; }
-keep class com.worklight.wlclient.push.** { *; }
-keep class com.worklight.common.security.AppAuthenticityToken { *; }
-keep class com.google.** { *;}
-dontwarn com.google.common.**
-dontwarn com.google.ads.**
-dontwarn com.worklight.androidgap.push.GCMIntentService
-dontwarn com.worklight.androidgap.plugin.WLInitializationPlugin
-dontwarn com.worklight.wlclient.push.GCMIntentService
-dontwarn org.bouncycastle.**
-dontwarn com.worklight.nativeandroid.common.WLUtils
-dontwarn com.worklight.wlclient.push.WLBroadcastReceiver
-dontwarn com.worklight.wlclient.push.common.*
-dontwarn com.worklight.wlclient.api.WLPush
I'm trying to configure Proguard, but I can't manage to get it working.
This is the error:
I've tried things like:
-keep class com.android.auth.TwitterHandle.** { *; }
-keep class oauth.** { *; }
Without any luck.
Anyways, I don't really think ignoring is the answer. Because that might mean something is broken.
Any tips?
Thanks!
The warnings indicate that the AndroidQuery library depends on the OAuth library. Apparently, you're using the former library in your project, but the latter library is missing. You could add the missing library, but if your application is working fine without it in debug mode, you can just tell ProGuard to ignore the missing dependency. In this case:
-dontwarn com.androidquery.auth.**
or, to the same effect:
-dontwarn oauth.signpost.**
See the ProGuard manual > Troubleshooting > Warning: can't find referenced class
(I am the developer of ProGuard)
Add these lines to your proguard file.
-dontwarn oauth.**
-dontwarn com.android.auth.TwitterHandle.**
-keep class oauth.** { *; }
-keep class com.android.auth.TwitterHandle.** { *; }
Edit:
Anyways, I don't really think ignoring is the answer. Because that
might mean something is broken.
If you want to use Proguard and you are having some errors such as class not found, then you must disable/ignore their obfuscation. Because Proguard renames names, fields and methods of classes while obfuscating. This becomes a big problem if reflection is used for that classes. So you have to say proguard to ignore(not obfuscate) some classes to prevent this problem.
Please try this post https://stackoverflow.com/a/15477898/1665964
Insert to skip obfuscated in ProGuard your libs, jars, Classes and Subclasses with this example
-optimizationpasses 5
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-allowaccessmodification
-repackageclasses ''
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-libraryjars libs/commons-io-2.2.jar
-libraryjars libs/gson-2.2.2.jar
-keep public class org.apache.commons.io.**
-keep public class com.google.gson.**
-keep public class com.google.gson.** {public private protected *;}
##---------------Begin: proguard configuration for Gson ----------
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.mypackage.ActivityMonitor.ClassMultiPoints.** { *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints$ClassPoint { public protected *; }
##---------------End: proguard configuration for Gson ----------
The reason for error must be that you might be using an external jar file (in libs folder).
If this is the case, adding the following line before -keep class ... lines should solve your problem.
-libraryjars libs/<jar_filename>
If u are unfamiliar with proguard cmd tool then you can try proguard gui located at tools/proguard/lib/proguardgui of your android SDK folder.
open proguardgui and load your configuration file.
then in Input / output section add your input and output jar as well as add your android lib used in your project.
***** your main problem is that you havent added your library (Aquery.jar and others) jar that is used in your project , so that proguard can't find the required Classes.***
Hi i am developing an app with Javacv. The app works fine until i proguard the build. After proguarding, the app crashes at the place of jni function call.
-dontshrink
-dontoptimize
-dontpreverify
-dontwarn android.support.**
-keep class com.googlecode.javacv.**
-dontwarn com.googlecode.javacv.**
-keep class com.googlecode.javacpp.**
-dontwarn com.googlecode.javacpp.**
-keepclasseswithmembernames class * {
native <methods>;
}
-keepattributes *Annotation*
I can't find any answer that solves my problem. I am getting NoSuchMethodError. Anybody help me. I am using the latest version of Javacv library.
You have to keep your native methods (which you're already doing), as well as the Java methods called from native code.
You can keep all javacv and javacpp methods like so:
-keep class com.googlecode.javacv.**{ *; }
-keepclassmembers class com.googlecode.javacv.** {
<methods>;
}
-keep class com.googlecode.javacpp.**{ *; }
-keepclassmembers class com.googlecode.javacpp.** {
<methods>;
}
Also, if you want to cut down on warnings in the build output:
-dontwarn com.googlecode.javacv.**, com.googlecode.javacpp.**
-dontnote com.googlecode.javacv.**, com.googlecode.javacpp.**
I am developing an app that uses google maps. The app works fine up until I Export the signed app package .After the code has been obfuscated the maps are no longer loaded. I am pretty new to ProGuard,I've tried modifying proguard.cfg but soo far nothing has worked.
Here are some of the different things that i've tried:
-libraryjars C:/Program Files/Android/android-sdk/add-ons/addon-google_apis-google_inc_-10/libs/maps.jar
-keep class android.location.** { *; }
-keepnames class com.google.android.maps.** {*;}
-keep public class com.google.android.maps.** {*;}
-dontwarn com.google.android.maps.GeoPoint
-dontwarn com.google.android.maps.MapActivity
-dontwarn com.google.android.maps.MapView
-dontwarn com.google.android.maps.MapController
-dontwarn com.google.android.maps.Overlay
Thanks
Edit: For Google Maps For Android V2 Specifically:
Just in case anyone sees this and has a similar issue - I was getting a Parcelable RuntimeException when I tried to view a second map (as in, Activity A had a map instance, then moving to Activity B, another instance with different params), pointing to what i was assuming was an obfuscated class name in the google package.
after i added
-keep class com.google.android.gms.maps.** { *; }
-keep interface com.google.android.gms.maps.** { *; }
to my proguard-project.txt everything seemed to keep working as normal
It is most likely issue with the Maps API Key. You should generate the Key with the signature used while exporting the app and use it in your map view.
Its unlikely that Obfuscation using ProGuard will affect the map rendering.
It might help:
-optimizations !code/simplification/variable
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
# The Maps API uses custom Parcelables.
# Use this rule (which is slightly broader than the standard recommended one)
# to avoid obfuscating them.
-keepclassmembers class * implements android.os.Parcelable {
static *** CREATOR;
}
# The Maps API uses serialization.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
Source:
https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/proguard-rules.pro
I've had a similar issue using the Google Maps Roads API - it didn't work in obfuscated code. Turns out, the API library uses reflection under the hood, so the solution was to add
-keep class com.google.maps.** { *; }
to proguard-rules.pro.
(Adding this answer here specifically, because this question came up as the most related when I was searching for a solution to my issue, and finding the answer here would've saved me a couple hours of further searching.)
this is better
-keep class * implements com.google.android.gms.maps { *; }
-keep class com.google.android.gms.maps.** { *; }
-keep interface com.google.android.gms.maps.** { *; }
I want to use Proguard mainly for obfuscation reasons.
My problem is that I have three libraries, Twitter4J and two signpost libraries. These libraries caused errors when I tried to create an signed APK. To get over this I put the following in the proguard.config file...
-dontwarn org.apache.commons.codec.binary.**
-dontwarn org.slf4j.**
-dontwarn com.sun.syndication.io.**
-dontwarn com.sun.syndication.feed.synd.*
While this got rid of the errors in the console, when i loaded my signed APK onto my mobile phone it instantly crashed. The DDMS said this was due to a class not found in Twitter4J.
Getting rid of the "dontwarns" above did not help. Neither did adding dontshrink dontoptimise.
I would like Proguard to completely ignore the libraries (as they are open source anyway). Is this possible?
Try this:
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
Cf post from #CaspNZ:
Android Proguard with external jar
You should be able to add to the proguard.cfg the following lines to exclude all classes within a package (and subpackages)
-keep class org.apache.commons.codec.binary.**
-keep interface org.apache.commons.codec.binary.**
-keep enum org.apache.commons.codec.binary.**
-keep class org.slf4j.**
-keep interface org.slf4j.**
-keep enum org.slf4j.**
-keep class com.sun.syndication.io.**
-keep interface com.sun.syndication.io.**
-keep enum com.sun.syndication.io.**
-keep class com.sun.syndication.feed.synd.**
-keep interface com.sun.syndication.feed.synd.**
-keep enum com.sun.syndication.feed.synd.**
I'd like to add that you should sync your project with Gradle files after adding proguard rules, otherwise they may not work.