(again…) Why the Android Market is not the right place for developers?

I’ve been working in Android platform for more than two years now. For two years I read many articles around the web which say the same: the android market is not developer friendly.

After two years of patience i finally decided to state about that and my final thought has no doubt: the Android Market is bad.

There are the reasons why i finally concluded that:

1- Google does not want to support paid apps as much as free apps. From the beginning, how Google builds their “user flow”, it’s not helping paid apps. Because Google wants to build a Google checkout users base, we may see some hope with the new Google wallet program.

If it was only that…

2- The refund politics is unfair. To illegally copy the app and then ask for refund is so easy on Android I truly believe that 1/3 of the refund rate is due to piracy. The licensing API is not good. From my pov, the licensing code should not be hold by the developer but Google itself! You may want to know that there is 30% banking transactions failure (from my own numbers), ~2/3 of them is due to a customer request, 1/3 is technical issues.

If it was only that…

3- No approval process is NOT the way to go. Freedom is good but anarchy is a mess. How many crap apps are flooding the market every day? the market is messy, it’s impossible for the users to find out relevant applications. Check on the new app category… it’s just disgusting. Approval process has more benefits than disadvantages, it prevents malware/malfunction apps for users, it gives feedback to the developers, it keeps the market clean and reliable. Actually I believe Google does not want to provide approval process only because it will cost them too much. And because again they want to promote free apps, they believe in “user-base” rating/censorship, just like the web… NO the Market SHOULD NOT be like the web. The Market is a reliable place for developers and users to sell and buy, publish and enjoy, support and be supported… Unfortunately the market is far from that today.

If it was only that…

4- The developer console is really BAD. Managing applications is painful and dangerous (because of the bad design of the dashboard). There is no way to get in touch with users directly, there is no promotion code system, no offers system (discount, package…) there is no way for users to report issues to developers. The download report is not reliable and numbers are difficult to analyze. The report system is often down, statistics are not reliable (active installs are usually wrong, no statistics for users updates), the Google checkout dashboard is a mess, can’t do anything with that numbers, except maybe the payouts… I’m still amazed by the fact that we cannot create users account for the developer console with different rights!! It’s like Google thinks all the apps on the market are one man-job… no there are companies with Team! We need accounting rights, developer right, publisher right… Should i give full access to my account to all the developers in my team?! No i should be able to define role and applications which are linked to each account.. many many improvements need to be done here…this is crazy…

If it was only that…

5- Google does not recognize the efforts of all the developers who work hard to build nice and useful apps (even if the platform is so fragmented) because if they do they would ANSWER to their support email! This is the last but not least… the support service from Google is awful, we never or rarely got answer from anybody, it seems there is only machines in Google or what?

This is non respect for all of us who support the platform from the beginning even if it still hard to gain money, this is non respect for all of us who work hard everyday to build apps even if the platform is so fragmented, this is non respect for all of us who believe in Google.

Ok let’s talk about the future now what can we do as an optimistic developer? 🙂

– Publish the Android app in others stores like Amazon app store. I will give you soon my feedbacks, i just started today.

– Learn and publish apps on others platform such as Windows, iOs..

There is no hate but only love in this post! 🙂

Advertisements

main(){ for(;;){ printf (“RIP Dennis Ritchie!\n RIP S.Jobs!\n”); }}

I did not want to write about the death of Jobs because so many people did and better than me but now that Dennis Ritchie passed away too, and I found few articles on it… so RIP Ritchie, and so RIP Jobs too.

They are the Great minds.

RIP Ritchie

 

RIP Jobs

Motorola Dev team letter to developers

I got this email yesterday night, few hours after the announcement of Google new acquisition:

Dear MOTODEV member,

Today, Google and Motorola Mobility have announced their intention to enter an agreement under which Google will acquire Motorola Mobility. This is a positive step in Motorola Mobility’s evolution and exciting news for the Android ecosystem.

As you know, Motorola Mobility has played a leading role in the advancement of the Android platform globally. With Google, we plan to continue to build upon our 80-year history of technology innovation and take Motorola Mobility’s cutting-edge products and solutions to the next level.

