Posts Tagged ‘Programming’

Android robot logo.
Image via Wikipedia

I did some hacking yesterday with Calculon in a attempt to see if it could be extended similar to robotium. Not possible, robotium is the best option..sorry MK(Calculon developer). Thus, we have a IDE plugin or build that runs all the tests at one time and completes a code coverage report along with a DSL syntax to reduce the complexity of writing unit tests.

It will not be as pretty as say Spock, but still it reduces test writing expertise to something manageable.

But Android emulation is unique in that we have to start up anew AVD to test a different device model. The obvious next step is to get some way to start and stop the AVDs in your emulator inventory and run install-app and tests each time and produce test reports for each device model.

Apache ANT is too brittle of DSL to be flexible enough to work as a work-flow testing scenario. This might be an ideal situation to use Gradle in as it uses Groovy’ DSL with the ability to run/execute ant tasks/targets, maven stuff, ivy, etc.

Dependency Injection vs Mock wise I do not see a need in testing to resort to DI if you have Android-Mock available. But maybe some developers prefer to use DI rather Android-Mock, it just seems that yuo are moving your focus away from  tests up the DI chain if you pursue that route.

Enhanced by Zemanta
Advertisements

AndCooperANT alpha release supporting ant build of regular android java projects, javadoc generation with UML diagrams, js javadoc generation for those using webkit, proguard obfuscation, android library projects, android jar library projects,  and android test projects.  Its alpha as I have not finished docs on how to customize javadoc look, code quality reports look, js javadoc look, etc.

I am converting all my projects to using it, so I am eating my own dog food folks to uncover any bugs/issues.

Enhanced by Zemanta

Secrets of the Android Dev Ninjas

Posted: September 12, 2010 in Android
Tags: , ,

You have to remember that Android is a new platform so while some interesting stuff is being built, the documents are far from being updated. Take for instance the AAPT tool.  Did you knbow you can do this with the AAPT tool:

1. Get the proguard config file to use by using the -G aapt option so you can use proguard to obfuscate the application’s code.

2. Insert code version into the manifest by using the –version-code option.

There is a full listing here.

Enhanced by Zemanta
the android logo
Image via Wikipedia

I guess I have a set of stupid questions, stupid as in I should have asked them sooner. These questions concern Android Code Best practices.

If you look at either Android Source code for Android default applications or for example the ReplicaIsland Game you see certain patterns. One, hard to encapsulate and decouple as in the bean/service pattern concepts not used. Two, the MVC pattern non encapsulated.

Due to the size of both types of applications could we not benefit form use of a non-reflection, non-aop Dependency Injection and a use of a small MVC framework? The benefits would seem to be in the DI case to be the program logic would be back in classes with the Android boilerplate code being the items injected and reducing the coding by 25%. In the case of using a small MVC framework  one would get a better programming contract between the applications presentation layer, logic layer, and the model layer and may even be easier to implement a real actual ORM .

I have started playing with O’Reilly’s Android CookBook Wiki and The MVC Principle contribution request triggered this thinking as how would you teach MVC in Android in 3 pages since the MVC pattern is somewhat modified in Android. Modified by meaning in that the View GUI navigation is not separate from the Controllers, etc.

Some of the MVC pattern is of course there in Android as we could extend the Application class as a Controller as a sourceforge Android-MVC does that, in alpha state at the moment. Android-XMBCRemote also made an attempt at MVC and in their approach they had more than one controller and it seemed to be that the benefits they obtained was a better module or unit encapsulation of the application model units which would translate to a better and easier maintainable code base.

Could it be performance? Would be a reasonable question, right? On the Dependency injection side RoboGuice and Yasdic do not use reflection so we do not or should not see a performance hit. On the MVC framework side such as using Android-MVC there would be a slight increase in coding to use the MVC framework but if you are using Dependency injection with that where everything is loaded in the lazy fashion(only loaded when needed, etc) that should counter balance the added code used to use the Android-MVC in an application.

What brought up this line of thinking, originally is I was debating actually teaching java using the Android Platform and of course the modified MVC pattern came up, etc. But, if you had a decent combination of DI and MVC framework avoiding java reflection you could use the strength of those patterns not only in having easier maintained code but also to teach java using android. The person I was debating this with brought up the fact that Android is visual, but that is an advantage as that is one of the channels of learning is in fact visual.

Of course part of Android is XML. But no one teaches  SGML any more and yet we use it every day in word processors(most word processors use SGML as one of their internal core formats). The way Google implemented using XML in Android is just one step closer to using XML without having to know all the internals and thus that point about it might detract from teaching java using android should be a non-operation debating point.

The obvious first step would be to convert some small and big android applications to use use dependency injection(roboguice) and and android centric MVC and see what the challenges are and the benefits and write about both.

