Tuesday, September 4, 2012

Android dynamic load library

There are two tricks to create dynamic load library in Android
  1. Use of sharedUserId in AndroidManifest for your applications and library project
  2. Use of dalvik.system.DexClassLoader to load library

Library Code:

It contains just java code without any Android specific entry points. AndroidManifest.xml just contains this android:sharedUserId attribute

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testlib"
    android:sharedUserId="com.example.testlib"
    android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minsdkversion="15" android:targetsdkversion="15" />

    <application android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme">
    </application>
</manifest>

TestCore.java

package com.example.testlib;
public class TestCore implements ITestCore{
    private int count = 0;
    public String testString(String arg) {
        String res = arg + count;
        count++;
        return res;
    }
}

Sample Application Code

Application that uses the library. Here is just the AndroidManifest.xml and TestApplication.java which do the trick. All other application staff is as usual.

AndroidManifest.xml

Be carefull to use same android:sharedUserId value in AndroidManifest.xml as library one
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testapp"
    android:sharedUserId="com.example.testlib"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk= android:minsdkversion="15" android:targetsdkversion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".TestApplication" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="android.app.Activity" />
           <intent-filter
                <action android:name="android.intent.action.MAIN"/ >
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.DEFAULT" /&gt
            </intent-filter>
        &lt/activity>
    </application>
</manifest>

ITestCore.java

Library interface has to be declared in application to avoid use reflection

    package com.example.testlib;
 
    public interface ITestCore {
    String testString(String arg);
    }

TestApplication.java

In applicatiopn's onCreate handler there is real work happens
package com.example.testapp;

import com.example.testlib.ITestCore;
import dalvik.system.DexClassLoader;
import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.util.Log;

public class TestApplication extends Application {
    ClassLoader libClassLoader;
   
    @Override
    public void onCreate() {
        PackageManager pm = getPackageManager();
        String libSrcPath = null;
        for (ApplicationInfo app : pm.getInstalledApplications(0)) {
            if (app.packageName.equals("com.rhomobile.testlibrary")) {
                libSrcPath = app.sourceDir;
                Log.d("TestApplication", "package: " + app.packageName + ", sourceDir: " + app.sourceDir);
            }
        }
        try {
            libClassLoader = new DexClassLoader(libSrcPath, getDir("dex", 0).getAbsolutePath(), null, getClassLoader());
            Class clazz = libClassLoader.loadClass("com.rhomobile.testlib.TestCore");
            ITestCore core = (ITestCore)clazz.newInstance();
            String str = core.testString("TestApplication 1:");
            Log.i("TestApplication", "output: " + str);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            Log.e("TestApplication", libClassLoader.toString());
            e.printStackTrace();
        }
    }
}

Central idea is borrowed from here: Android Developers Blog: Custom Class Loading in Dalvik

Tuesday, June 5, 2012

Thursday, October 13, 2011

Multiple working folders with single GIT repository clone

Actually the trick is quite trivial, we use our knowledge of git internals and unix symbolic links to achieve what we want. All we wanted is to have one repository and multiple working folders associated with it, so lets do just that.

Monday, April 4, 2011

Disable screen rotation at runtime on Android

It's strange I found no ready solution in Net...

There are two sources that help me:
http://stackoverflow.com/questions/2795833/check-orientation-on-android-phone
http://www.anddev.org/rotate_screen_from_code_change_screen_orientation-t2687.html

Finally, the next code is really works (I tested it):


public class MyActivity extends Activity {

   private int mRuntimeOrientation;
   private boolean mDisableScreenRotation;

   protected int getScreenOrientation() {
      Display display = getWindowManager().getDefaultDisplay();
      int orientation = display.getOrientation();

      if (orientation == Configuration.ORIENTATION_UNDEFINED) {
         orientation = getResources().getConfiguration().orientation;

         if (orientation == Configuration.ORIENTATION_UNDEFINED) {
            if (display.getWidth() == display.getHeight())
               orientation = Configuration.ORIENTATION_SQUARE;
            else if(display.getWidth() < display.getHeight())

               orientation = Configuration.ORIENTATION_PORTRAIT;
            else
               orientation = Configuration.ORIENTATION_LANDSCAPE;
            }
         }
      return orientation;
   }

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mRuntimeOrientation = this.getScreenOrientation();
   }

   @Override
   public void onConfigurationChanged(Configuration newConfig) {
      if (mDisableScreenRotation) {
         super.onConfigurationChanged(newConfig);
         this.setRequestedOrientation(mRuntimeOrientation);
      } else {
         mRuntimeOrientation = this.getScreenOrientation();
         super.onConfigurationChanged(newConfig);
      }
   }
}

Thursday, March 17, 2011

C++ exceptions in destructors

Latest time while I'm looking a new job place and participating in interviews with professionals at other companies I continiously try to lighten different C++ questions...

I will post here Links to most appropriate C++ articles like previous and this ones...

C++ exceptions in destructors

 

Friday, December 10, 2010

Obvios and incredible C++

 
void print_component(const Component&, const std::string&);
void print_component_env(const Component&, const std::string&);

...
(env ? print_component_env : print_component)(comp, prop_names);

Friday, March 12, 2010

.NET: The Project Location is Not Trusted

There is instructions at msdn that can be found easy:
http://msdn.microsoft.com/en-us/library/bs2bkwxc(VS.80).aspx

To start Mscorcfg.msc tool go to:
Control Panel\Administrative Tools\Microsoft .NET Framework 2.0 Configuration

Microsoft gives instruction to setup new trusted zone for every project location at intranet. There is better solution if your corporate intranet protected by firewall and you have many project locations (or location can change frequently: like with ClearCase).

Instead of URL select Zone for code group condition type and select Local Intranet zone.
Select FullTrust permission set at next page. Finish the wizard.
Viola: All intranet is trusted. The only thing: you should be sure that you can trust your intranet :)

Wednesday, March 10, 2010

How do you dig in another's source codes?..

Two and a half years ago I moved to my present job place. Then I again faced the problem to lean new portion of legacy spaghetti code...

I asked my new colleagues what tools they use to understand project code. I was very pity for their answer: a most advanced tools they used are a paper and a pen... One or two remembered SourceInsight IDE that can build a call tree (kind of search of references organized in a tree view).

I made fast analysis what facilities I need to dig in to a completely unknown complex code:
1. Search of references
2. Editable result of the search (to remove references I do not need)
3. Bookmarks to remember recent places in sources that are interesting
4. Tree organized bookmarks view to remember search tree

It is not very complex requirements but nobody implemented it so far (Or I do not know about...) :-(