We do not expect this announced transaction to have any immediate impact on MOTODEV programs or activities. As the transaction moves forward we will keep you informed as details become available.

As always, technology innovation remains the lifeblood of Motorola Mobility and the success of our developer community remains top priority for MOTODEV.

Sincerely,
The MOTODEV team

I sincerely hope, unlike the MOTODEV Team, that new acquisition will help them to improve the OS integration on their devices… no more MotionBlur, no more private API, more stability in Media components… and so on… (i.e The Xoom is really a BAD device, I would ever recommend this purchase to anybody, it’s slow and unstable…)

So yes please immediate impact asap… :p

Motorola and Google

Motorola has new color

 

Strategy lesson by Google… this is Art!!

I just read this morning Google just announced they will acquire Motorola mobility for around 12$ billions!

Thank you Google!! 🙂 As an Android professional I have to say this is a great news for me and all Android users and professionals. Those acquirement is a strong signal to the market that Google will support its Os. Those last months, with all the fragmentation and patents issues I started to worry about my future in Android Os eco-system 🙂 From this morning my faith and hope are rising back!! (What about my wage? :p)

Google now is facing a historical challenge! Deal as the partner and also a competitor against the other manufacturers such as HTC and Samsung. The balance is fragile. We all now have our fingers crossed: Google don’t be evil!

Google Motorola

Motorola Mobile is now Google

Back to the beginning I cannot help my self to think the Motorola move was predicted, and apart of the strategy from the beginning…

act 1: Google announced Android and positioned itself as an innovative company which helps the mobile market!

act 2: Android is free and spreads over the market thanks to the trust of the manufacturers!

act 3: Google refused to join Apple, Microsoft and RIM […] to acquire Nortel patents…(everybody says why? 🙂 )

act 4: Android is now under many lawsuits, Apple Microsoft and the others take advantages of the situation.

act 5: Google is now the Victim! The manufacturers, developers ask for help and support of the Os!

act 6: Google is the Hero! They can now safely acquire Motorola-Mobility which is a double benefit: 1/acquire the useful patents to ensure the future of Android OS. 2/ directly have control on the market as a manufacturer, Samsung and HTC have few to say, they have what they ask for: support! :))

The manufacturers could still move back, and stop using android, but as Samsung with all the millions Android phones sales, I feel it’s a risky and unproductive move for them in middle term. The stock markets seems not have the same idea than me, Google shares drop since this morning after the announcement, I plan to buy some right now :p

Cheers!

OOM Android

OOM == OutOfMemory is one of the most annoying and frustrated issue  you can experience on the Android platform.

To avoid the issue you have to be very careful on your code, especially when you share references between different objects or activities. There is no unique solution for OOM, because the memory usage really depends on your code and how you code, what your app is doing and so on.

The first thing to do is to install a memory tracker, track allocations,  dump the heap stack and have “fun” :p

Well nevertheless there is one thing that I can do to help you, is provide you a tool method you can call on OnDestroy() event, when you are about leaving your activity.

The method is not speed optimized (mostly because of the use of the instanceof keyword and the recursive call) but does well its job: release all bitmaps of the activity! The only thing you have to do is to pass the parent view as the parameter, then it will release all the bitmaps of the parent and children views.

-recycle bmp buffer for the background’s view and/or the bitmap of the ImageView.

-set reference to null for the garbage collector

-set the drawing callback function to null

