Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Saturday, January 29, 2011

Multilayout ListView

This is a multi Layout view sample. You can  use it when you need to display the same amount of data (in sample text and images but it should be located differently
You need to build a special ListView adaptor 

Source code for MultiLayout Adapter is bellow







Beginning Android 2

Tuesday, January 11, 2011

Java pre-processor

How Eclipse works to compile project?

If we are looking for android project compilation process, it contains from many builders
- before resource generator builder;
- resource builder;
- Java compiler;
- package builder;

Next builder will be started after previous one was finished successfully.


Sometimes you may want to use one source for different incompatible platforms (like JavaME MIPS2.0 or Java SE or some other Java specific platform like Android).

The best approach here to have you project separated from Java SDK by creating wrappers on SDK layer and then refer only wrapped classes in your project. Then when in and script for package builder build your project together with Java specific library wrapper.(recommended)

Another way to dial with this problem is to have a preprocessor like C preprocessor and wrap platform specific code. This approach is less clear and it feels like some comments you cannot remove. (not recommended) 

If you need Java cross platform but it is difficult to separate api in your project - you have to redesign you project.

Custom Java preprocessor (also could be done using ant script as well as using external preprocessor tool (like C preprocessor). To understand how it works I have created my own custom preprocessor using ant

Eclipse defines 4 targets
  • before clean
  • manual build
  • auto build
  • during clean 
I have created a simple xml file with 4 targets that is shown below:
  <project name="new builder" >
  <target name="before_clean"/>
  <target name="manual_build"/>
  <target name="auto_build"/>
  <target name="during_clean">
  </project>

Do you have other solution how to build the same app on different Java platforms? 

Tuesday, January 4, 2011

Android and Ant builder. Part 2

About ant commands :
You can create your own command processor with ant (you are able to create elements and ant is able to process commands in ants way (using xml to join parts )

For example for search and replace there is a command that is mapped to java or to implemented in other language application


 <replaceregexp file="file"   match="pattern"    replace="pattern"  

 flags="options"
 byline="true|false" /> ;

 
it is actually a prepared a java class(s) that do the job

Is Ant depends on Java JRE or it is a separate native application? I think it is...
Probably that's why Java and Ant is so close...

I also would like to understand how preprocessor works in Eclipse. It may helps me with my tasks

Wednesday, December 22, 2010

Android Ant builder

Android build process is quite complicated
First of all it is based on ant script together with sdk tools and java apps aligned to ant.

Lets take a closer look to it
to create ant script manually just type:

cmd <enter>
if you don't have Android SDK folder in system PATH environmental variable - add it
set path=%path%;X:\android\android-sdk-windows-1.5_r3\tools

now you can create new or update existent eclipse project
(I assume that you like me create project in eclipse first and then, for some reason, you need to build your fancy application from command line

set current dir to your android project dir

cd c:\apps\myapp <enter>
android update project  <enter>

now you have build.xml in your projects root folder

for now you can open them in eclipse but you cannot build (execute) ant script from eclipse
The problem is in java component that connect you build.xml ant script with platform dependent android ant script that located in SDK

for example for API level 8 it will be android_rules_r3.xml.

File contains a lot of comments about every section
but I'll explain some of them just for those who  who know nothing about ant engine :)

Ant stuff
I will explain only things that I need to build android project manually

every project contains
<project name="myapps" default="<default target>" basedir=<path to your android project> 
...
project>
nice to see basedir here because you are able to move you Ant script

main concept of ant is targets (like "release", "debug", "release-signed", ets.)
every target could have dependency on other targets
and targets could be public and private (hidden)

for example simple target:
<target name="help">
<echo>This project has extended helpecho>
target> 

complex target
<target name="release" depends="resources, java_compiler, zip, sign, renameing">

target> 

you can specify properties ( they are playing the same function as variables in other languages )
<property name="app.file.name" value="${build.prop.name}" />
let me explain this
you can read/ write app.file.name using ${app.file.name} sintax
in sample you define property and set value for it equal to value of  build.prop.name property

you could override this prop value in build.properties file
lets call it first level of customization

you also  able to define properties in build.properties and then load to project
<property file="build.properties"/>

Combination of both <property name.../> and <property file=.../> creates a list of properties that could be redefined in a separate settings file 
Example:

<property name="one" value="ha-ha"/>
<property file="build.properties"/>

now we can move to targets and other xml elements

<taskdef name="setup" classname="com.android.ant.SetupTask"
classpathref="android.antlibs"/>


Defines a java class with a starting "main" point in com.android.ant.SetupTask.
reference android.antlibs - a link to path(s) where SetupTask could be found.
All android elements (tags) could use (execute) this application
using <setup>setup> tag 

few more samples
<taskdef name="apkbuilder"
classname="com.android.ant.ApkBuilderTask"
classpathref="android.antlibs" />


<taskdef name="xpath"
classname="com.android.ant.XPathTask"
classpathref="android.antlibs" />
usage:

<xpath input="AndroidManifest.xml" expression="/manifest/@package"
output="manifest.package" />


<aaptexec executable="${aapt}"
    command="package"
    verbose="${verbose}"
    manifest="AndroidManifest.xml"
    androidjar="${android.jar}"
    rfolder="${gen.absolute.dir}">

aaptexec>   
if you command sequence that you have to use in different targets you could write a macro
definition:

<macrodef name="dex-helper">
   <element name="external-libs" optional="yes" />
   <element name="extra-parameters" optional="yes" />
   <sequential> 

      <echo>Converting compiled files and external libraries into ${intermediate.dex.file}...echo>
   sequential>
 macrodef>
usage: 
<dex-helper /> 
or 
<dex-helper>
   <extra-parameters>
     <arg value="--no-locals" />
   extra-parameters>
   <external-libs>
     <fileset file="${emma.dir}/emma_device.jar" />
   external-libs>
 dex-helper/>


I hope you've got the idea.

Now about problem I met

for android platform 2.2 (API level 8) 
if you open build script that contains external targets (targets that were defined in android_rules_r3.xml or other external files)
in eclipse. you've get ant compilation errors (unknown target)

if you run the same script (build.xml) from command promt - it works fine

for example in case with auto-generated build.xml

this one return error unknown help target if you open it in eclipse
after that you are not able to compile you app!!! 
As a not very good solution is moving  build.xml file outside project root dir in this case eclipce will not see it and you can add to get it working from command line

Tuesday, November 30, 2010

Java final String optimisation

Some times I need a sub string of a string and I noticed that if you add final keyword, Java compiler makes a small optimization, isn't it?

For example :

String name = "this is a simple string";
String simple = name.substring(0,4);

Here Java creates two strings
but if you write this code in different way you get rid of one extra allocation

final String name = "this is a simple string";
final String simple = name.substring(0,4);

Both objects points to the same memory block and String object itself has a constant context
Am I right?

I am not sure about this conclusions, so, I will check it again when I have time.

If you know something how to use final for Strings and what exactly java compiler does, 

I'll be pleased if someone share his knowledges in this area

Friday, March 19, 2010

Android Streaming Audio

Android audio framework

I will try to explain as detailed as possible about streaming audio in android. For this purposes in SDK 1.5 has been added AudioRecord and AudioTrack classes. AudioRecord is responsible to get samples from microphone and AudioTrack is responsible for playback samples.

This classes works only with PCM encoded data (it means that they are not encoded at all :)

Examples:
Play one buffer loop

Initialzation

AudioRecord record = null;
AudioTrack track = null;
 
record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,
  AudioFormat.CHANNEL_CONFIGURATION_MONO,
  AudioFormat.ENCODING_PCM_16BIT, 
    AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * 4
  );

log.d("AudioTrack min buffer size: "
+ AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT));

track = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, AUDIO_SYSTEM_BUFFER_SIZE, AudioTrack.MODE_STREAM);
 
Initialization is quite simple. All you have to do is to create AudioRecord and AudioTrack

Start audio player
track.play();


Start audio recorder

record.startRecording(); 

Main Loop 
while (needMoreAudioData)
{
     recorder.read(buffer, bufferSize);
     player.write(buffer, bufferSize);
} 

Stop audio player/recorder
track.stop();
record.stop(); 

Remove player
Because this objects works with system resources developer has to release them when they are not in use. Java garbage collector will not release them automatically because instances hold system handlers.
 
track.release();
record.release();


Hope you have got the idea ...

Now few practical tips

When you call  record.startRecording();  recording is already started! and to reduce latency you have to read that data immediately.

You should realize that android is not a real-time operating system and often call backs come not exactly at certain. You will end-up with increased latency over time unless you apply a sort of throttling algorithm to adjust playback side.