Friday, May 18, 2018

Mounting OSFMount RAM drive on boot

I have used a number of RAM drives over time and more in the recent years with the increase in amount of RAM available to store user temporary files (autoclean on power down) and even projects build output directories (try and reduce some build times).

PassMark OSFMount might still be missing some features compared to other available RAM drive software out there, but it is free and it has received a number of improvements lately.

Install software

Download OSFMount (v2.0.1001, 21 Mar 2018 at the time of writing) and follow the installation instructions, nothing special there.

Create automount script

The script will mount the drive if the letter is available and it uses its internal format command which can only format FAT32 at the moment. Adjust the settings to fit depending on your needs and available free RAM (check with Task Manager > Performance > Memory). Save in a system (e.g. "%WINDIR%\Create RAM Drive + TEMP directory.cmd") or user location.
@ECHO OFF
SET RAMDISK_DRIVE=R:
SET RAMDISK_SIZE=1G
SET RAMDISK_LABEL=RAM Disk
IF NOT EXIST "%RAMDISK_DRIVE%" (
  "%PROGRAMFILES%\OSFMount\OSFMount.com" -a -t vm -s %RAMDISK_SIZE% -o format:"%RAMDISK_LABEL%" -m "%RAMDISK_DRIVE%
  MKDIR "%RAMDISK_DRIVE%\TEMP"
)
If you test run it in an elevated Command Prompt it should output like below:
"%WINDIR%\Create RAM Drive + TEMP directory.cmd"
Creating device...
Created device 0: R: -> VM image
Formatting drive with volume label RAM Disk
Notifying applications...
Done.


Task Scheduler

Create a scheduled task in Task Scheduler (taskschd.msc),  the important parts are to run At system startup and to Run whether user is logged on or not.




Finishing notes

Reboot and confirm RAM drive is there on startup.



IMPORTANT NOTE:

If you intend to change your user TEMP and TMP environment variables to point to R:\TEMP with a small RAM drive you can run into all sorts of weird issues when installing large applications or with anything that takes large amounts of temporary disk space for operating like Android sdkmanager update or anything like that.

If you still want to go this way cause you think you know what you're doing, any time something weird happens like that happens I would remember to change your TEMP and TMP environment variables back to default %USERPROFILE%\AppData\Local\Temp, logoff and try the operation again.

I have never considered changing system's TEMP or TMP environment variables, just the user ones.

Tuesday, April 17, 2018

Android SDK for development with Eclipse ADT

If you are still using Eclipse ADT for Android development, this is a tutorial to help you with installing the latest possible Android SDK / Tools that would work with last Eclipse ADT plugin.

  1. Eclipse IDE for Java Developers 4.7.3a
    http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/oxygen3a
  2. Eclipse ADT plugin - 23.0.7.2120684 (Aug 2015)
    https://dl-ssl.google.com/android/eclipse/
  3. Java JDK 1.8.0_172
    http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Now onwards to Android SDK & Tools.

Standard choice 

  1. SDK Tools 25.2.5 (Jan 2017)

    Extract into your chosen location e.g. android-sdk (note: do not extract on top of an existing installation, you can have as many Android SDK installations you want - create a new location or backup the old and remove / rename).
    Open a command line / shell and test by calling sdkmanager:
    tools\bin\sdkmanager --list | more
    
  2. Build Tools 25.0.3 (Apr 2017)

    tools\bin\sdkmanager "build-tools;25.0.3"
    Accept? (y/N): y
    
  3. Platform Tools 28.0.0 (May 2018)

    tools\bin\sdkmanager "platform-tools"
    Accept? (y/N): y 
  4. Platform(s) and sources

  5. tools\bin\sdkmanager "platforms;android-25"
    tools\bin\sdkmanager "sources;android-25"
    
    tools\bin\sdkmanager "platforms;android-27"
    tools\bin\sdkmanager "sources;android-27"
  6. Emulator 27.2.9 (May 2018)

  7. tools\bin\sdkmanager "emulator"
    Accept? (y/N): y
    
  8. Emulator images

    Downloading the image with sdkmanager may produce a 'broken' unusable image. Dowload using the the graphical version of Android SDK Manager. Additionally, API 27 images did not seem to work for me (emulator image stuck at boot with a blank screen). Recommending to try the API 25 images (or whichever versions you need).
    tools\android

  9. Check installed components

    tools\bin\sdkmanager --list | more
    
    Installed packages:
      Path                              | Version | Description                       | Location
      -------                           | ------- | -------                           | -------
      build-tools;25.0.3                | 25.0.3  | Android SDK Build-Tools 25.0.3    | build-tools\25.0.3\
      emulator                          | 27.2.9  | Android Emulator                  | emulator\
      patcher;v4                        | 1       | SDK Patch Applier v4              | patcher\v4\
      platform-tools                    | 28.0.0  | Android SDK Platform-Tools        | platform-tools\
      platforms;android-25              | 3       | Android SDK Platform 25           | platforms\android-25\
      platforms;android-27              | 1       | Android SDK Platform 27           | platforms\android-27\
      sources;android-25                | 1       | Sources for Android 25            | sources\android-25\
      sources;android-27                | 1       | Sources for Android 27            | sources\android-27\
      system-images;a...s_playstore;x86 | 9       | Google Play Intel x86 Atom Sys... | system-images\a..._playstore\x86\
      tools                             | 25.2.5  | Android SDK Tools 25.2.5          | tools\
  10. Intel HAXM 7.2.0 (May 2018)


    Read installation guide, download & install from:
    https://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager-intel-haxm

  11. Start Eclipse

    To be detailed
  12. Create AVD

    To be detailed


     