public void releaseView(View parent)
	   {
		   if(parent instanceof ViewGroup)
		   {
			   int c  = ((ViewGroup) parent).getChildCount();
			   for (int i=0;i<c;i++)
			   {
				   releaseView(((ViewGroup) parent).getChildAt(i));
			   }
			   Drawable d = parent.getBackground();
			   if(d != null)
			   {
				   if(d instanceof BitmapDrawable)
					   ((BitmapDrawable) d).getBitmap().recycle();
				   d.setCallback(null);
			   }
			   parent.setBackgroundDrawable(null);
		   }
		   else
		   {

			   if(parent instanceof ImageView)
			   {
				   Drawable d =((ImageView) parent).getDrawable();
				   if(d != null)
				   {
					   d.setCallback(null);
					   if(d instanceof BitmapDrawable)
						   if(((BitmapDrawable) d).getBitmap() != null)
							   ((BitmapDrawable) d).getBitmap().recycle();
				   }

				   d=((ImageView) parent).getBackground();
				   if(d != null)
				   {
					   	if(d instanceof BitmapDrawable)
					   		if(((BitmapDrawable) d).getBitmap() != null)
					   			((BitmapDrawable) d).getBitmap().recycle();
					   	d.setCallback(null);
				   }
				   ((ImageView) parent).setImageBitmap(null);
			   }
			   else
			   {
			       Drawable d = parent.getBackground();
				   if(d instanceof BitmapDrawable)
					   ((BitmapDrawable) d).getBitmap().recycle();
				   if(d != null)
					   d.setCallback(null);
				   parent.setBackgroundDrawable(null);
			   }
		   }
	   }

Feel free to suggest me some changes, I’m always looking forward to improve it (ImageButton for instance).

Google+, circles need Hierarchy concept

++

I do enjoy using Google+ those few days. And from my pov Circles is very simple and nice concept but it missed something really relevant, HIEARCHY!

For example i want to create two circles like “friends” and “close friends”. The idea is simple my close friends are also my friends! So when i want to publish something to my friends circle i wish my close friends should be also noticed! On the other hand when i publish to my close friends i dont want all my friends know about it.

So the idea is simple, Allow me to add circle to circle!!

Support multiple sdk-version in one release (Android or others Java based platform)

Hi,

I just think it’s could be useful to share the new java notion I just learned to fix the study case below:

how to handle multiple sdk version in one release on Android?

I’m building a camera app right now for my company, then I want to handle front and back camera, and others camera capacities which could not be available on the current SDK.

So how could I make my right import without crashing the VM?

Very simple answer here:

Static classes are not loaded by the VM until one his method is called.

So what you need to do is implement a singleton pattern, through an abstract class, which will choose the static class to call.  So graceful right?

You can find an implementation example here: http://devtcg.blogspot.com/2009/12/gracefully-supporting-multiple-android.html

Find real and full explanation on wiki here: http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom

 

News? What for?

Hi There!

It’s been long time now I did not write something here. Mmm… Yeah I’ve to admit I had lots of things better to do ! 😉

I changed the website theme to something more “twitter” because I’m not going to publish any “real technical articles” for the few next months. Then I think it should better for your reading to have several posts directly on the homepage.

There are some big news which are coming, no it’s not “my last creation” neither “the product of my life” 😉 but it may drastically change the way life goes for me… let’s keep our patient for the biggest one to this week-end.

Well the second one is concerning my Android development experiments. Let me remind you about Bunjix a kind of “start- start-up” which have be launched few months ago by previous co-workers and friend Benjamin. Bunjix is a tiny French firm specialized in Mobile development. Bunjix started few months ago with its first contract, the project consists on a crosswords game. It was a successful project. From this point his tried so many times to involve me to his project…Mmm… Finally I hooked on! 🙂

Then It will be a pleasure for me to be invited to work with him. We cannot give any names, marks, products because nothing finalized yet, but there are some surprises to come…

So here we are… c u soon! 🙂

Plotting Android screen :)

As promised here is my former application fireworks which I migrated to Android OS.

I changed a little bit the application in order to handle touch event, so it’s not a fireworks anymore, it’s a kind of  wasted-time ZEN application 🙂

The app is very simple, when you touched the screen it draws you a square in magenta and the screen is continuously blurred… the result aim to be a ZEN application ! 😉

Of course, it’s more for education purpose…

Here is a screen of our final application:

Check it !

Check it !

So we have  these 4 steps below in order to get the same result:

  1. Create an Android project and an activity
  2. Implement onDraw function to compute and draw result / do some optimization in order to have a decent frame rate
  3. Handle finger touch

Please note that I assume you already have the SDK installed (1.1 or higher)  and you know how to create a new project.