Side Note: Yes, Android_MVC is missing other MVC framework features such as using the facade apttern, etc. That is why I would imagine the project lead is thinking of forking his own project and why others might also want to fork it. Nothing against the code effort as its a very first good start.

Enhanced by Zemanta
In Android Java Applications we use a logging system to record log events including errors, debugging, etc.
Log levels are:

Verbose 2
Debug 3
Info 4
Warn 5
Error 6
Assert 7

The default log level set by the Android OS is 4 and above. Its the reverse for the levels of detail
in that verbose is the most detailed log level you can use. And debug is compield but stripped out
at runtime and obvoously you do not want Verbose triggered in your producition application.

At bare minimum to get debug and verbose to show you have to set it, which you can do via:

$adb setprops log.tag. DEBUG

Quick question, if you do this what log levels show in logcat? The log level you have sset and
everything above that log level shows in logcat. Thus if you want everything to show you set Verbose log level.

Okay so where does it show up? The Android OS by default logs to logcat four ‘log streams’;

Main
Radio
Events
System

Logs of levels Verbose through Assert are sent to the Main Log stream, in other words all application logging.

Thus, how do we prevent verbose and debug from being triggered in the produciton application but have it
triggered in the application we are debugging without changing any code?

You wrap the log calls with isLogable, for example in log wrapper class:

public static void debug(final Class myClass, final String tag,
final String msg) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, myClass.getSimpleName() + “:” + msg);
}
}

In this case if setprops is not used to set either Verbose or debug than log debug never gets executed
because android OS defaults to INFO log level and above if not set via setprops. if you use log calls
wrapped by isLoggable than you never have to worry about removing log calls to Debug or Verbose
as the isLoggable if statements ensure its not executed if not set to Loggable.

One of the best coding practices for Android Java Application Development is code wrapper classes that
make your code development easier by saving steps. Cdoing a log wrapper class should one of your
first steps in best coding practices.

Enhanced by Zemanta

Good morning and welcome to the beginning of the Android ‘Land-grab’. Some useful tools:

1. OpenNCF has published their sdk for andorid and an android add on at:

http://sourceforge.net/projects/open-nfc/files/

2. The AppInventor site went live:

http://appinventor.googlelabs.com/about/

Its a visual programming tool to develop android applications.

3. OpenFrameworks has released an android version for NDK development:

http://www.openframeworks.cc/setup/android-eclipse

4. Mark Murphy has released an Android Jar library tool called AndParcel that makes it easier for Androdi Jar Library deployment for those who do not use the Eclipse IDE and Gogle ADT combination at:

http://andparcel.com/

Enhanced by Zemanta

Like I never complain, right? While I appreciate the hard work every Android OS contributor has put in thus far some of the android code samples leave a lot to be desired. Code style mess-ups like if statements without brackets, parameters not finalized, etc. Still using the old test sub-folder in project instead of separate test project way of testing.

I can understand if we are not using modern IDEs.  But are we not using Eclipse, IDEA, NetBeans, etc? Well did we not have time considering that these code samples are supposed to show correct coding techniques?

Guess how long it took to clean up the LunarLander code project using properly set tools to get it to actually run on a device and emulator? Now, I have not completed the text code project yet but it was only one hour.

Yes, I am putting some  at github in the month of July. We have to have more professional code samples. The code samples in the SDK are just as important as the outstanding behind the scenes UI work that is occurring for Android 3.0 release in October.

Enhanced by Zemanta

One of the obstacles lately that I have run into is how do you describe an Android Agile Enabler Build System such as AndCooper. Usually, i am communicating with managerial people that already have some exposure to such code review items as unit/mock test code coverage, code comment coverage, code correctness measurements, and etc. Thus, you would think in explaining that currently only have of that is supported in that build systems have yet to be built supporting the other half I get this blankness in the conversation on their part and that is after I explain that because unit/mock testing and code coverage testing occurs on device it requires a more integrated build system than just throwing together a few lines of ANT XML scripting.

In other words usually in most code review processes focus around a continuous build process producing code analysis reports used in the code review process. While EMMA reports can be generated off EMMA data produced, the unit/mock test data is not in report form yet as its in either the IDE stdout/console, or the device/emulator. Now you could make the project manager have to know how to start up an emulator and run the build to get the data manually but most managers are busy and thus it should be automated. And quite frankly automating the process so that the developer can use that feedback daily catches errors before they hit the code review process thus saving the whole team development time.

It is quite simple. If you put the right infrastructure in place so that the developer as part of his or her hourly activity can run an automated code review process to use as feedback than there are less items that require correction after the project manager end of day code review. It is not that I do not like explaining it, it is that I am somewhat tired of running into non-caring managers as it has an immediate value to both the costs and that impact on costs towards profits something most project mangers should care about.

Of course it would be nice to encounter a manger that ‘gets it’. Onward, the next few days refactoring the Android Build Life Cycle than the final sequences of testing tasks and than a full preview release.

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]

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]