Posts Tagged ‘Development Tools’

Okay, time for some more eclipse tricks. Create new project, do not click finish yet!  Uncheck the default location and browser and select the parent project folder and in the address bar of project location type /test and you will see:

Correction: Name Project ParentProjectNameTest, ADT plugin will show an extra project at workspace root(you can ignore that as its not an actual project ..ie its not in file explorer on your SystemOS etc.)

If you use build scripts than the tested.project.dir property will change with the test build script in the test directory as it will be a relative location to the parent project. If you use a different IDE, I am assuming you can do the same trick with the IDE Android plugin you have.

Well, if you are using a DVCS like Git you are already using the do not default location to get all your DVCS stuff in one sub-folder for all projects anyway and thus its just an extension of that technique.

Enhanced by Zemanta
Advertisements

One of the founders of  Zutubi came up with extending the JUnit TestRunner used in Android to generate xml reports stored on the SD card that than can be pushed down to a desktop folder using an ant task. The blog post is here and github project page is here.

Thus you can now get unit test reports without having to run them in the IDE.

Enhanced by Zemanta

On Dec 1st Moto released MotoDEVStduo4androd 1.0.2 updated to SDK 2.0. One improvement that might not have been talked about yet is being able to install rest of Eclipse IDe components as MotoDevStudio base starts with just Eclipse Java and some other parts.

So first screen shot Team SVN and Git installed:

As I go through this process I will post more screen-shots. I should also point out I had to Dave Winer yell at someone at MotoDev Studio Team about not being able to install all the Eclipse components. Maybe this is a sign of better listening? This not tot begrudge the MotoDev Studio team in any way as I appreciate the hard work that went on to solve the problem.

Next up is to install WTP. TPTP, BiRT so I can get the eclipse Memory analyzer plugins working and Eclipse ECF.

Reblog this post [with Zemanta]

I use proguard settings specific to Android Java applications so change to fit your needs before using:

task generateProguardConfigFile << { logger.info('Creating andcooper.pro file for obfsucate task') /** * andcooper.pro must have the following text * (the variables are replaced as the fiel is created): * -libraryjars androidJar: externalLibsFolder * -injars outClassesLocation * -outjars obfuscateLocation/classes.min.jar * -keep public class * extends android.app.Activity * -optimizations !code/simplification/cast * -allowaccessmodification * * '\n' goes at end of each line */ andcooperProguardConfig = new file('andcooper.pro') andcooperProguardConfig.withWriter{ writer ->
writer << ‘-libraryjars ’ + androidJar + '; ' + externalLibsFolder + '\n' writer << ‘-injars ' + outClassesLocation + '\n' writer << '-outjars ' + obfuscateLocation + '/classes.min.jar' + '\n' writer << '-keep public class * extends android.app.Activity' + '\n' writer << '-optimizations !code/simplification/cast' + '\n' writer << '-allowaccessmodification' + '\n' } } task obfuscate << { ant.taskdef(resource: 'proguard/ant/task.properties', classpath: configurations.runtime.asPath ) ant.proguard(configuration: 'andcooper.pro') } [/sourcecode] Notice all I am doing is creating the proguard.pro file on-the-fly and than using that in my taskdef via the ANTBuilder.

Reblog this post [with Zemanta]

The main feature, one of them, of Groovy’s Gradle build framework  is that plug-ins will add task to the life-cycle. Life-cycle in this case is the build life-cycle. Since mobile java builds are different than enterprise java I have had to come up with my own build life cycle definition, which looks like this in Gradle:

gradle.taskGraph.whenReady {taskGraph ->

if (taskGraph.hasTask(':debug')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doLast(dependsOn: 'appInstall') {
}
} else {
}
if (taskGraph.hasTask(':release')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'obfuscate') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doLast(dependsOn; 'appProductionSigned') {
}
} else {
}
/**
* mockTestsSomething tasks are defined under the project tag
*/
if (taskGraph.hasTask(':tests:mockAll')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
if (taskGraph.hasTask(':tests:mockFunctional')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
if (taskGraph.hasTask(':tests:mockUnit')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
/**
*  Have to disallow individual task exuciton that is not from
*  the debug, release, and :tests:mockSomething entry points
*
*  we hack it by setting  tasks to false and
*  printing an error message
*/
if (taskGraph.hasTask(':clean')) {
clean.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskgraph.hasTask(':generateJavaClassesFromTemplates')) {
generateJavaClassesFromTemplates.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask(':processJavaPreprocess')) {
processJavaPreprocess.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processSrcResources') {
processSrcResources.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('compileAidlJavaClasses') {
compileAidlJavaClasses.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPreCompileReports') {
processPreCompileReports.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('compile') {
compile.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPostCompileReports') {
processPostCompileReports.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processAssetsResources') {
processAssetsResources.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPackageResources') {
processPackageResources.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processDex') {
processDex.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('appReinstall') {
appReinstall.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('appInstall') {
appInstall.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('obfuscate') {
obfuscate.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}

Basically, the only entry points are debug, release, and mockSomething tasks. I kept the dependencies group in the order of execution thus the build is both readable and understandable and functional. Now it is add in the details of all tasks and start testing each task one by one. With the Gradle 0.8 project feature I was able to eliminate the need for a separate build script to be in the tests/src folder and remotely execute that script.

I should optimize my Life-cycle definition by using Goovy switch statements. Than switch to switch statements for the if-else blocks in my configurations block and I should be down to a compact 300 lines and with the other task details filled in about 800 lines. The ANT build script with the same feature set was turning out ot be 300 lines of mind-numbing not easy to read and understand mess.

Reblog this post [with Zemanta]

One of my complaints has been that the underlying platform. Eclipse 3.4, uses ANT 1.0 which has a major bug. Unzip this into your plugins folder and take out the ANT 1.0 plugin folder in your MotoDEvVStudio for Android install. Now when you do soem tasks like declare the task library for JDepend it will be able to pick up the configuration file whereas with ANT 1.7 it was not due to a bug.

Reblog this post [with Zemanta]

Android-TDD Bug Fixes

Posted: August 7, 2009 in Android, Mobile
Tags: ,

The  java-tests.template having the class extend the wrong class for testing  bug 3350 looks to be apporved for a future SDk release. Hopfully, it is the android SDK 1.6 release. So no wits somewhat offical, I became an Android Project contributor.  Okay, soem more bug fixes to submit this weekend revolving aroudn ANT support of TDD in andorid application development.

Reblog this post [with Zemanta]

I am on the laste final stesp of adding VPP(Velocity Template Preprocessing for WebView html preprocessing and etc) and JavaPP(Java Preprocessing to handle same code base different SDK targets) and the final testing. One of the issues has been getting  to work right with non-Eclispe IDEs in the same easy manner.

Why two preprocessors? VPP is known as a template engine preprocessor, for those who are experienced in other mobile platforms like JavaMe it was a 1st generation preprocessing solution both for text preprocessing and java preprocessing Although, we do not use it for Java Preprocessing(interferes with IDE incremental builds and etc) we do ue it for template duties in producing class file templates fof classes we are starting with in a project in addition to the html stuff for webview.  JavaPP is than used a full Java preprocessing tool in that it recognizes the Java preprocessing commands in the comments and processes them base don trggers defined in ant properties file adn thus we can use the same code base with Android SDK 1.5, 1.6, 1.7, 2.0, and etc.

Release of AndCooper 0.1 should be shortly tonight or  Wed morning.

Reblog this post [with Zemanta]

SAP has developed a memory porfiler for java applications that takes a java memory  dump, a hprof file a heap dump, and analyses that data both visually and otherwise to allow us to do queries of that data to analyze trends and change code. Earier this year they had open sourced this technology and donated it to the Eclipse Project as the sub-project called Eclipse MAT(Memory Analyzer Technology). A the same time the Android Project started working on a converter that converted Dalvik heap dump data to the hprof file format.

Several bloggers have instructions in how to use it in Android SDK 1.5( Such as here and here), the caveat being that the multiple-processes data is not yet converted to hprof format, I would imagine that would be completed in time for ANdroid SDK 2.0.

What you may have noticed that the profiling tools for Android are becoming Eclipse enabled. There is also a profiling data converter to take the traces.txt data and allow you to analyze that data using Eclipse TPTP. Notice tha the underlying data tool engine for both projects is Eclipse BiRT. That will become important in integrating with an Android Application Build System.

Reblog this post [with Zemanta]