1 – Create a project and a activity

We created an activity and an anonymous class derived from View (Graphique which means graphic in french :p ) class. We have to do so because we want to override the onDraw function of the view then we can draw on the current View.

The anonymous class is an ugly solution. Because the application structure is very simple we can avoid this rule 😉 But yes try to never use anonymous class as all good books told you!

We also defined a Bitmap which represents the back screen. We will firstly draw on the back screen before copy it to main screen (real phone screen). It’s a kind of double buffer. Also don’t forget to define a Paint which tell to Android how you want to draw the pixels.

<pre>public class Fireworks extends Activity{
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(new Graphique(this));        
 }
 private static class Graphique extends View {
 private Paint mPaints, mFramePaint ;

 public Graphique(Context context) {
 super(context);
 mFramePaint = new Paint();
 mFramePaint.setAntiAlias(true);
 mFramePaint.setStyle(Paint.Style.STROKE);
 mFramePaint.setStrokeWidth(0);
 mPaints = new Paint();
 mPaints.setAntiAlias(true);
 mPaints.setStyle(Paint.Style.FILL);
 mPaints.setColor(Color.BLUE);

 this.bufferscreen = Bitmap.createBitmap(
 315,425,Bitmap.Config.ARGB_8888);
  }
 @Override
 protected void onDraw(Canvas canvas) {
 canvas.drawBitmap(this.bufferscreen, 0.0f,0.0f,mFramePaint);
 invalidate();
 }
 }
}

2 – Implement onDraw function to compute and draw result

Here is the core of our application. Please refer to my original post to know how the algorithm is working.

You have to focus here on the mini_buffer and optimization code. Because it’s very slow to compute the screen entirely, I created a mini screen with fewer pixels where we draw and compute them. When all computing are finished I project the mini screen to the buffer screen with the real size. And after that I copy the buffer screen to the real phone’s screen. It’s seems very complex but in fact it’s very simple, please stay with me 🙂

For instance my real screen sizes are 100/100 and my mini screen are 10/10 (width/height). So we did all maths in the 10/10 screen then project it to the 100/100. Which mean:

– I have originally 100*100 pixels to compute, finally I only compute 10*10 (one line in the real screen !)

-1 pixel in my mini screen represents a square of 10/10 pixels in my real screen.

-my real screen will pixelize ! Yes it’s the fact, but the gain I earned by computing one single line instead of 100 lines is much relevant! Any way you can change the projection in order to match exactly what you need.

Finally what is this ?


r = (
 (
 ((p1 >> 16) & 0xff)+
 ((p2 >> 16) & 0xff)+
 ((p3 >> 16) & 0xff)+
 ((p4 >> 16) & 0xff)
 )>>2
 )<<16;

&#91;/sourcecode&#93;

Because of the algorithm (<a href="https://tuanbach.wordpress.com/2009/01/26/the-java-plan-for-you-valentines-day-second-part/">please refer to my previous post</a>) I have to extract each component (RGB) and compute separately these with pixel's components around. Then the pixel's components are stored as below:

Pixel = Red (8 bytes) | Green (8bytes) | Blue (8bytes)

So to get the component I wanted I have to shift to the right and do an AND to 0xff. The steps below will explain you why:

Pixel &gt;&gt; 16 &lt;==&gt; Pixel = 8 Unknown bytes | 8 Unknown bytes | Red (8 bytes)

0xff &lt;==&gt; 00000000 | 00000000 | 11111111

[ 8 Unknown bytes | 8 Unknown bytes | Red (8 bytes) ] AND 00000000 | 00000000 | 11111111 &lt;==&gt; 00000000 | 00000000 | Red (8 bytes)

Now I have the red component of my pixel, I can do it with all components. note that for the Blue component you don't have to shift any bytes, because it 's already at the beginning.

Then I add all red's components, divide them by 4  by shifting to the right by 2. Yes it works, when you shift n to the right you divide your number by 2*n. The proof can be found on Google, or you can practice some exercises by trying to get the proof yourself. It's due to the binary, with the same reason when you shift by 1 in the decimal system (human system) to the right you divide by 10 (e.g 100&gt;&gt;1 &lt;==&gt; 10)

