Monday, July 19, 2010

Optimizing, Obfuscating, and Shrinking your Android Applications with ProGuard

Obfu-what? Right, there's a lot of technical terms there, and you may not know what they mean. I'm going to describe a way for you to shrink the size of your Android applications in half, optimize them to make them run faster, and obfuscate them to make it harder for others to reverse engineer your code.

What we'll do is use a Java program called ProGuard to apply its magic to your program's code, during the build process. To do this we'll use an Ant script to build the program, and add our extra steps into the regular build process.

Why do it?

The short answer is that your code will be smaller and faster. How much smaller and faster depends, but in general you'll find your code will be a lot smaller and a little faster. There are three key functions that ProGuard will do. Much of the text below is taken from the ProGuard website.

You may hear the term obfuscation to describe all three processes. Actually, obfuscation is just one form of the processes that a program such as ProGuard does. Instead of saying "shrink, obfuscate, and optimize", we'll just use the simple term of obfuscation to describe all three in this blog.

Shrinking

Java source code (.java files) is typically compiled to bytecode (.class files). Bytecode is more compact than Java source code, but it may still contain a lot of unused code, especially if it includes program libraries. Shrinking programs such as ProGuard can analyze bytecode and remove unused classes, fields, and methods. The program remains functionally equivalent, including the information given in exception stack traces.

For a realistic example, take the following code:
    if (Config.LOGGING)
    {
        TestClass test = new TestClass();
        Log.d(TAG"[onCreate] testClass=" + test);
    }
The above code is a typical scenario during development. You create code like this to help debug and test your code. Before releasing the final product, though, you set Config.LOGGING to false, so it doesn't execute. The problem is, this code is still in your application. It makes it bigger, and may cause potential security issues by including code which should never be seen by a snooping hacker.

Shrinking the code solves this problem beautifully. The code is completely removed from the final product, leaving the final package safer and smaller.

Obfuscation

By default, compiled bytecode still contains a lot of debugging information: source file names, line numbers, field names, method names, argument names, variable names, etc. This information makes it straightforward to decompile the bytecode and reverse-engineer entire programs. Sometimes, this is not desirable. Obfuscators such as ProGuard can remove the debugging information and replace all names by meaningless character sequences, making it much harder to reverse-engineer the code. It further compacts the code as a bonus. The program remains functionally equivalent, except for the class names, method names, and line numbers given in exception stack traces.

Optimizing

Apart from removing unused classes, fields, and methods in the shrinking step, ProGuard can also perform optimizations at the bytecode level, inside and across methods. Thanks to techniques like control flow analysis, data flow analysis, partial evaluation, static single assignment, global value numbering, and liveness analysis, ProGuard can do things such as perform over 200 peephole optimizations, like replacing x * 2 with x << 1. The positive effects of these optimizations will depend on your code and on the virtual machine on which the code is executed. Simple virtual machines may benefit more than advanced virtual machines with sophisticated JIT compilers. At the very least, your bytecode may become a bit smaller.

Using Ant to build your project

When you create your Android application, or build it, there are many steps involved. First, a Java compiler compiles the source files (i.e. the textual .java files) into Java bytecode (i.e. .class files). Then, a tool in the Android SDK turns the Java bytecode into Dalvik bytecode (i.e. .dex files). Finally, all of the resources and code are packaged into a single ZIP file, which is an .APK file. Since ProGuard works with Java bytecode, we want to run ProGuard on the class files that are created by the Java compiler, before the build process converts the Java bytecode into Dalvik bytecode. This isn't possible with the regular Eclipse method of creating Android packages (at least, not that I know of), but it's a cinch if you use Ant to build your application. It doesn't take long to create an Ant build script to build your existing Android application. See the instructions on my blog post here. Or, you can just download the sample at the end of this blog.

Adding ProGuard to the Ant build script

Download the latest ProGuard distribution. Inside, find the library, and put it in a convenient location in your project directory, such as proguard/. For example, in the latest version as of this writing (4.5.1 distribution), I copied lib/proguard.jar from the distribution ZIP file into my source tree as proguard/proguard.jar. Now, we add the script to the Ant build file, build.xml.

<!-- ================================================= -->
    <!-- Obfuscation with ProGuard -->
    <!-- ================================================= -->
 
    <property name="proguard-dir" value="proguard"/>
 <property name="unoptimized" value="${proguard-dir}/unoptimized.jar"/>
 <property name="optimized" value="${proguard-dir}/optimized.jar"/>
 
 <target name="optimize" unless="nooptimize">
  <jar basedir="${out.classes.dir}" destfile="${unoptimized}"/>
 
  <java jar="${proguard-dir}/proguard.jar" fork="true" failonerror="true">
   <jvmarg value="-Dmaximum.inlined.code.length=16"/>
   <arg value="@${proguard-dir}/config.txt"/>      
   <arg value="-injars ${unoptimized}"/>
   <arg value="-outjars ${optimized}"/>
   <arg value="-libraryjars ${android.jar}"/>
  </java>     
 
  <!-- Delete source pre-optimized jar -->     
  <!--delete file="${unoptimized}"/-->
 
  <!-- Unzip target optimization jar to original output, and delete optimized.jar -->
  <delete dir="${out.classes.dir}"/>
  <mkdir dir="${out.classes.dir}"/>
  <unzip src="${proguard-dir}/optimized.jar" dest="${out.classes.dir}"/>
 
  <!-- Delete optimized jar (now unzipped into bin directory) -->
  <delete file="optimized.jar"/>
 
   </target>
To have the build call the optimize Ant target between the Java compiler and dex compiler, we change the dex target as so:

Android 7 and below:
<!-- Converts this project's .class files into .dex files -->
<target name="-dex" depends="compile,optimize">
Android 8 and above: Uncomment the -post-compile target, and add this:
<target name="-post-compile">
  <antcall target="optimize"/>
</target>

Configuring ProGuard

Now we'll tell ProGuard how it can work with our Android application. Create a file called proguard/config.txt, which is referenced in the above Ant script. The following is taken from the ProGuard manual, although -libraryjars, -injars, and -outjars is passed in via the Ant build script instead of here.
-target 1.6 
-optimizationpasses 2 
-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
-dump class_files.txt 
-printseeds seeds.txt 
-printusage unused.txt 
-printmapping mapping.txt 

# The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. 
-optimizations !code/simplification/arithmetic 

-keep public class * extends android.app.Activity 
-keep public class * extends android.app.Application 
-keep public class * extends android.app.Service 
-keep public class * extends android.content.BroadcastReceiver 
-keep public class * extends android.content.ContentProvider 

-keep public class * extends View { 
public <init>(android.content.Context); 
public <init>(android.content.Context, android.util.AttributeSet); 
public <init>(android.content.Context, android.util.AttributeSet, int); 
public void set*(...); 
}

# Also keep - Enumerations. Keep the special static 
# methods that are required in enumeration classes.
-keepclassmembers enum  * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
} 
Note that we have added a few configurations which make extra output, such as -verbose and -printusage unused.txt. You may remove these if you don't like the extra output cluttering your build process.

