Archive for the ‘General’ Category
[DevoxxFR2012] Android Development Essentials: A Comprehensive Introduction to Core Concepts and Best Practices
Lecturer
Mathias Seguy founded Android2EE, specializing in Android training, expertise, and consulting. Holding a PhD in Fundamental Mathematics and an engineering degree from ENSEEIHT, he transitioned from critical J2EE projects—serving as technical expert, manager, project leader, and technical director—to focus on Android. Mathias authored multiple books on Android development, available via Android2ee.com, and contributes articles to Developpez.com.
Abstract
This article examines Mathias Seguy’s introductory session on Android development, designed to equip Java programmers with foundational knowledge for building mobile applications. It explores the Android ecosystem’s global context, core components like activities, intents, and services, and practical implementation strategies. Situated within the rapid evolution of mobile IT, the analysis reviews methodologies for UI construction, resource management, asynchronous processing, and data handling. Through code examples and architectural patterns, it assesses implications for application lifecycle management, performance optimization, and testing, providing a roadmap for novices to navigate Android’s intricacies effectively.
Positioning Android Within the Global IT Landscape
Android’s prominence in mobile computing stems from its open-source roots and widespread adoption. Mathias begins by contextualizing Android in the IT world, noting its Linux-based kernel enhanced with Java libraries for application development. This hybrid architecture leverages Java’s familiarity while optimizing for mobile constraints like battery life and varying screen sizes.
The ecosystem encompasses devices from smartphones to tablets, supported by Google’s Play Store for distribution. Key players include manufacturers (e.g., Samsung, Huawei) customizing the OS, and developers contributing via the Android Open Source Project (AOSP). Mathias highlights market dominance: by 2012, Android held significant share, driven by affordability and customization.
Development tools integrate with Eclipse (then primary IDE), using SDK for emulation and debugging. Best practices emphasize modular design to accommodate fragmentation—diverse API levels and hardware. This overview underscores Android’s accessibility for Java developers, bridging desktop/server paradigms to mobile’s event-driven model.
Core Components and Application Structure
Central to Android apps are activities—single screens with user interfaces. Mathias demonstrates starting with a minimal project: manifest.xml declares entry points, main_activity.java handles logic, and layout.xml defines UI via XML or code.
Code for a basic activity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Intents facilitate inter-component communication, enabling actions like starting activities or services. Explicit intents target specific classes; implicit rely on system resolution.
Services run background tasks, unbound for independence or bound for client interaction. Content Providers expose data across apps, using URIs for CRUD operations. Broadcast Receivers respond to system events.
Mathias stresses lifecycle awareness: methods like onCreate(), onPause(), onDestroy() manage state transitions, preventing leaks.
Handling Asynchronous Operations and Resources
Mobile apps demand responsive UIs; Mathias introduces Handlers and AsyncTasks for off-main-thread work. Handlers post Runnables to UI thread:
Handler handler = new Handler();
handler.post(new Runnable() {
public void run() {
// UI update
}
});
AsyncTask abstracts background execution with doInBackground(), onPostExecute():
private class DownloadTask extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... urls) {
// Download
return result;
}
protected void onPostExecute(String result) {
// Update UI
}
}
Resources—strings, images, layouts—are externalized in res/ folder, supporting localization and densities. Access via R class: getString(R.string.app_name).
Data persistence uses SharedPreferences for simple key-values, SQLite for databases via SQLiteOpenHelper.
Advanced Patterns and Testing Considerations
Patterns address lifecycle challenges: Bind threads to activity states using booleans for running/pausing. onRetainNonConfigurationInstance() passes objects across recreations (pre-Fragments).
For REST services, use HttpClient or Volley; sensors via SensorManager.
Testing employs JUnit for units, AndroidJUnitRunner for instrumentation. Maven/Hudson automate builds, ensuring CI.
Implications: These elements foster robust, efficient apps. Lifecycle mastery prevents crashes; async patterns maintain fluidity. In fragmented ecosystems, adaptive resources ensure compatibility, while testing mitigates regressions.
Mathias’s approach demystifies Android, empowering Java devs to innovate in mobile spaces.
Links:
(long tweet) Increase choice with mvn archetype:generate
By default, mvn archetype:generate offers ~50 template projects. How to offer more templates?
Actually, Maven bases itself on a archetype-catalog.xml file, in Maven’s local repository. Updating this file is possible, by mvn archetype:crawl (and/or archetype:update-local-catalog ?).
Anyway, Maven can base on a remote repository, using archetypeCatalog, such as:
[java]mvn archetype:generate -DarchetypeCatalog=http://download.java.net/maven/2[/java]
You can hint at the remote repository available in settings.xml file, for instance.
(long tweet) JOnAS / GenIC / Method … of interface … should NOT throw RemoteException
Case
On generating Locals and Remotes of EJBs (let’s say JonathanBean) to be deployed on JOnAS, the GenIC raises:
[java]GenIC.fatalError : GenIC fatal error: Cannot read the Deployment Descriptors from /foo/goo/jonathan-server.jar: Method foo of interface lalou.jonathan.JonathanLocal should NOT throw RemoteException[/java]
Within the EJB2, the method foo is declared to be Local and to throw RemoteException
Quickfix
The error is explicit.
A Local EJB cannot throw RemoteException.
Especially, the considered method can be declared with the right XDocLet tag, ie:
[java]* @ejb.interface-method view-type="remote"[/java]
but can with neither:
[java]* @ejb.interface-method view-type="both"[/java]
nor:
[java]* @ejb.interface-method view-type="local"[/java]
As a quickfix, I suggest to surround with a try/catch block a throw a RuntimeException if needed.
(long tweet) Tip: How to know the location of a resource?
Case:
You have many files with the same names (log4.xml, applicationContext.xml, etc.), you need know which of them is loaded.
Tip:
On the debugger and/or in the logs, use an instruction similar to:
getClass().getClassLoader().getResource("log4j.xml")
(long tweet) JOnAS / no security manager: RMI class loader disabled
On server side:
an EJB2 packaged in a JAR within an EAR, deployed on JOnAS 5.
On client side:
java.lang.ClassNotFoundException: org.ow2.jonas_gen.com.clam.indice.api.interfaces.JOnASHelloWorldService150707405Home_Stub (no security manager: RMI class loader disabled)]
Explanation:
This means there is some kind of issue with generated Stubs on client side. Should check whether the Stubs depended on are available in classpath.
Problems when invoking main method from GenIC … error in fastrmic
Case
Trying to deploy an EAR on JOnAS, I got the following error:
[java]Problems when invoking main method from GenIC: java.lang.RuntimeException: error in fastrmic (null)[/java]
More detail:
[java]JOnASEJBService.__checkGenIC : Cannot apply GenIC on the file ‘C:\jonathan\jonathan_2012.05.11-13.47.29.ear\jonathan-server.jar’ with the args ‘[-classpath, C:\jonathan\jonathan_2012.05.11-13.47.29.ear\jonathan-server.jar, -protocols, jrmp, -invokecmd]’.
org.ow2.jonas.service.ServiceException : Problems when invoking main method from GenIC: java.lang.RuntimeException: error in fastrmic (null)
at org.ow2.jonas.generators.genic.wrapper.GenicServiceWrapper.callGenic(GenicServiceWrapper.java:79)
at org.ow2.jonas.ejb2.internal.JOnASEJBService.__callGenic(JOnASEJBService.java:2017)[/java]
Quickfix
Edit $JONAS_BASE/conf/jonas.properties.
The properties jonas.services and jonas.service.ejb2.auto-genic must be consistent.
Especially, if GenIC is enabled (jonas.service.ejb2.auto-genic true), then check ejb2 is among the services pointed at by jonas.services, eg:
jonas.services jtm,db,security,resource,ejb2,web,ear.
IntelliJ IDEA / Unsupported classpath format eclipse
Case
The project on which I work is built on Eclipse and Ant. I am trying to migrate it to Maven 3.0. I thought to do this within IntelliJ IDEA.
Once the pom.xml was created, I wanted to revert to a configuration based on Eclipse’s .classpath file.
Then IntelliJ IDEA crashes. On starting up again, I get the following error
[java]Cannot load module file ‘jonathanModule’ Unsupported classpath format eclipse[/java]
Quick Fix
For a reason I ignore, Eclipse integration plugin was disabled. To restore Eclipse compatibility, simply do enable Eclipse integration in the plugin preference menu of IntelliJ IDEA.
Sniffing RMI Traffic… Rather log it!
Suspecting a thread leak, there is some traffic I’d like to track on my JOnAS server: most of all, the calling IPs, with the methods and parameters sent. Actually, I lack some tools, so I tried to snif the network traffic.
Two softwares may make the job:
I discarded these solutions for several reasons. First, there are some issues with Windows Seven compatibility. Moreover, traffic on RMI protocol is SSL-encrypted… therefore not easy to read.
At least, I withdrew from this idea to snif, and I decided to intercept calls thanks to loggers.
In order to enable RMI logs, add the following properties to your JVM (to JAVA_OPTS parameters):
- on client side:
-Dsun.rmi.client.logCalls=true - on server side:
-Djava.rmi.server.logCalls=true
More details and options are available in Oracle’s documentation: RMI Implementation Logging.
By default, the logs look like this:
[java]FINEST: RMI TCP Connection(5)-10.76.35.25: [10.76.35.25: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
2012-05-03 15:35:51,053 : Log$LoggerLog.log : RMI TCP Connection(5)-10.76.35.25: [10.76.35.25: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)][/java]
(Don’t be fool: this is Java logging, but not Log4J!)
By the way, a very interesting result I got is the following: monitoring and profile tools such as JVisualVM or JProfiler “ping” the RMI server, disturbing the measurements. Let’s consider that as “the Heisenberg uncertainty principle” applied to softwares 😉
Configure JProfiler 5 to work with JOnAS 5
JOnAS 4 (and older) and JProfiler 4 (and older) were used to working smoothly. JOnAS 5 makes a large use of OSGi libraries… which may “blind” JProfiler.
Here is a workaround, slightly different from former version, to bypass this issue, in order to make JProfiler 5 work with JOnAS 5:
- let’s assume you have installed JOnAS in a folder, let’s say
JONAS_ROOT - install JProfiler 5 with default options, set the JDK, licence key, etc., let’s say in a folder
C:\win32app\jprofiler5\also known asJPROFILER_HOME. - edit
%JONAS_ROOT%/bin/setEnv.bat:- set:
JAVA_OPTS=-agentlib:jprofilerti=port=8849 "-Xbootclasspath/a:C:\win32app\jprofiler5\bin\agent.jar" %JAVA_OPTS%
- set:
- edit
%JONAS_ROOT%/conf/osgi/default.properties- in the property
bootdelegation-packages, add the JProfiler packages:
- in the property
[java]
bootdelegation-packages com.sun.corba, \
com.sun.corba.*, \
(…)
com.jprofiler, \
com.jprofiler.*, \
com.jprofiler.agent, \
com.jprofiler.agent.*[/java]
- add
JPROFILER_HOME\bin\windowsto your environment variablePATH. - startup JOnAS, you should see the following block in standard output:
[java]JProfiler> Protocol version 25
JProfiler> Using JVMTI
JProfiler> 32-bit library
JProfiler> Listening on port: 8849.
JProfiler> Native library initialized
JProfiler> Waiting for a connection from the JProfiler GUI …
JProfiler> Using dynamic instrumentation
JProfiler> Time measurement: elapsed time
JProfiler> CPU profiling enabled
JProfiler> Hotspot compiler enabled
JProfiler> Starting org/ow2/jonas/commands/admin/ClientAdmin …[/java]
- run JProfiler, follow the wizard, take caution to set JProfiler port at 8849 (or remain consistent with the port set in JOnAS config file)
Starting a new position at Amundi AM
This week I have started a new position as transverse architect at Amundi Asset Management in Paris (France).
I have to manage the project of Stabilization and Reliability of the platform (tens of JOnAS servers, EJB2 to migrate to EJB3, JVM tuning, etc.). I will have to face hard technical challenges.
I wish I’ll spend a nice time with my new team!