And I shift back the component to the right position (16 for red, 8 for green, 0 for blue).

When I finished to compute I regroup all my components by doing a simple OR:

respix = 0xff000000 | r | g | b;
<blockquote>Note that I added the alpha component on the left of my variable because Android system stored the pixel as ARGB.</blockquote>
Finally I do the projection by writing my pixel square in the buffer screen. In my code I divided the real screen by 5, so I have to draw a square of 5/5 in my buffer for each pixel from my mini buffer.



int index,r,g,b,index2;
 int[] buffer = this.mini_buffer;
 int p1,p2,p3,p4;
 int respix;
 for(int y = 85 -2;y>0; y--)
 {
 for(int x = 63-2;x>0; x--)
 {
 index = y*63+ x;
 p1 = buffer[index+63];
 p2 = buffer[index-63];
 p3 = buffer[index+1];
 p4 = buffer[index-1];
 r = (
 (
 ((p1 >> 16) & 0xff)+
 ((p2 >> 16) & 0xff)+
 ((p3 >> 16) & 0xff)+
 ((p4 >> 16) & 0xff)
 )>>2
 )<<16;
 g = (
 (
 ((p1 >> 8) & 0xff)+
 ((p2 >> 8) & 0xff)+
 ((p3 >> 8) & 0xff)+
 ((p4 >> 8) & 0xff)
 )>>2
 )<<8;
 b = (
 (
 ((p1) & 0xff)+
 ((p2) & 0xff)+
 ((p3) & 0xff)+
 ((p4) & 0xff)
 )>>2
 );
 //compute pixel color
 respix = 0xff000000 | r | g | b;
 index2 = (y*5)*315+ (x*5);
 //write color pixels to front screen
 this.buffer_class[index2]= respix;
 this.buffer_class[index2+1]= respix;
 this.buffer_class[index2+2]= respix;
 this.buffer_class[index2+3]= respix;
 this.buffer_class[index2+4]= respix;

 this.buffer_class[index2+315]= respix;
 this.buffer_class[index2+315+1]= respix;
 this.buffer_class[index2+315+2]= respix;
 this.buffer_class[index2+315+3]= respix;
 this.buffer_class[index2+315+4]= respix;

 this.buffer_class[index2+630]= respix;
 this.buffer_class[index2+630+1]= respix;
 this.buffer_class[index2+630+2]= respix;
 this.buffer_class[index2+630+3]= respix;
 this.buffer_class[index2+630+4]= respix;

 this.buffer_class[index2+945]= respix;
 this.buffer_class[index2+945+1]= respix;
 this.buffer_class[index2+945+2]= respix;
 this.buffer_class[index2+945+3]= respix;
 this.buffer_class[index2+945+4]= respix;

 this.buffer_class[index2+1260]= respix;
 this.buffer_class[index2+1260+1]= respix;
 this.buffer_class[index2+1260+2]= respix;
 this.buffer_class[index2+1260+3]= respix;
 this.buffer_class[index2+1260+4]= respix;

 //write color pixels to back screen
 buffer[index] = respix;
 }                
 }      
 //            

 this.bufferscreen.setPixels(this.buffer_class,0,315,0,0,315,425);

 canvas.drawBitmap(this.bufferscreen, 0.0f,0.0f,mFramePaint);
 invalidate();
 }
 }

3-Handle finger touch

Final point I implement the right interface in order to handle the touch events and trackball events. Because it’s very simple, it avoids explanation…

You have to focus here on the Finger class, which represents the finger square to draw when user touches the screen. Note that I have to blit pixel in the mini buffer!