Results

Now we're ready! When you run ant release from the command line, you will see the optimizer run. Here is the output from the test project, included below, when the build property config.logging is true:
>ant release
...
     [java] Shrinking...
     [java] Printing usage to [blog\obfuscation\proguard\unused.txt]...
     [java] Removing unused program classes and class elements...
     [java]   Original number of program classes: 8
     [java]   Final number of program classes:    2
Because we configured ProGuard with -printusage unused.txt, we can see what was removed from our code:
com.androidengineer.obfu.Obfuscation: 
    private static final java.lang.String TAG 
com.androidengineer.obfu.R 
com.androidengineer.obfu.R$attr 
com.androidengineer.obfu.R$drawable 
com.androidengineer.obfu.R$layout 
com.androidengineer.obfu.R$string 
com.androidengineer.obfu.TestClass: 
    private static final java.lang.String TAG 
That's pretty cool. You can also look at proguard/unoptimized.jar and proguard/optimized.jar. We can see that it removed many classes which were just placeholders for constants, and it removed the string TAG variables used by our logging code by replacing the references with the actual string constants.

In addition, if we build the application by changing the build property config.logging to false, we get an even further reduction in size. The best part about it is, it removes all of our debugging code.
>ant release
...
     [java]   Original number of program classes: 8
     [java]   Final number of program classes:    1
You can see that one more class was removed, TestClass. Because it is only used when Config.LOGGING is true, it is completely removed from the final build during the obfuscation process. So feel free to leave all of the debugging code you want in your source, because it can be removed during the build.

Of course, with our simple test project, our results are skewed, because it is not a typical Android application. proguard/unoptimized.jar is 4,959 bytes and proguard/optimized.jar is 646 bytes. But on an application I work with, which has over a thousand classes, I've seen a literal 50% reduction of code size. Well worth the trouble of setting this build up, in my opinion.

ClassNotFoundExceptions

There may be some cases where you get a ClassNotFoundException when running your application which has been obfuscated with ProGuard. In this case, you need to edit the config.txt file to tell ProGuard to keep the class in question. For example,

# Keep classes which are not directly referenced by code, but referenced by layout files. 
-keep,allowshrinking class com.androidengineer.MyClass 
{ 
*** (...); 
} 
This scenario is rare. I have seen it happen when I reference the child of an Android View class in an Android layout file, such as MyButton extends Button, but the class is not referenced in regular code. More information can be found in the ProGuard documentation.

Update for Android SDK versions 7 and above

Google updated the Ant scripts in the later SDK versions. They changed the name of a key variable, $[android-jar}, to ${android.jar}. This caused the builds to break. The solution is to define them both if they do not exist:
 <!-- In newer platforms, the build setup tasks were updated to begin using ${android.jar} instead of ${android-jar}.  This makes them both compatible. -->
<target name="target-new-vars" unless="android-jar">
<property name="android-jar" value="${android.jar}"/>
</target>

<!-- Be sure to call target-new-vars before anything else. -->   
<target name="config" depends="target-new-vars,clean">

The sample project file below has been updated.


Update for Android SDK versions 8

Well, it turns out Google changed the ant build files again. This time, though, they actually made it pretty darn easy. The build.xml file is much smaller this time. They've added a nifty new section:
<!-- extension targets. Uncomment the ones where you want to 
     do custom work in between standard targets -->
<!--
    <target name="-pre-build">
    </target>
    <target name="-pre-compile">
    </target>

    [This is typically used for code obfuscation.
     Compiled code location: ${out.classes.absolute.dir}
     If this is not done in place, override 
     ${out.dex.input.absolute.dir}]
    <target name="-post-compile">
    </target>
-->
All we have to do is uncomment the -post-compile Ant target, and add our obfuscation Ant target to it.
<target name="-post-compile">
    <antcall target="optimize"/>
</target>
The complete build file is here.

Using Google's License Verification Library (LVL)

For those of you using the Google licensing service, License Verification Library, you will want to keep an additional class from being obfuscated in the additional library. Be sure the following is in your proguard/config.txt file.
-keep class com.android.vending.licensing.ILicensingService

Sample Application

The sample application is a simple Hello World application, but it includes the custom build script and ProGuard library as described in this tutorial. First, you must run "android update project -p ." from the command line in the project's directory to let the tools set the SDK path in local.properties. Then you can turn on and off logging by changing the value of config.logging in build.properties. Finally, run ant release to build the application, which will create the obfuscated and signed .apk file. If you have any trouble, you may want to review the previous blog post about setting up Ant builds.

Project source code - obfuscation.zip (600 Kb)

Build file for Android API level 8 and above:build.xml (4.52 Kb)