Publishing early as a draft for my friend Enzo :-) to be continued tomorrow.

Tuesday, January 2, 2018

AppCompat runtime error: "android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052"

Developing an Android app with the latest Support Library versions you may encounter this crash at startup on devices running Android < 5.0 (API 21):
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.googleplayservicesdemo/com.example.googleplayservicesdemo.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
       at android.app.ActivityThread.access$600(ActivityThread.java:141)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:137)
       at android.app.ActivityThread.main(ActivityThread.java:5041)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:511)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/abc_vector_test.xml from drawable resource ID #0x7f020052
       at android.content.res.Resources.loadDrawable(Resources.java:1953)
       at android.content.res.Resources.getDrawable(Resources.java:660)
       at android.support.v7.widget.VectorEnabledTintResources.superGetDrawable(VectorEnabledTintResources.java:74)
       at android.support.v7.widget.AppCompatDrawableManager.onDrawableLoadedFromResources(AppCompatDrawableManager.java:435)
       at android.support.v7.widget.VectorEnabledTintResources.getDrawable(VectorEnabledTintResources.java:67)
       at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:353)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:200)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:188)
       at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:755)
       at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:193)
       at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:87)
       at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:128)
       at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
       at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29)
       at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54)
       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202)
       at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
       at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
       at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:70)
       at com.example.googleplayservicesdemo.MainActivity.onCreate(MainActivity.java:19)
       at android.app.Activity.performCreate(Activity.java:5104)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
       ... 11 more
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #17: invalid drawable tag vector
       at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881)
       at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
       at android.content.res.Resources.loadDrawable(Resources.java:1950)
       ... 33 more
Force finishing activity com.example.googleplayservicesdemo/.MainActivity

Cause

Android Developers documentation (Vector Drawables Backward Compatibility Solution) mentions having to add --no-version-vectors AAPT parameter for older versions of Gradle plugin.

Running android-sdk/build-tools/xx.y.z/aapt with no parameters tells us more about the parameter:
   --no-version-vectors
       Do not automatically generate versioned copies of vector XML resources.
If we look at the AppCompat library it contains only one res/drawable/abc_vector_test.xml, but if you dissamble your APK with Apktool (apktool d your.apk) you will notice that during preparing and packaging the Android tools have created two versions from the original: res/drawable/abc_vector_test.xml and res/drawable-v21/abc_vector_test.xml.

Eclipse Andmore

Eclipse Andmore brought support for --no-version-vectors with version 0.5.1 (bug 509663)
  1. Go to your app project > Properties
  2. Check the '--no-version-vectors' option
  3. Project > Clean

Eclipse ADT

Eclipse ADT plugin is no longer supported by Google, but if you are still using it and you haven't migrated to Eclipse Andmore or Android Studio yet there is a solution that involves replacing aapt with a wrapper tool that will add --no-version-vectors when called with package option.

That is because if you enable verbose (Preferences > Android > Build > Build output = Verbose) the path and name of aapt tool is pretty much hardcoded so for this to work we will need to rename the original and replace it with this wrapper program I wrote for this.

  1. Download the latest from Github dandar3/android-aapt-wrapper releases
  2. Go to android-sdk\build-tools\xx.y.z\
  3. Rename aapt.exe to aapt-original.exe (Windows) and aapt to aapt-original (Linux) 
  4. Save aapt-wrapper.exe as aapt.exe (Windows) and aapt-wrapper as aapt (Linux) 
  5. Verify the pass through by running aapt - you should see the wrapper info followed by the real aapt output:
    Android Asset Packaging Tool - Wrapper
    Version 1.0 (31 Dec 2017)
    https://github.com/dandar3/android-aapt-wrapper
    
    Command:
      aapt-original.exe
    
    Android Asset Packaging Tool
    
    Usage:
     aapt l[ist] [-v] [-a] file.{zip,jar,apk}
       List contents of Zip-compatible archive.
    
     aapt d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]
       strings          Print the contents of the resource table string pool in the APK.
    ... 
  6. Project > Clean