<pre>public class Fireworks extends Activity{

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(new Graphique(this));        
 }
 private static class Graphique extends View {
 private Paint mPaints, mFramePaint;
 private RectF mRect;
 protected Bitmap bufferscreen;
 int buffer_class[],mini_buffer[];
 Finger finger;
 public Graphique(Context context) {
 super(context);
 finger = new Finger();
 mFramePaint = new Paint();
 mFramePaint.setAntiAlias(true);
 mFramePaint.setStyle(Paint.Style.STROKE);
 mFramePaint.setStrokeWidth(0);
 mPaints = new Paint();
 mPaints.setAntiAlias(true);
 mPaints.setStyle(Paint.Style.FILL);
 mPaints.setColor(Color.BLUE);
 mRect = new RectF(5, 5, 315, 425);
 this.bufferscreen = Bitmap.createBitmap(
 315,425,Bitmap.Config.ARGB_8888);
 this.buffer_class = new int[315*425];
 this.mini_buffer = new int[63*85];
 }
 public boolean onTouchEvent(MotionEvent ev){
 if(ev.getAction() == MotionEvent.ACTION_UP)
 this.finger.bprint = false;
 else
 this.finger.bprint = true;
 this.finger.parametre_x((ev.getX()*63)/315);
 this.finger.parametre_y((ev.getY()*105)/425);
 return true;
 }
 public boolean  onTrackballEvent  (MotionEvent event){
 this.finger.parametre_x(((this.finger.donne_x()+(Math.random()*100))*63)/315);
 this.finger.parametre_y(((this.finger.donne_y()+(Math.random()*100))*105)/425);
 return true;
 }
 @Override
 protected void onDraw(Canvas canvas) {
 int index,r,g,b,index2;
 int[] buffer = this.mini_buffer;
 int p1,p2,p3,p4;
 int respix;
 finger.dessine(this.mini_buffer,63,85);
 for(int y = 85 -2;y>0; y--)
 {
 for(int x = 63-2;x>0; x--)
 {
 index = y*63+ x;
 p1 = buffer[index+63];
 p2 = buffer[index-63];
 p3 = buffer[index+1];
 p4 = buffer[index-1];
 r = (
 (
 ((p1 >> 16) & 0xff)+
 ((p2 >> 16) & 0xff)+
 ((p3 >> 16) & 0xff)+
 ((p4 >> 16) & 0xff)
 )>>2
 )<<16;
 g = (
 (
 ((p1 >> 8) & 0xff)+
 ((p2 >> 8) & 0xff)+
 ((p3 >> 8) & 0xff)+
 ((p4 >> 8) & 0xff)
 )>>2
 )<<8;
 b = (
 (
 ((p1) & 0xff)+
 ((p2) & 0xff)+
 ((p3) & 0xff)+
 ((p4) & 0xff)
 )>>2
 );
 //compute pixel color
 respix = 0xff000000 | r | g | b;
 index2 = (y*5)*315+ (x*5);
 //write color pixels to front screen
 this.buffer_class[index2]= respix;
 this.buffer_class[index2+1]= respix;
 this.buffer_class[index2+2]= respix;
 this.buffer_class[index2+3]= respix;
 this.buffer_class[index2+4]= respix;

 this.buffer_class[index2+315]= respix;
 this.buffer_class[index2+315+1]= respix;
 this.buffer_class[index2+315+2]= respix;
 this.buffer_class[index2+315+3]= respix;
 this.buffer_class[index2+315+4]= respix;

 this.buffer_class[index2+630]= respix;
 this.buffer_class[index2+630+1]= respix;
 this.buffer_class[index2+630+2]= respix;
 this.buffer_class[index2+630+3]= respix;
 this.buffer_class[index2+630+4]= respix;

 this.buffer_class[index2+945]= respix;
 this.buffer_class[index2+945+1]= respix;
 this.buffer_class[index2+945+2]= respix;
 this.buffer_class[index2+945+3]= respix;
 this.buffer_class[index2+945+4]= respix;

 this.buffer_class[index2+1260]= respix;
 this.buffer_class[index2+1260+1]= respix;
 this.buffer_class[index2+1260+2]= respix;
 this.buffer_class[index2+1260+3]= respix;
 this.buffer_class[index2+1260+4]= respix;
 //write color pixels to back screen
 buffer[index] = respix;
 }                
 }      
 this.bufferscreen.setPixels(this.buffer_class,0,315,0,0,315,425);
 canvas.drawBitmap(this.bufferscreen, 0.0f,0.0f,mFramePaint);
 invalidate();
 }
 }
}
<pre>