225 comments:

  1. Sweet! I can't wait to try it out!

    ReplyDelete
  2. Thanks for it. It's really help me.

    ReplyDelete
  3. Man I'm really stuck. I can't get the basic build.xml to work. After creating it with the tools/android create command, I get this:

    -package-no-sign:
    [apkbuilder] Creating Dash-unsigned.apk for release...

    BUILD FAILED
    /opt/android-sdk-2.1/android-sdk-linux_86/platforms/android-6/templates/android_rules.xml:320: The following error occurred while executing this line:
    /opt/android-sdk-2.1/android-sdk-linux_86/platforms/android-6/templates/android_rules.xml:186: java.lang.NoClassDefFoundError: com.android.jarutils.SignedJarBuilder

    ReplyDelete
  4. @Brad Hein

    Hard to say... what steps did you take when creating the basic build.xml? Did you follow the instructions in the previous post?

    http://www.androidengineer.com/2010/06/using-ant-to-automate-building-android.html

    ReplyDelete
  5. Awesome, worked perfect for me!
    Thanks for the writeup, going to use this with androids new license library as suggested.

    ReplyDelete
  6. I'm using Proguard with Androids new licensing library and had to add the following to my Proguard config.txt

    -keep public interface com.android.vending.licensing.ILicenseResultListener
    -keep public interface com.android.vending.licensing.ILicensingService
    -keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
    }

    ReplyDelete
  7. Is there a way I can apply the obfuscation to only one class? I read through the proguard documentation but just couldn't find anything.

    One option is to mention everything in keep except the class i want to obfuscate. But that seems unmaintainable.

    Do you have any ideas?

    ReplyDelete
  8. @Arun Gopalan

    In order to do that, you simply need to specify what the source is. In the sample program, there is the following line in the build.xml file:
    <arg value="-injars ${unoptimized}"/>

    That argument to ProGuard says that the input is ${optimized}, which points to an entire .jar (or ZIP) of all the class files. Instead of working on the entire ZIP, you would just change the -injars parameter to your class, such as:

    -injars c:\your_directory\your_class.class

    (you would also need to change -outjars as well, see http://proguard.sourceforge.net/manual/usage.html#iooptions )

    However, I would question why you are doing this. There is no disadvantage to obfuscating the entire program, so why not go ahead and obfuscate the entire thing?

    ReplyDelete
  9. Specifying the android sdk manually in the build.xml fixed my problem. Thanks for the great article

    ReplyDelete
  10. Oops sorry I missed the line of code in my last post:

    ReplyDelete
  11. #property name="sdk.dir" value="/Platforms/android.platform" /-#
    replace the fir # with < and the second with >

    ReplyDelete
  12. Great job, Matt !

    Both the ant build.xml setup and the proguard stuff worked like a charm..

    ReplyDelete
  13. Thanks!

    Worked for a while but then trying a
    # ant clean
    # ant release
    I get the following error:
    /Users/android-sdk-mac_86/platforms/android-4/templates/android_rules.xml:286: The following error occurred while executing this line:
    /Users/android-sdk-mac_86/platforms/android-4/templates/android_rules.xml:152: com.android.apkbuilder.ApkBuilder$ApkCreationException: /Volumes/NO NAME/bin/classes.dex does not exists!

    Would appriciate some help!

    ReplyDelete
  14. Hi,

    I want to thank you for some excellent articles!
    It is seldom to find so good and accurate info
    on the web. Keep up the great work!

    Jonas from Switzerland

    ReplyDelete
  15. @Anonymous

    > /Users/android-sdk-mac_86/platforms/android-4/templates/android_rules.xml:152: com.android.apkbuilder.ApkBuilder$ApkCreationException: /Volumes/NO NAME/bin/classes.dex does not exists!

    If it worked for some time and now it doesn't, I think the good news is that you can get it to work again. I don't use macs, so there may be some setup configuration that I don't know about that is messed up. Also, maybe there is a compile error earlier that you're not seeing, so the code was never fully compiled properly?

    ReplyDelete
  16. Thanks a lot for this useful article. It is very helpful for android developers to protect their source code. Who knows whether google can reverse-engineering dalvik's byte code or not?

    ReplyDelete
  17. I had to add: -libraryjars ..\libs
    to the config.txt file for my Admob and Flurry libs but otherwise excellent tutorial.

    PS I also has problems with spaces in directory names (Program Files). But after moving the Android SDK to a root directory it worked.

    ReplyDelete
  18. Hi,

    I've tried your DemoApp but it doesn't work (i have unzipped the file, done an "android update project -p." and when I type ant debug it does some things but he breaks while packaging the file(s):

    -package-debug-sign:
    [apkbuilder] WARNING: Using deprecated 'basename' attribute in ApkBuilderTask.Use 'apkfilepath' (path) instead.
    [apkbuilder] WARNING: Using deprecated inner element in ApkBuilderTask.Use instead.

    BUILD FAILED
    C:\demoapp\build.xml:347: The following error occurred while executing this line:
    C:\demoapp\build.xml:218: java.lang.NullPointerException

    ReplyDelete
  19. Works with SDK v6 but breaks with newest version 7. Thanks for the ideas though!

    ReplyDelete
  20. Any Ideas on how to solve it for sdk 7. Thanks

    ReplyDelete
  21. How about you can copy the android_install/tools/ant/ant_rules_r3.xml template and infuse the aforementioned 'optimize' target as a dependancy in the 'dex' target.

    I haven't tried it yet but that is where I'd start.

    ReplyDelete
  22. To all that had problems with a newer Android SDK, I have fixed the problem, updated the sample project, and added a comment in the post. Basically, Google changed ${android-jar} to ${android.jar}. Subtly dangerous! The quick fix was to add:

    <target name="target-new-vars" unless="android-jar">
    <property name="android-jar" value="${android.jar}"/>
    </target>

    to the build file, so that both variables are defined.

    ReplyDelete
  23. Looks like with the new SDK [v7] you can just paste the modified '--dex' target






    and the 'optimize' ProGuard target before the 'setup' target in the

    android update project --path .

    generated build.xml file and it will run just fine.

    ReplyDelete
  24. I still can't get it to work with r7.
    I downloaded your new example project
    and I get the following when I try to do an "ant release"

    -package-resources:
    [echo] Packaging resources
    [aaptexec] WARNNG: Using deprecated 'resources' attribute in AaptExecLoopTask.U
    se nested element(s) instead.
    [aaptexec] WARNNG: Using deprecated 'outfolder' attribute in AaptExecLoopTask.U
    se 'apkfolder' (path) instead.
    [aaptexec] WARNNG: Using deprecated 'basename' attribute in AaptExecLoopTask.Us
    e 'resourcefilename' (string) instead.
    [aaptexec] Creating full resource package...

    -package-no-sign:
    [apkbuilder] WARNING: Using deprecated 'basename' attribute in ApkBuilderTask.Us
    e 'apkfilepath' (path) instead.
    [apkbuilder] WARNING: Using deprecated inner element in ApkBuilderTask.Us
    e instead.

    BUILD FAILED
    C:\Users\GodsMoon\workspace\obfuscation\build.xml:351: The following error occur
    red while executing this line:
    C:\Users\GodsMoon\workspace\obfuscation\build.xml:217: java.lang.NullPointerExce
    ption

    I saw this in the forums: http://groups.google.com/group/android-developers/browse_thread/thread/17968bd74bcc6560#

    I'm still having trouble.

    ReplyDelete
  25. With v7 you should just append to the android created build.xml file. First create the build.xml file by navigating to your root directory and typing:

    android update project --path .

    Then in the build.xml file generated paste the following before the 'setup' target:

    <!-- ================================================================ -->

    <!-- Obfuscation with ProGuard -->

    <!-- ================================================================ -->


    <property name="proguard-dir" value="proguard"/>

    <property name="unoptimized" value="${proguard-dir}/unoptimized.jar"/>
    <property name="optimized" value="${proguard-dir}/optimized.jar"/>



    <target name="optimize" unless="nooptimize">

    <jar basedir="${out.classes.dir}" destfile="${unoptimized}"/>



    <java jar="${proguard-dir}/proguard.jar" fork="true" failonerror="true">

    <jvmarg value="-Dmaximum.inlined.code.length=16"/>

    <arg value="@${proguard-dir}/config.txt"/>

    <arg value="-injars ${unoptimized}"/>

    <arg value="-outjars ${optimized}"/>

    <arg value="-libraryjars ${android.jar}"/>

    </java>


    <!-- Delete source pre-optimized jar -->


    <!--delete file="${unoptimized}"/-->



    <!-- Unzip target optimization jar to original output, and delete optimized.jar -->

    <delete dir="${out.classes.dir}"/>

    <mkdir dir="${out.classes.dir}"/>

    <unzip src="${proguard-dir}/optimized.jar" dest="${out.classes.dir}"/>



    <!-- Delete optimized jar (now unzipped into bin directory) -->

    <delete file="optimized.jar"/>



    </target>



    <target name="-dex" depends="clean, compile, optimize">

    <dex-helper />

    </target>

    ReplyDelete
  26. Thanks for this tutorial. After searching and trying around for some time I could obufuscate my project within less than half a day.

    I am using Java Script interfaces in my project and I had to add

    -keep public class com.xyz.JavaScriptInterface {
    public void getHTML_INTERNAL(...);
    }

    to my config.txt file but then it worked perfectly.

    ReplyDelete
  27. I miss the -mergeallclasses parameter in ProGuard. It was included in the 3.6beta version, I think. But then they deprecated it because in some cases it produced some errors when running an application. But it was the best parameter to reduce the jar size a lot.

    ReplyDelete
  28. Thank you very much..!! This was very helpful !! Keep up the good work !

    ReplyDelete
  29. Hi ,
    it seems to work fine, but it crashing with the below error before creating an optimized apk
    please let me know where it might be wrong.
    BUILD FAILED
    C:\LocalCVS\ANDROID\LOCALSVN\progaurdbuild\MyProject\build.xml:370: The following
    error occurred while executing this line:
    C:\LocalCVS\ANDROID\LOCALSVN\progaurdbuild\MyProject\build.xml:236: java.lang.Nul
    lPointerException
    at com.android.ant.ApkBuilderTask.execute(ApkBuilderTask.java:239)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
    java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
    sorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.jav
    a:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
    java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
    sorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.jav
    a:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.jav
    a:398)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
    java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
    sorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.jav
    a:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:390)
    at org.apache.tools.ant.Target.performTasks(Target.java:411)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1397)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1366)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExe
    cutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1249)
    at org.apache.tools.ant.Main.runBuild(Main.java:801)
    at org.apache.tools.ant.Main.startAnt(Main.java:218)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

    Total time: 2 minutes 14 seconds

    ReplyDelete
  30. Thanks, been looking for how to do this for a while. This is the best article I've found yet!

    ReplyDelete
  31. Hi everyone. I finally got around to figuring out what these errors you may have been seeing recently. Google updated their Ant build files again in API level 8. I updated the post to mention how to fix it.

    In a nutshell, you can download the new build.xml file I provided above, or follow the instructions on how to update your own project to be compatible with API level 8.

    ReplyDelete
  32. Alright, I downloaded Ant, ProGuard, build.xml and all that stuff and when I run "ant release" i got "Warning: there were 145 unresolved references to classses or interfaces. You may need to specify additional library jars . Warning: there were 44 unresolved references to program class members. Your input classes appear to be inconsistent. You may need to recompile them and try again. Alternatively, you may have to specify the option "-donskipnonpubliclibraryclassmembers".

    Where to start? =/ Where to add those options?

    ReplyDelete
  33. Hey Svebee,
    It can't find some of the additional jar files you are using. Let's say you have some jar file under lib folder. Then just add the following line
    -libraryjars ..\libs
    to Proguard's config file. That should fix it.

    ReplyDelete
  34. Hi All.

    After trying many methods to use ProGuard and the Android LVL in Ant build, I found a now well tested method that works efficiently and should provide less headaches for newbees who are not familiar using command line methods to build their apps.

    I separated the project from eclipse to avoid any possible corruption that may be caused by typos or incorrect path configuration.

    1. Create a project library as follows.

    Project Root Directory
    copy Android Mainfest.xml, default.properties,Classpath.file and Project file that were created using Eclipse into the Project root directory. Add your keystore.file.

    2. Add the following directories from Eclipse to your project root path as follows:
    assets
    bin
    gen
    libs
    res
    src
    Create proguard directory
    Create a proguard config.txt file, tailor it to your requirements and put this file in the proguard directory. Copy the proguard.jar file into the proguard directory.
    If using other external library jar files such as Flurry put these in the libs directory

    Locate the market_licensing directory and copy the library directory to the Project root directory.

    Warning: if LVL was used in eclipse, then this library should be used and not the one that originally came with the Android SDK because you may have configured it to suit your environment requirements and any other additional changes.

    Your Project environment should now be set-up ready for the ant build.

    3. Ensure that you have the path to the android-sdk-windows\tools directory.
    Run the update command in the command line, or create a batch script containing the following
    android update project --path c:\YourProject
    This will create a build.xml, and local.properties file.

    4. Create a build.properties file and put in the following:

    android.library.reference.1=library

    key.store=your.keystore
    key.alias=youralias
    key.store.password=yourpassword
    key.alias.password=aliaspassword


    5. Edit and tailor your build.xml file that was created previously in update project.

    I copied ant_rules_r3.xml file located in android-sdk-windows/tools/ant

    6. Proguard
    Edit your proguard config.txt to suite your program. It is advisable to read the proguard documentation or other sites that discuss proguard and obfuscating.
    The following points are important.

    The LVL licensing service must be kept as follows.
    -keep class com.android.vending.licensing.ILicensingService

    If you do not specify your library jars paths in the build.xml file, then you must ensure that they are included in the proguard config.txt.

    -libraryjars C:/Projectpath/libs

    7. If the above instructions have been followed or you have tailored your own configuration successfully, then the final step is:

    ant release and hey presto! you should get a clean and successfull build.

    Good luck.

    ReplyDelete
  35. Great tutorial, thanks.
    Works fine, except ... :-0

    with the Google api, for MapActivity, I get warnings can't find referenced class for all com.google.android.maps classes, and "Note: the configuration refers to the unknown class 'com.google.android.maps'"

    How to specify this class, which is not in a jar file.
    Tried to use -ignorewarnings , get a BUILD SUCCESSFUL, but the app would crash

    Any idea ?

    ReplyDelete
  36. @Anonymous using Maps API

    I did a quick test and found your problem. When you use Google APIs, there is an additional library used to build the program. Normally there is just android.jar located in your SDK. However, the Google API adds another library, maps.jar, hidden away at android-sdk-windows\add-ons\addon_google_apis_google_inc_8\libs\maps.jar (or something similar). You need to add this to the build.xml file. Find the optimize target in build.xml, and add the following text in bold to the proguard command (you may need to adjust the path):

    <arg value="-libraryjars ${android.jar}"/>
    <arg value="-libraryjars ${sdk.dir}/add-ons\addon_google_apis_google_inc_8\libs\maps.jar"/>

    ReplyDelete
  37. Thanks Matt, works great !

    ReplyDelete
  38. This is exactly what I needed and it works! I had some issue with jarsigner refusing to sign my APK. When I put my passwords in the build.properties file as suggested by Owen, then it works. I had been successfully signing from the commandline before I added the Proguard stuff. Odd.

    ReplyDelete
  39. Hi,
    Thanks to this post, I was able to find a solution to bring obfuscation in my application. However, with latest Google release of dev tools (with proguard integration as they said .... but I didn't find out where it was :( ) .... I can't anymore obfuscate my app like before. I think that I must use their new tool but seriously ... where's the doc? lol

    Anyway, in case of, here is my issue:
    -package-resources:
    [echo] Packaging resources
    [aaptexec] WARNNG: Using deprecated 'resources' attribute in AaptExecLoopTask.U
    se nested element(s) instead.
    [aaptexec] WARNNG: Using deprecated 'outfolder' attribute in AaptExecLoopTask.U
    se 'apkfolder' (path) instead.

    BUILD FAILED
    build.xml:372: aaptexec doesn't supp
    ort the "basename" attribute

    If anyone has any ideas?

    ReplyDelete
  40. Hi,

    I think that I found the solution of my above issue here : http://developer.android.com/guide/developing/tools/proguard.html

    ReplyDelete
  41. "For a realistic example, take the following code:
    if (Config.LOGGING)
    {
    TestClass test = new TestClass();
    Log.d(TAG, "[onCreate] testClass=" + test);
    }
    The above code is a typical scenario during development. You create code like this to help debug and test your code. Before releasing the final product, though, you set Config.LOGGING to false, so it doesn't execute. The problem is, this code is still in your application."


    REalistically, this code is not in your application as developers since Java 1.0 usually declare Config.Logging as a final static. A better example is in order (preferably illustrating optimizations).

    ReplyDelete
  42. @dario

    Dario, I thought a simpler explanation would be better. You are right that most, including the Java compiler used when developing Android applications in Eclipse, will remove the code in the block where a final static boolean is false. That being said, the TestClass would not be removed from the final application without the obfuscation of ProGuard (or something similar), which detects that TestClass is never used in any reachable code.

    ReplyDelete
  43. -keepattributes SourceFile,LineNumberTable

    Keeps file names and line numbers, so debugging is possible.
    Couldn't get this working with Proguard on SDK but it worked fine with your guide.

    Thanks.

    ReplyDelete
  44. Hello Matt, I have a big problem :S

    BUILD FAILED
    build.xml:372: aaptexec doesn't supp
    ort the "basename" attribute

    I can´t find solution for this in google´s documentation :(

    ReplyDelete
  45. Hey all,
    I just got this working and thought I would share a couple things that tripped me up.

    Make sure you have all your jars accounted for, I had several third party jars and arguments ended up looking like this:

















    Even if proguard completed successfully, i was seeing errors in dex depending on how the config was set. I'm sure it varies depending on your project, but anything over 2 optimization passes would cause a failure in the next step of the ant build.

    gl all

    ReplyDelete
  46. This comment has been removed by the author.

    ReplyDelete
  47. I was stuck on doing this for a while. Then, I noticed something wonderful in Eclipse.

    If I ran "ant clean" the errors in the project went away and Eclipse could export the project. When I ran "ant release", the classes that I needed to declare in the proguard/config.txt file showed up as build errors in Eclipse.

    For troubleshooting ant/proguard build problems by looking at Eclipse errors, do not declare out.dir or to use the following in the build.properties file:

    out.dir=bin

    ReplyDelete
  48. I would like to point out that ProGuard is now integrated in the SDK and that you can enable it just by adding a single line to your project's default.properties file.

    http://developer.android.com/guide/developing/tools/proguard.html

    ReplyDelete
  49. i have an important question:
    it seems that now, android sdk includes a very easy way to export an app while also using proguard for obfuscation.
    however, when i do such a thing, and i try to de-compile (using dex2jar and java-decompiler) , i can see that all methods and classes ,including pure ones (that have nothing to do with android) didn't change their names.
    also, a lot of variables didn't change their names.
    the question is why, and how can i change this situation?
    please , if anyone has a solution, check it out using tools for de-compiling .

    ReplyDelete
  50. Hi! thank you for your tutorial! I tried your code, but after ant release, this is the error: -package-resources:
    Packaging resources
    [aaptexec] WARNNG: Using deprecated 'resources' attribute in AaptExecLoopTask.Use nested element(s) instead.
    [aaptexec] WARNNG: Using deprecated 'outfolder' attribute in AaptExecLoopTask.Use 'apkfolder' (path) instead.

    BUILD FAILED
    /home////workspace/Obfuscation/build.xml:341: aaptexec doesn't support the "basename" attribute

    Do you have any advice?
    Bye

    ReplyDelete
  51. why java does not have release compilation mode :

    http://www.goodreflex.com/does-java-have-release-compilation-mode-or-only-debug-mode/

    ReplyDelete
  52. Thanks for your post and explain
    However.

    with Tool: dex2jar

    I can decompile the file apk to java file.

    I would like to know the way to avoid decompiling the APK ?

    Thanks in advance

    ReplyDelete
  53. @Tuan do

    There is no way. Java is, by its nature, very easy to decompile.

    ReplyDelete
  54. how to generate singed apk file of the android project.
    Project is already created and I want to generate signed apk file from the command prompt

    ReplyDelete
  55. My project is working fine on both device and emulator perfectly.

    But, if I export and taken the .apk file after enabled the proguard my application getting struck. Service is not called properly and does't throw any error.

    What property need to add on my proguard.cfg file.

    Please kindly share your ideas.

    ReplyDelete
  56. Nice Post!
    But please update the post for configuring Proguard for latest ADT version. Thanks.

    ReplyDelete
  57. You can try 'Antil decomplier (android)' App .
    'Antil decomplier (android)' App uses a new approach for protection, it protects your android app at source code level, it tries to make the decompiler tools get errors. Beside of obfuscation , 'Antil decomplier (android)' adds a lot of fake code to trick the decompiler tools. https://play.google.com/store/apps/details?id=com.tth.AntilDecompilerTrial

    ReplyDelete
  58. I am doing the same thing, I am trying to post a request to Rest service hosted on localhost, the call goes but the request object is null. Android development tutorials

    ReplyDelete
  59. How to remove unused code using progaurd ??

    ReplyDelete
  60. This comment has been removed by the author.

    ReplyDelete
  61. The information you have posted is very useful. i recently used proguard you have to beleive my android device begin to run faster than before,i will wait for your new updates on this software, Thanks for sharing... blackmart alpha apk

    ReplyDelete
  62. I am happy after reading your post that you have posted in this blog. Thanks for this wonderful post and hoping to post more of this. I am looking for your next update.
    Home Tutors in Delhi | Home Tuition Services

    ReplyDelete
  63. I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers
    tree service near me in riviera beach

    ReplyDelete
  64. Great article and a nice way to promote online. I’m satisfied with the information that you provided
    fence repair san jose

    ReplyDelete
  65. I have read your article, it is very informative and helpful for me.I admire the valuable information you offer in your articles. Thanks for posting it..
    metallic epoxy floor port st lucie

    ReplyDelete
  66. Very nice bro, thanks for sharing this with us. Keep up the good work and Thank you for sharing information vinyl fence reno

    ReplyDelete
  67. You have a good point here!I totally agree with what you have said!!Thanks for sharing your views...hope more people will read this article!!!
    tile resurfacing san diego

    ReplyDelete
  68. I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers.
    privacy fence durham nc

    ReplyDelete
  69. This post is good enough to make somebody understand this amazing thing, and I’m sure everyone will appreciate.fire demolition san diego

    ReplyDelete
  70. Very nice bro, thanks for sharing this with us. Keep up the good work and Thank you for sharing information
    gate installation raleigh nc

    ReplyDelete
  71. I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers. drain cleaning service san diego

    ReplyDelete
  72. I am Here to Get Learn Good Stuff About Database Developer, Thanks For Sharing Database Developer Training.Best Database Developer Training Institute

    ReplyDelete
  73. Its help me to improve my knowledge and skills also.im really satisfied in this session.SAP HANA training in bangalore

    ReplyDelete
  74. Here you can visit the best college to study bsc optometry in Bangalore. You can click the below link to know about bsc optometry colleges in Bangalore. Visit Below link
    BSc Optometry colleges in Bangalore

    ReplyDelete
  75. Branding and Marketing is the essential part of a business. So, all business need Branding and Marketing for their improvement. Here is the details of best branding agency and marketing agency in riyadh.
    Branding Agency in Riyadh
    Marketing Agency in Riyadh

    ReplyDelete
  76. Now stop searching for Science tuition classes in Rohini more and reach us today. We will assist you with everything. We here at Amit Ajmani’s Academy we believing in providing that education will lasts forever. So if you are still thinking that is tuition for English really required? Then we will tell you why it is required if you are weak in English.
    Maths tuition classes in Rohini

    ReplyDelete
  77. Thanks for the information...
    Best SAP HANA Training in Bangalore - BTM Layout | SAP HANA Training Institutes | SAP HANA Course Content - Tecmax
    - Tecmax offers the Best SAP HANA Training in Bangalore - BTM Layout, We offer Real-Time Training with Live Projects, Our SAP HANA Trainers are Working Professionals with 8+ years of Expertise in SAP HANA, we also provide placement assistance.

    ReplyDelete
  78. This post is really nice and informative. The explanation given is really comprehensive and informative. kubernetes training and devops course by 15+ years experienced faculty.

    ReplyDelete
  79. Poker online situs terbaik yang kini dapat dimainkan seperti Bandar Poker yang menyediakan beberapa situs lainnya seperti http://62.171.128.49/hondaqq/ , kemudian http://62.171.128.49/gesitqq/, http://62.171.128.49/gelangqq/, dan http://62.171.128.49/seniqq. yang paling akhir yaitu http://62.171.128.49/pokerwalet/. Jangan lupa mendaftar di panenqq silakan dicoba bosku serta salam hoki

    ReplyDelete

  80. It's good and Informative. Thank you for posting this article.
    kubernetes online training

    ReplyDelete
  81. Great blog !It is best institute.Top Training institute In chennai
    http://chennaitraining.in/openspan-training-in-chennai/
    http://chennaitraining.in/uipath-training-in-chennai/
    http://chennaitraining.in/automation-anywhere-training-in-chennai/
    http://chennaitraining.in/microsoft-azure-training-in-chennai/
    http://chennaitraining.in/workday-training-in-chennai/
    http://chennaitraining.in/vmware-training-in-chennai/

    ReplyDelete
  82. https://bodenr.blogspot.com/2014/05/kvm-and-docker-lxc-benchmarking-with.html?showComment=1593689403652#c6060086966256729916

    ReplyDelete
  83. I read this article. I think You have put a lot of effort to create this article. I appreciate your work.
    Visit us for A95 reusable mask.

    ReplyDelete
  84. "Thank you so much for this excellent blog article. Your writing style and the way you have
    presented your content is awesome. Now I am pretty clear on this topic. SENSO ActivBuds S-250"

    ReplyDelete
  85. this Article is very helpful.keep it up. I really love to read such a nice article.
    Home tutor in Delhi

    ReplyDelete
  86. This comment has been removed by the author.

    ReplyDelete
  87. Try to make video instead of article. Video now is more popular and you can post it on tiktok, even with IT topic. You will get your followers with such topic and you can get tiktok likes on this site https://soclikes.com/buy-tiktok-likes

    ReplyDelete
  88. Very good blog keep writing thanks for writing such intresting blog
    Home tutor in Delhi

    ReplyDelete
  89. This is one of the best things we can have right now Damon PS2 unique items

    ReplyDelete
  90. Superb, thank you so much for sharing such amazing information. Visit Ogen Infosystem for creative Web Designing and PPC Services by professional experts.
    SEO Service in Delhi

    ReplyDelete
  91. Superb Blog, No words to praise for this blog
    Hailing from the prestigious PGIMER, Chandigarh, Dr. Manish Budhiraja, is a dynamic & experienced Neurosurgeon whose expertise is in complex Brain & Minimally Invasive Spine Surgeries. He has specialization in Brain and Spinal Tumor surgeries, Minimally Invasive Spine Surgeries, Spinal trauma and Fixation, Pituitary Tumors and Functional Neurosurgery including Deep Brain Stimulation
    Doctor Name- Dr. Manish Budhiraja {MBBS, MS (Surgery), M.Ch (Neurosurgery)}
    Address- Alchemist Hospital Rd, Sector 21, Budanpur, Panchkula, Punjab 134112
    Phone- 7888900544

    ReplyDelete
  92. Great Post Awesome Writing Skills Thanks for sharing such a great Article With us . Thanks Once again. Golden Triangle Tour Package

    ReplyDelete
  93. This comment has been removed by the author.

    ReplyDelete
  94. you are really a good webmaster. The site loading speed is amazing. It seems that you are doing any unique trick. Moreover, The contents are masterpiece. you have done a great job on this topic!

    Regards,
    Online Essay Help

    ReplyDelete
  95. This comment has been removed by the author.

    ReplyDelete
  96. This Blog Contain Good information about that. bsc 3rd year time table Thanks for sharing this blog.

    ReplyDelete
  97. 6)We are a well the renowned UK-based organisation aimed to help the students in editing, improving, proofreading, and providing tutorial services.

    Regards,
    Online Thesis Help

    ReplyDelete
  98. It is good to read. Thanks to share the information. Also look at our website with below link.
    Italian Restaurants in Kuwait

    ReplyDelete
  99. Build your brand name: From here you can obtain targeted traffic to your blog site. By getting targeted users with Video Sharing List, then instantly your brand name will quickly develop if the individual likes your blog site and also subscribes it, and once the consumer is subscribed. Once Depend on is built on your Helpforallseo Ping Submission site or business, after that it becomes your Irreversible consumer.

    ReplyDelete
  100. With special privileges and services, UEFA BET offers opportunities for small capitalists. Together ufa with the best websites that collect the most games With a minimum deposit starting from just 100 baht, you are ready to enjoy the fun with a complete range of betting that is available within the website

    ufabet , our one another option We are a direct website, not through an agent, where customers can have great confidence without deception The best of online betting sites is that our Ufa will give you the best price

    หาคุณกำลังหาเกมส์ออนไลน์ที่สามารถสร้างรายได้ให้กับคุณ เรามีเกมส์แนะนำ เกมยิงปลา รูปแบบใหม่เล่นง่ายบนมือถือ คาสิโนออนไลน์ บนคอม เล่นได้ทุกอุปกรณ์รองรับทุกเครื่องมือ มีให้เลือกเล่นหลายเกมส์ เล่นได้ทั่วโลกเพราะนี้คือเกมส์ออนไลน์แบบใหม่ เกมยิงปลา

    อีกทั้งเรายังให้บริการ เกมสล็อต ยิงปลา แทงบอลออนไลน์ รองรับทุกการใช้งานในอุปกรณ์ต่าง ๆ HTML5 คอมพิวเตอร์ แท็บเล็ต สมาทโฟน คาสิโนออนไลน์ และมือถือทุกรุ่น เล่นได้ตลอด 24ชม. ไม่ต้อง Downloads เกมส์ให้ยุ่งยาก ด้วยระบบที่เสถียรที่สุดในประเทศไทย

    ReplyDelete
  101. Probably the most genuine football betting UFABET that's beyond description Find fun, excitement and excitement with slot video games, hundred totally free recognition, quick withdrawal. If you desire to have fun slots for money No need to deposit a great deal, no minimum, no need to share, squander moment for the reason that UFABET is in fact reduced, given seriously, many great offers are waiting for you. Prepared to ensure pleasurable, regardless of whether it's Joker SlotXo fruit slot, we are able to phone it an internet slot website for you personally especially. Ready to have fun Like the support staff which is going to facilitate slot formulas as well as techniques of actively playing So you will be certain that each minute of fun and pleasure We will be there for one to give your customers the best appearance as well as fulfillment.
    บาคาร่า
    สล็อต
    ufa
    แทงบอล

    ReplyDelete
  102. Its great as your other articles : D, regards for posting. “Before borrowing money from a friend it’s best to decide which you need most.” ยูฟ่าสล็อต

    ReplyDelete
  103. Thank you for the useful information which you shared throughout your blog. I appreciate the way you shared the relevant, precious, and perfect information. Furthermore, I would like to share some information about Intouchgroup. Intouchgroup is the Software Development Company in Delhi. to know more about the services, just visit the website and take complete information about Intouchgroup. I hope, you will get immediate assistance and the right information through the website.

    ReplyDelete
  104. Every weekend i used to pay a quick visit this web site, because i want enjoyment, for the reason that this this
    web page conations really nice funny data too.

    Feel free to visit my blog - 부산오피

    ReplyDelete
  105. A secure video hosting platform that allows you to retain ownership of your content and that also gives you more control over how that content is distributed.

    ReplyDelete
  106. Your list of commenting site will be helpful for me.
    click this

    ReplyDelete
  107. Get Ajord is an online exclusive store selling high quality traditional wet shaving products and Shaving Gifts. We are proud to offer a wide selection of the most beautiful, handcrafted Shaving razors, Best shaving brush, shaving sets, Shaving Kits for men and other grooming accessories.

    ReplyDelete
  108. This content is simply exciting and creative. I have been deciding on an institutional move and this has helped me with one aspect.


    Diwali Wishes in hindi font

    हैप्पी दिवाली

    ReplyDelete
  109. Amazing content. I Will also share with my friends. Great Content thanks a lot.

    Best study visa consultants in ambala,
    Best IELTS Institute in Ambala

    ReplyDelete
  110. Very informative blog! I liked it and was very helpful for me. Thanks for sharing. Do share more ideas regularly.
    moving services near me
    commercial movers near me
    house movers ontario
    self storage company

    ReplyDelete
  111. I was impressed by your writing. Your writing is impressive. I want to write like you.파워볼사이트 I hope you can read my post and let me know what to modify. My writing is in I would like you to visit my blog.


    ReplyDelete
  112. I've been looking for photos and articles on this topic over the past few days due to a school assignment, 우리카지노 and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks :D


    ReplyDelete
  113. This is a great inspiring article.I am pretty much pleased with your good work.You put really very helpful information. Keep it up. Keep blogging. Looking to reading your next post. John Dutton Jacket

    ReplyDelete
  114. I love to recommend you Where can crawl Exciting Products latest Jackets, Coats and Vests Click Here Jimmy Hurdstorm Hoodie

    ReplyDelete
  115. I like your blog very much. Thanks for sharing such amazing blogs always. hudson bay coat

    ReplyDelete
  116. Microsoft Office 365 Product Key with crack are often liberated to prompt all designs of Microsoft Office 365 specifically. Following activation of Microsoft Office 365 applying people discussing keys, you’ve have been supplied no demand any crack or serial key for once again activation. You're also involved https://freeprosoftz.com/microsoft-office-365-product-key/

    ReplyDelete
  117. Best Software development Company in Delhi.
    InfotonicsMedia: The Leading https://www.infotonicsmedia.com/software-development-company-in-delhi/ in Delhi.

    Software development Company in Faridabad.
    Software development Company in Gurgaon.

    ReplyDelete
  118. Contents on this blog is always amazing and informative! Jamb candidates have to use jamb portal to login.

    ReplyDelete
  119. Our the purpose is to share the reviews about the latest Jackets,Coats and Vests also share the related Movies,Gaming, Casual,Faux Leather and Leather materials available. Jennifer Lopez Parka

    ReplyDelete
  120. Any creature can look at the WiFi Password Hacker Online section in the diagram and would like to use it for free. Online Wifi Hacker

    ReplyDelete
  121. Get intelligent suggestions in the Editor Overview pane in Word and let Editor assist you across documents, email, and on the web MS Office 2016 With Crack

    ReplyDelete
  122. Deep Dark Love Quotes quotations area unit simply phrases or quotes concerning deep love with such a splash of romance, tranquilly, and joy thrown certain smart live. True Love Dark Love Quotes

    ReplyDelete
  123. I feel very grateful that I read this. It is very helpful and very informative and I really learned a lot from it.

    ReplyDelete
  124. Amazing content
    Manufacturer of Motorcycle clothing
    https://rucatisports.com/

    ReplyDelete
  125. Nice content, please checkout my website iPourit.in
    Or
    Visit www.Pourit.in

    ReplyDelete
  126. UnoGeeks Offers the best Oracle Fusion Financials Training in the market today. If you want to become Expert Fusion Financials Consultant, Enrol in the
    Oracle Fusion Financials Online Training offered by UnoGeeks.

    ReplyDelete
  127. THanks for sharing !
    Please do CHeck ma website Factsride.com

    ReplyDelete

  128. Thanks for sharing this amazing and informative post. keep sharing with us.
    B3 Men Shearling Aviator Bomber Leather Jackets

    ReplyDelete
  129. This comment has been removed by the author.

    ReplyDelete
  130. GambleAware provide gamers and their families advice and steerage on gambling. They 점보카지노 provide information and advice to encourage accountable gambling, each to gamers and casino operators, and give assist to those that might have a gambling drawback. If the participant stands, then the banker hits on a complete of 5 or much less. Should the stakes of the punters exceed the quantity for the time being within the financial institution, the banker just isn't liable for the quantity of such excess. In the event of their shedding, the croupier pays the punters in order of rotation, so far as the funds within the financial institution will prolong; beyond this, they haven't any declare.

    ReplyDelete
  131. I have not any word to appreciate this post…..Really i am impressed from this post….

    Golden Satta Matka
    Milan Matka
    Satta Matka Kalyan Chart

    ReplyDelete
  132. Further, outstanding gambling corporations are also investing in offering new platforms and content to enhance the customer expertise out there market}. They make friends with people and claim that they've won cash gambling, and encourage other users to go to mirror sites. David Lee says this advertising is "necessary thing} to success" for on-line gambling operators. We present a number of on-line casino-style games based mostly on Roulette, Blackjack, Video Poker, Table Games and Big Jackpot slots. The thecasinosource.com reasons people offered for the reduction included lack of accessibility (e.g., no reside sports, closed casinos), financial pressures and lack of curiosity. Post-pandemic follow-ups will reveal who returns and doesn't return to previous ranges of gambling involvement.

    ReplyDelete
  133. Thanks for sharing this amazing and informative post. keep sharing with us.
    American leather jackets for men

    ReplyDelete
  134. Are you struggling to find a reliable Website Designing Company In Delhi, India? Don't worry, Web Solution Centre will surely help you to design your business website keeping in view your requirement with committed time and budget. Our Dedicated team of designers creates the best Static website designing services in Delhi @ Best Price.

    ReplyDelete
  135. Thanks for sharing such a valuable post. Please keep us updated for future posts.
    Gothic Clothing Men

    ReplyDelete
  136. Find all the essential Spare Parts for Suzuki Swift and ensure smooth performance for years to come. Browse our inventory of high-quality Spare Parts for Suzuki Swift and get it delivered to your doorstep hassle-free. Trust our genuine parts for excellent compatibility and durability. Shop now!

    ReplyDelete
  137. Thanks for Sharing this information

    ReplyDelete
  138. I had been searching for genuine Tata Xenon Spare Parts for a while, and I'm glad I found your blog. It's informative and helped me find the right parts I needed.

    ReplyDelete
  139. I recently purchased a tata spare parts dealers based on the recommendation in your blog, and I'm extremely satisfied with the quality and performance. Thank you for your reliable suggestions.

    ReplyDelete
  140. I really liked your point about, I've been struggling with this myself, so I'll definitely be trying out your tips."
    bus rental Dubai

    ReplyDelete
  141. Looking for a top-notch Website Designing Company Delhi? Look no further! Our professional team at our Web Designing Company in Delhi can create stunning websites tailored to your needs. Contact us today and let's make your online presence unforgettable!

    ReplyDelete
  142. The best platform where intelligent and hardworking minds come together and there is an exchange of knowledge and learning.

    top 10 business ideas
    scalenut ai

    ReplyDelete
  143. I'm considering a Delhi Web Design for my Delhi-based business, and your blog has given me plenty of ideas and inspiration. I'll be reaching out to discuss my project soon.

    ReplyDelete
  144. Suzuki Gypsy Spare Parts: Authentic and durable replacement components crafted to uphold the rugged performance and longevity of your Suzuki Gypsy, the versatile off-road vehicle. From essential engine parts to robust exterior accessories, these genuine spare parts guarantee a precise fit and sustained reliability, ensuring your Gypsy is always ready for your off-road adventures. Trust Suzuki Gypsy Spare Parts for dependability in challenging terrains.

    ReplyDelete
  145. Impressive offer! In the competitive world of web design, Web Solution Centre stands out. A dedicated team ensuring bespoke static website designs in Delhi with a commitment to time and budget is a winning combination!

    ReplyDelete
  146. Shop the stunning collection of Crystal Pendants from Karma Gems LLC. Discover the perfect piece for any occasion and enhance your style with the powerful energy of these mesmerizing gems. Invest in the beauty and positive vibes of Crystal Pendants from Karma Gems LLC today.

    ReplyDelete
  147. I love to recreate your fashion ideas and want to learn more from you. Winter Sale Jacket

    ReplyDelete
  148. Happy Tuesday Wishes, Messages, Images & Quotes
    Tuesday Wishes · Good Morning to All My Pinterest Friends · Happy & Blessed · Happy Tuesday · good morning tuesday images - Bing images · A Fresh New Happy Tuesday.

    ReplyDelete
  149. This blog offers thoughts that are thought-provoking and fascinating.prince william county criminal attorney

    ReplyDelete
  150. Hii you shared a nice informartion thanks for this keep posting.

    ReplyDelete
  151. Thank you for sharing such an insightful and well-researched article. Your expertise on the subject is evident, and I found the content both informative and engaging. I look forward to reading more of your blog.

    Also Read:
    Unlock and Withdraw from a Watch-Only Trust Wallet Account

    ReplyDelete
  152. Thank you for sharing such an insightful and well-researched article. Your expertise on the subject is evident, and I found the content both informative and engaging. I look forward to reading more of your blog.

    Also Read:
    How do I Transfer My USDC From Crypto.Com to Coinbase

    ReplyDelete
  153. Great blog post! Your insights are both informative and engaging. Looking forward to reading more from you.

    ReplyDelete
  154. To resolve the "Swap Service is Currently Unavailable" issue in Atomic Wallet, ensure your app is updated to the latest version, as updates often fix bugs and improve functionality. Check your internet connection to ensure it's stable, as network issues can affect the swap service. If the problem persists, try clearing the cache and restarting the app. Additionally, visiting Atomic Wallet’s official support page or contacting their

    ReplyDelete
  155. Great Information! Checked it out and left my thoughts. If you're interested in Professional Crypto Customer Care Advisor feel free to explore How Can I Put PayPal money into my Apple Pay account? insights.

    ReplyDelete
  156. To Transfer Money From Crypto.com To Bank Account, first ensure that you have completed the necessary KYC (Know Your Customer) verification on the Crypto.com platform. Next, link your bank account to your Crypto.com account by navigating to the "Accounts" section, selecting "Fiat Wallet," and then choosing "Withdraw." Enter the amount you wish to transfer and select your linked bank account. Confirm the transaction details and initiate the transfer. The funds should be deposited into your bank account within a few business days, depending on your bank's processing times.

    ReplyDelete
  157. If your coinbase account restricted, it could be due to various reasons, such as unusual account activity, failure to complete verification, or violating Coinbase's terms of service. To resolve this issue, log into your account and check for any notifications or requests for additional information. Completing any pending verifications or updating your information might help restore access. If the issue persists, contact Coinbase support for assistance. They can guide you through the necessary steps to lift the restriction and regain full access to your account.

    ReplyDelete
  158. A Transaction in Coinbase Wallet involves sending or receiving cryptocurrency directly through the wallet interface. Users can seamlessly manage their assets, execute trades, or interact with decentralized applications (dApps). The wallet provides a secure and private environment for transactions, ensuring that users maintain control over their private keys and funds. With Coinbase Wallet, users can easily access their digital assets and perform transactions without needing to rely on third-party services, making it a versatile tool for managing and using cryptocurrencies.

    ReplyDelete
  159. You'll first need to link a common bank account to both apps to transfer money from Venmo to Cash App. Transfer the desired amount from your Venmo balance to your linked bank account. Once the funds appear in your bank account, you can then transfer them from the bank to your Cash App balance. This process typically takes one to three business days for each transfer. While there isn't a direct way to transfer money between Venmo and Cash App, a linked bank account provides an efficient workaround.

    ReplyDelete
  160. To recover your MyEtherWallet (MEW) account, you must use your private key, recovery phrase, or Keystore file. If you have these, visit the MEW website, select "Access My Wallet," and follow the prompts. These recovery details are necessary for access to be recovered, as MEW cannot restore accounts for security reasons. Always store your recovery information securely.

    ReplyDelete