Tuesday, September 7, 2010

Starting Android applications from shell

Starting application from the shell can be helpful in many scenarios. On scenario is when you want to limit the resources that the application is going to use with ulimit.
1. Start the shell.

2. Start the ActivityManager(am) command-line tool with appropriate parameters.
The syntax for the am command-line tool is the following.
ssue am command. am command syntax is as follow :
am [start|instrument]
am start [-a <action>] [-d ] [-t <mime_type>]
[-c <category> [-c <category>] ...]
[-e <extra_key> <extra_value> [-e <extra_key> <extra_value> ...]
[-n <component>] [-D] [<uri>]
am instrument [-e <arg_name> <arg_value>] [-p <prof_file>]
[-w] <component>


3. Start the web browser with the following command.

am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity
to start your own application just type:
am start -a android.intent.action.MAIN -n "Your Package"/."Your Activity"
If you hare unsure of what your package and main activity are look in your manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.TordSoft.HelloWorld">
  <application android:icon="@drawable/icon">
   <android:name=".HelloWorld" android:label="@string/app_name">
    <intent-filter>
    <action android:value="android.intent.action.MAIN" />
    <category android:value="android.intent.category.LAUNCHER" /> </intent-filter>
  </activity></application>..</manifest>

Sunday, October 25, 2009

NeoDatis Benchmark on Android

After doing a lot of different testing and trying a lot of different settings I finally decided to do some testing. I had some heap size memory when doing the complete TestIndex test with all of the 10000 records, NeoDatis like to store all of entries in it's internal cache, so I settled with 1000 for now, until I can figure out a way to get around the memory related issues.



Here are the result table:

Perst
SQLite
DB4O
BerkeleyDB
NeoDatis
Insert
1159
6892
4168
4619
25022
Search
599
9481
18261
3405
18325
Iterate
120
290
4392
2889
11126
Delete
1659
6315
7084
5565
10156
It should be noted that the NeoDatis team releases new versions often, so if you have some problem, it might be fixed in a new version.

Wednesday, October 14, 2009

NeoDatis on Android intro

I've been playing around with NeoDatis a little while now so I thought I'd write a little intro post on it before I did the testing.
NeoDatis ODB like a lot of the other database management system (DBMS)'s that I've tested lately can be used as both an an embedded database engine or in client/server mode.
Size
The makers of NeoDatis say that ODB runtime is less than 550k, witch would make it quite suitable for use on android. In the some time soon I'll do some heap usage tests to see how much heap the different DBMS's use while running, just need a tool to do it, worst case I'll write it myself.
Features
It supports ACID transactions to insure data integrity,  it also has a automatic transaction recovery that runs in the startup sequence that will commit the records in case of a "fatal" shutdown due to an unexpected event such as a hardware failure.
Storage
NeoDatis ODB uses a single file to store all it's data:
  • The Meta-model
  • The objects
  • The indexes

NB: How ever you should be aware of a few things before starting using the NeoDatis.
The file that you are going to use for the database, must not be a new empty file. If you give NeoDatis a empty file, it will crash and give you an exception looking something like this:
Version=1.9.17 , Build=632, Date=03-10-2009-05-38-18, Thread=Thread-8
NeoDatisError:276:End Of File reached - position = 0 : Length = 0
StackTrace: org.neodatis.odb.impl.core.layers.layer3.buffer.MultiBufferedIO.manageBufferForNewPosition(MultiBufferedIO.java:151)
org.neodatis.odb.impl.core.layers.layer3.buffer.MultiBufferedIO.setCurrentReadPosition(MultiBufferedIO.java:271)
org.neodatis.odb.core.layers.layer3.engine.FileSystemInterface.setReadPosition(FileSystemInterface.java:202)
org.neodatis.odb.impl.core.layers.layer3.engine.ObjectReader.readEncryptionFlag(ObjectReader.java:180)
org.neodatis.odb.impl.core.layers.layer3.engine.ObjectReader.readDatabaseHeader(ObjectReader.java:244)
org.neodatis.odb.core.layers.layer3.engine.AbstractStorageEngine.init(AbstractStorageEngine.java:206)
org.neodatis.odb.core.layers.layer3.engine.AbstractStorageEngine.(AbstractStorageEngine.java:171)
org.neodatis.odb.impl.core.layers.layer3.engine.LocalStorageEngine.(LocalStorageEngine.java:18)
org.neodatis.odb.impl.DefaultCoreProvider.getClientStorageEngine(DefaultCoreProvider.java:140)
org.neodatis.odb.impl.main.LocalODB.(LocalODB.java:49)
org.neodatis.odb.impl.main.LocalODB.getInstance(LocalODB.java:35)
org.neodatis.odb.ODBFactory.open(ODBFactory.java:72)
I've submitted it as a bug, and got a reply pretty fast so It will probably be fixed or documented soon. 
Thread safety
NeoDatis ODB supports usage in a multi-threaded environment.

Import/Export
ODB lets you export & import all data to XML.

Refactoring
An interesting feature that I haven't seen before. You can add and remove fields without problems, it allso support additional refactoring through through it's Object Explorer(Extra app) where you can rename classes and fields.

Licence
ODB is distributed under the LGPL license.

So this was a quick introduction, at the moment I'm working on a TestIndex for it which should be done soon. If you want to know more about NeoDatis I suggest their homepage which has pretty good documentation.

Sunday, October 11, 2009

JODB (Java Objects Database) for Android (3) with reduced TestIndex benchmark

While creating and running the TestIndex for JODB I've discovered a few things.
  • Search operations are slow, and scale with the amount of records that is present in the database, so if it tok 2 seconds to get 10 distinct records with 100 records it will take 200 seconds with 10000, which are the number of records currently used in the TestIndex test. So large record-sets are not a good idea.
  • It seems to use a very little amount of memory, but when searching goes as it goes, that doesn't really help that much when things take as much time as it does.
  • As mentioned before it only supports primitives as indexes, so one really can't do a full TestIndex test.
As search operations was so costly I though I run a very reduced test with 100 records just to see how all of the other database management systems (DBMS).


As we see search operations are costly, my guess to why they are so costly is the way that JODB interacts with files on the system. I think that it do a lot of input/output (IO) operations when it does it's search operations. From what I gathered from looking in the source code it uses a FileChannel object to access its database files, which just reads or writes on a specific part of a file. So when doing a search operation it will read through the file until it finds the "part" (Record) that we are interested in. This would also explain why it use so little memory when it is running.



Perst
SQLite
DB4O
BerkeleyDB
JODB
Insert
106
586
278
354
2183
Search
48
889
989
334
31021
Iterate
14
36
238
192
718
Delete
115
498
415
465
1011

JODB (Java Objects Database) for Android (2)

After my previous post on JODB and after using it for a while I discovered a couple of things about JODB. JODB is picky of what it allows you to use as an Index. It will only allow you to use primitives as an index, so if you try to use something that is not a primitive, such as a string:

db.configureIndex(Record.class, "strKey", true); won't work.

You will get an exception looking something like this:
com.mobixess.jodb.core.JodbIOException: can't find description for primitive java.lang.String
com.mobixess.jodb.util.PrimitiveJavaTypesUtil.getEnumeratedType(PrimitiveJavaTypesUtil.java:141)
com.mobixess.jodb.core.index.JODBIndexingAgent.(JODBIndexingAgent.java:73)
com.mobixess.jodb.core.index.JODBIndexingRootAgent.addAgent(JODBIndexingRootAgent.java:148)
com.mobixess.jodb.core.index.JODBIndexingRootAgent.enableIndex(JODBIndexingRootAgent.java:72)
com.mobixess.jodb.core.JODBSessionContainer.configureIndex(JODBSessionContainer.java:130)
com.mobixess.jodb.core.JODBSessionContainer.configureIndex(JODBSessionContainer.java:102)

Another thing you must watch out for is when you are deleting your object from the database, you should(must at least when they contain other stuff than primitives) deactivate them, before, deleting them.
Record r = set.next();
db.deactivate(r, 1);
db.delete(r);
If you do not do this you will get an exception from deep within the Apache harmoney classes, in mmap method.
java.io.IOException
org.apache.harmony.luni.platform.OSMemory.mmap(OSMemory.java:617)
org.apache.harmony.luni.platform.PlatformAddressFactory.allocMapPlatformAddressFactory.java:107)
org.apache.harmony.nio.internal.FileChannelImpl.mapImpl(FileChannelImpl.java:201)
org.apache.harmony.nio.internal.ReadWriteFileChannel.map(ReadWriteFileChannel.java:53)
org.apache.harmony.nio.internal.FileChannelImpl.transferFrom(FileChannelImpl.java:422)
com.mobixess.jodb.core.io.buffers.RandomAccessFileTransactionBuffer.transferFrom(RandomAccessFileTransactionBuffer.java:156)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction0(JODBIOBase.java:501)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction0(JODBIOBase.java:433)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction(JODBIOBase.java:336)
com.mobixess.jodb.core.JODBSessionContainer.commit(JODBSessionContainer.java:202
com.mobixess.jodb.core.JODBSessionContainer.commit(JODBSessionContainer.java:191)

So now I got a working TestIndex for JODB, so soon I'll hopefully have some results on the emulator and on the ADP1. The biggest problem I found with using JODB is the lack of documentation, so if you're considering using it you should be aware that it's not that much help to get.

Thursday, October 8, 2009

JODB (Java Objects Database) for Android

JODB (Java Objects Database) is an open source object-oriented database that is somewhat similar to db4objects.

License
JODB is completely free for personal and commercial use.

JODB
The developer of JODB sais that JODB is created with performance, size and scalability in mind. It uses soft reference based caches to effectively use the available ram but at the same time reduce the memory footprint as much as possible when memory is pricey, like it is on Android.
The developer say that the queries are optimized to the minimal of objects instantiations during the search so that garbage collector will have more time to 'rest' which is especially important for busy server applications (GC as is expensive and this is unlikely to change in near future).


Things you should watch out for
The Android version of JODB does not have the Client/Server functionality and can thus only be used as an embedded database. This really doesn't matter that much to me, as I was going to use it as an embedded database anyway, but it is something to take not of. The current version of JODB mini doesn't support running of native queries. The developer(s) say this will be corrected in future versions, but that's a long time ago so I'm not really sure that it will happen  . And at last the big one you must use com.mobixess.jodb.core.JodbMini as the entry point instead of com.mobixess.jodb.core.JODB.

So opening a database would look something like this:  JodbMini.open(databaseName) ;

Problems related to android
JODB have had Android support for a long time ( since 2007 ), but Android has changed a bit since they released their JODB Mini. RandomAccessFileBufferFactory.createBuffer in JODB, uses File.createTempFile() which creates a new file in the directory that is defined by the java.io.tmpdir system property. Using this method not a recommended practice in Android, as it will fill up data in a folder that might not be cleaned up, making the application fill up a lot of space, that we won't get back until it cleanup. It seems that Android( at least in 1.6 )  have solved this problem by setting the java.io.tmpdir to the SDCARD. But still we don't want to pollute our SDCARD directory with lots of temporary files, and in this case we want the files to be written and read fast so the SDCARD is not a good option. An other thing is that Android as of 1.6  Applications need explicit permission to be allowed to write to the SDCARD through the android.permission.WRITE_EXTERNAL_STORAGE permission.
To fix this you can:
  1. Give the application write access to the SDCARD.
  2. Set the "java.io.tmpdir" property to somewhere on the phone where the application can write, like in it's own "home" directory.
The nice thing about setting the "java.io.tmpdir" property property to a directory within the applications own directory is that when you remove the application from the device, all of the related data will also be removed.

I here set the temp directory to a directory with the application directory so I can clean up the temp files by just deleting the contents of that directory.

File dir = this.getDir("TMP", 0);
String newTempDir = dir.getAbsolutePath();
System.setProperty("java.io.tmpdir", newTempDir);

Documentation
JODB help page and javadoc is the only documentation that I found on JODB. JODB mini can be fetched here.

Wednesday, October 7, 2009

Signing Android applications

Signing
When you're developing Applications for Android you need to sign them. This must be done with a digital certificate that is owned by you, the
application developer.
Why sign?
There are several reasons for signing your applications; the most important reason is that Android needs to know who made the application and what applications an application can trust. Therefore the application must be signed with "your" private key.
Another reason as of the 1.6 SDK is to align your resources in your application packages. As mention in the previous post about Zipaling, the packages should be aligned after the application is signed.There are a lot of other aspects of signing in Android than one would think.
Application upgrading, Android won't allow application to be upgraded unless signed with same certificate the applications are signed with the same key.
Application modularity, Android allows applications that are signed with the same certificate to run in the same processes. This way you can deploy your application as modules.
Code/data sharing through permissions - the Android system provides a signature-based permissions enforcement, so that an application can expose functionality to another application that is signed with same certificate. So by signing multiple applications with the same certificate and using signature-base permissions
checks, your application can share code and data in a secure manner.
Validity
25 years or more is recommended. After the key's validity is expired, users will no longer be able, seamlessly upgrade to new versions of you application. When choosing the validity of your there are several aspects you should consider. As it must exceed all of the applications, including depending applications (modules) added in the future.
Marked
If you plan to put your applications on the Android Marked your validity period must be after 22. October 2033. This date is enforced by the Android Market Server and is put into place to ensure that users can seamlessly upgrade their applications.
When to sign
When your application is ready to be released to the "market", you should check that it is signed for "release", as the debug keys that are generated by the SDK won't do.
How to sign
There are two ways of signing your applications. Manually and from the build tool that you might be using environment in Android this will be Ant or ADT.
Manual approach:
The manual approach where you use the Keytool and Jarsigner from the command-line. These tools are bundled with the java development kit (JDK). When doing this you first compile your application as an unsigned .apk. After this you must a create keystore/key if you don’t allready has one. You can create the keystore/key by running keytool.
Creating keystore/key with Keytool:
The line below will create a keystore/key which you can use to sign your packages. The keystore file is a password protected file that stores keys and certificates that you use in the signing of you application.


keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000

When you run keytool with the following parameters you it will ask you about information that it needs to create your keystore.

Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: Jon Doe
What is the name of your organizational unit?
[Unknown]: R&D
What is the name of your organization?
[Unknown]: Corparation
What is the name of your City or Locality?
[Unknown]: Kongsberg
What is the name of your State or Province?
[Unknown]: Buskerud
What is the two-letter country code for this unit?
[Unknown]: NO
Is CN=Jon Doe, OU=R&D, O=Corparation, L=Kongsberg, ST=Buskerud, C=NO correct?
[no]: yes
Generating 1á024 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10á000 days for: CN=Jon Doe, OU=R&D, O=Corparation, L=Kongsberg, ST=Buskerud, C=NO
Enter key password for alias_name
(RETURN if same as keystore password):
[Storing my-release-key.keystore]

-genkey:tells keytool to create a key pair (public and private)
-v: Enable verbose output.
-keystore: The location of the keystore file, where the information is going to be stored.
-validity: The validity of the key, given in days.
-alias: The alias of your entry inside the keystore file
-keyalg:specifies the algorithm to be used to generate the key pair.

The keystore you just have made, you should put somewhere safe as this will be your identification as an Application developer. If someone gets a hold of your keystore they can sign applications with your identification.

Signing application with Jarsigner:
To sign your application with the key you created with the line above, you can the jarsigner tool.
jarsigner -verbose -keystore my-release-key.keystore my_application.apk alias_name

Enter Passphrase for keystore:
adding: META-INF/ALIAS_NA.SF
adding: META-INF/ALIAS_NA.RSA
signing: res/drawable/icon.png
signing: res/layout/main.xml
signing: res/layout/other.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: classes.dex

Once your application is signed, don't forget to run zipalign on the APK for additional optimization.

Using ADT
The Android SDK tools have options to assist you in signing your applications when debugging, and when you are ready for a release. Both the Android Development Tool (ADT) plug-in for Eclipse and ANT support debug and release mode signing, not going to go in to ANT signing now.
Debug mode signing

When you are developing and testing, you typically compile in debug mode. In this mode the build tools automatically use the Keytool from the JDK, creates a keystore and a key with a known key and alias. Since the password is known, the tools don't prompt you for the keystore/key password each time you compile. The self-signed certificate that is used to sign your application in default mode, have an expiration date of 365 days after its creation.So after a year you started signing in debug mode you might encounter:
debug:
[echo] Packaging bin/samples-debug.apk, and signing it with a debug key...
[exec] Debug Certificate expired on 8/4/08 3:43 PM
To remedy this you can delete the debug.keystore in the default storage location for AVD.

ADT release signing
Luckily the ADT can do all this for you in the ADT Export Wizard. It can even generate the key for you. And as mentioned in the previous post it will even do the aligning for you.
Creating a new keystore
The first thing you do is find the Export Signed Application Package wizard.
Then it will ask you which project you want to export.
The next step you will be asked to either use an existing keystore, or you can create a new one, we'll create a new one first.
At this stage you asked to enter an alias and password for this alias and validity for the signing, as well as the First and last name of the signer.
Now you just got to tell it where to export the signed package, and you're done.
Using an already existing keystore
If you already have a keystore that you want to use you select the use existing keystore.
To use the existing keystore you must select its location and enter the password you entered when creating it.
Now you can use the key that you that you defined when creating the key.


And now you're done, all signed up and ready to go.

For more info on the keytool application here, signing in Android documentation (recommended)