Here is the finger code

public class Finger extends    Point {

public boolean bprint=true;

Finger(){
super();
this.pw = 10;
this.ph = 10;
this.couleur = Color.MAGENTA;

}

protected void dessine(int buffer [], int w, int h) {
if(!this.bprint)
return;
if(this.donne_x() > 0 && this.donne_x()+pw < w && this.donne_y()> 0 && this.donne_y()+ph < h){ for(int x = 0;x [/caption]

Android development

For few months now, I’m doing some stuff on Android. Ok it looks a little strange that I started to build things for Android but I have an Iphone…

But as you already know I can only develop application for the Iphone on Mac OS, but I don’t have a Mac (I know it’s a shame).

So what did I do?

  • Learn Android system
  • Test some ideas regarding performance
  • Learn Opengl ES
  • Hate the Garbage collector
  • Hate the NDK

I want to give you some feedbacks on all my tests, a kind of overview. Then I will write a post for each of my test separately.

First of all, yes Android is very easy to get start with. I like the Activity and View structure, I can’t give more details because I did not develop things really cool yet with UI, Map, contacts… Let’s see another time.

Regarding the performance, I have to admit that performance is very poor !! Especially on the emulator (the HTC magic is much faster than the emulator). For instance, I migrated my fireworks app to Android, and I have to reduce by 4 the size of the screen in order to get a correct frames rate. You can guess how bad is the visual rendering (you know like 320×240 dos game  😉 ).  But I did not use OpenGL ES, it was a pure CPU computing.

But even when I tried to develop things with OpenGL ES, there is a very strange issue, I divided by 2 my frame rates when I blit a background! Actually the frame rate depend on how big is the surface to draw, for example you can draw 100 small bitmaps without performance issue if the total surface is not big… take a look on my figure to understand what I mean. So I guess it’s not the implemetnation of OpenGL ES which was bad but the device! But which device is it? It may be the screen/graphic component.

Blit OpenGL ES Android

Blit OpenGL ES Android

Finally I wasted the rest of my time to try to build a physic’s game for Android. Then I tried Box2D engine. I got 5/10 FPS with a world containing 5 bodies ! 🙂 So where did it come from?

Android is very bad in:

  • float computing
  • Memory managing

Ok we can understand the slow concerning the float computing. But regarding the garbage collector Google guys have to do something! And the main problem is that you can not have any influence on how the garbage works !! It tries to be smart and free everything for you but my god the GC is not smart at all !! The best defense on this issue is to code everything by yourself and be very careful on how you manage your memory. But as you know and Google guys also, we are now sharing codes, projects, then We can not review all codes!! For example I tried to review  the Box2D codes to reduce the lack of memory, then it worked but It took me a week, moreover it’s not perfect and very hard to debug! It could be great if we can manage variables status (like Java standard) and set up the policy depending to our needs… (like Java standard)

By the way on this point the only good news is the DMMs tool, which help you to track and debug. It’s very useful, but again it’s not working perfectly, sometimes the tool did  not identify correctly my activity.

Last thing was the NDK. Firstly the NDK is very hard to install. There is no good documentation (full documentation), for my part i don’t like this help page of Google. Yes developing with the NDK is much faster than Java, regarding some works done on Box2D (no comparison possible with Java Box2D!!). But you have to remain that will not be compatible with all devices (native code).  Then you have to compile for each different CPU a different application, how can you deal with it in the market place?..Mmm moreover the promise of Google’s Android was not “a full compatibility on all devices” ? For my part it’s one of the argument that convinced me to develop for Android… now that if I have to develop an application for each device… what a difference for me comparing to the past?

I think Google realeased the NDK because there are not so much games on the market and the main reason for that is the fact that Android is to slow!

So to summarize, Google guys, you have to speed Android up for the next version please because NDK is not a good solution at all !!!

(to be continued with how to plot pixel in Android… )