Authorvillain_dm

long or notlong

As you know you can name layout or resource folders with “-long” or “-notlong” postfix.
Documentation says:

  1. long – resources for screens of any size or density that have a significantly taller (in portrait mode) and wider (in landscape mode) aspect ratio than the baseline screen configuration.
  2. notlong – resources for use only on screens that have an aspect ratio that is similar to the baseline screen configuration.

What does it mean in practice?

hvga – notlong
qvga – notlong
wqvga400 – long
wqvga432 – long
wvga800 – long
wvga854 – long

i.e. if you have aspect ration > 1.5 like 1.78 (480×854) long folders will be used by Android.

For example if you scale layout hvga (1.5) to wvga854 (1.78) – you should take into account additional 480*1.5=720; 854-730=134 pixels in the middle.

p.s. Motorola Flipout is notlong also because it is just landscape qvga.

//DL

How to use PhantomReference

What is PhantomReference?

    1. They allow you to determine exactly when an object was removed from memory. They are in fact the only way to determine that. This isn’t generally that useful, but might come in handy in certain very specific circumstances like manipulating large images: if you know for sure that an image should be garbage collected, you can wait until it actually is before attempting to load the next image, and therefore make the dreaded OutOfMemoryError less likely [read more]
    2. The main advantage of using a PhantomReference over finalize() is that finalize() is called by a garbage-collector thread, meaning it introduces concurrency even in a single-threaded program, with all the potential issues (like correctly synchronizing shared state). With a PhantomReference, you choose the thread that dequeues references from your queue (in a single-threaded program, that thread could periodically do this job) [read more]

      Read more about references here: http://www.ibm.com/developerworks/library/j-refs/

      See example in Email application in Android platform: http://google.com/codesearch/p?hl=en#SS2by_AKaLs/src/org/apache/commons/io/FileCleaningTracker.java

      Btw, you can also ressurect object with reflection (http://code-o-matic.blogspot.com/2009/01/subtleties-of-phantomreference-and.html)

      Here’re small exaple of usage:

      import java.lang.ref.PhantomReference;
      import java.lang.ref.Reference;
      import java.lang.ref.ReferenceQueue;
      import java.lang.reflect.Field;
      import java.util.ArrayList;
      
      public class MemoryTest {
          private ReferenceQueue<Data> mQueue = new ReferenceQueue<Data>();
          private boolean mIsRun = true;
      
          public void test() {
      
              final ArrayList<PhantomReference<Data>> blocks = new ArrayList<PhantomReference<Data>>();
              ArrayList<Data> dataArray = new ArrayList<Data>();
              System.out.println("occupied mem 1 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
              for (int i = 0; i < 10; i++) {
                  Data data = new Data(i);
                  PhantomReference<Data> ref = new PhantomReference<Data>(data, mQueue);
                  blocks.add(ref);
                  dataArray.add(data);
              }
              System.out.println("occupied mem 2 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
              System.out.println("remove strong ref to object 0 and 1");
              dataArray.remove(0);
              dataArray.remove(0);
              new Thread() {
                  public void run() {
                      System.out.println("thread started");
                      while (mIsRun) {
                          Reference<?> ref = null;
                          try {
                              ref = mQueue.remove(1000);
                          } catch (IllegalArgumentException e) {
                              e.printStackTrace();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          if (ref != null) {
                              System.out.println(">> removed ref = " + ref);
                              blocks.remove(ref);
                              Field f = null;
                              try {
                                  f = Reference.class.getDeclaredField("referent");
                                  f.setAccessible(true);
                                  System.out.println("I see dead objects! --> " + f.get(ref));
                              } catch (SecurityException e) {
                                  e.printStackTrace();
                              } catch (NoSuchFieldException e) {
                                  e.printStackTrace();
                              } catch (IllegalAccessException e) {
                                  e.printStackTrace();
                              }
                          }
                      }
                      System.out.println("thread ended");
                  }
              }.start();
              System.out.println("objects created");
              try {
                  Thread.sleep(3000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("occupied mem 2 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
              System.out.println("run gc() to make object enqueued");
              System.gc();
              try {
                  Thread.sleep(3000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("collect memory");
              System.runFinalization();
              System.gc();
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("occupied mem 4 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
              mIsRun = false;
          }
      
          private static class Data {
              int id;
              byte[] memoryBlock = new byte[1048576];
      
              public Data(int id) {
                  this.id = id;
                  System.out.println("Data created: " + this);
              }
      
              @Override
              public String toString() {
                  return "{id=" + id + " " + super.toString() + "}";
              }
          }
      }
      

      What we can see in LogCat:

      06-08 14:38:51.154: INFO/System.out(1385): occupied mem 1 = 2186800
      06-08 14:38:51.254: DEBUG/dalvikvm(1385): GC freed 845 objects / 56288 bytes in 94ms
      06-08 14:38:51.295: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 4.119MB for 1048592-byte allocation
      06-08 14:38:51.394: DEBUG/dalvikvm(1385): GC freed 11 objects / 544 bytes in 93ms
      06-08 14:38:51.404: INFO/System.out(1385): Data created: {id=0 com.gtug.test.MemoryTest$Data@4373e658}
      06-08 14:38:51.484: DEBUG/dalvikvm(1385): GC freed 22 objects / 1456 bytes in 80ms
      06-08 14:38:51.534: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 5.119MB for 1048592-byte allocation
      06-08 14:38:51.724: DEBUG/dalvikvm(1385): GC freed 159 objects / 7136 bytes in 191ms
      06-08 14:38:51.734: INFO/System.out(1385): Data created: {id=1 com.gtug.test.MemoryTest$Data@4372b7e8}
      06-08 14:38:51.825: DEBUG/dalvikvm(1385): GC freed 20 objects / 1352 bytes in 92ms
      06-08 14:38:51.865: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 6.112MB for 1048592-byte allocation
      06-08 14:38:51.965: DEBUG/dalvikvm(1385): GC freed 36 objects / 18336 bytes in 96ms
      06-08 14:38:51.974: INFO/System.out(1385): Data created: {id=2 com.gtug.test.MemoryTest$Data@43734338}
      06-08 14:38:52.054: DEBUG/dalvikvm(1385): GC freed 20 objects / 1344 bytes in 87ms
      06-08 14:38:52.105: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 7.112MB for 1048592-byte allocation
      06-08 14:38:52.204: DEBUG/dalvikvm(1385): GC freed 0 objects / 0 bytes in 98ms
      06-08 14:38:52.214: INFO/System.out(1385): Data created: {id=3 com.gtug.test.MemoryTest$Data@4372a968}
      06-08 14:38:52.285: INFO/System.out(1385): Data created: {id=4 com.gtug.test.MemoryTest$Data@4372a498}
      06-08 14:38:52.375: DEBUG/dalvikvm(1385): GC freed 44 objects / 2888 bytes in 92ms
      06-08 14:38:52.455: INFO/System.out(1385): Data created: {id=5 com.gtug.test.MemoryTest$Data@43736180}
      06-08 14:38:52.565: DEBUG/dalvikvm(1385): GC freed 25 objects / 1464 bytes in 102ms
      06-08 14:38:52.635: INFO/System.out(1385): Data created: {id=6 com.gtug.test.MemoryTest$Data@4372b950}
      06-08 14:38:52.755: DEBUG/dalvikvm(1385): GC freed 28 objects / 1584 bytes in 116ms
      06-08 14:38:52.804: INFO/ActivityManager(578): Displayed activity com.gtug.test/.PhantomTest: 2327 ms
      06-08 14:38:52.875: INFO/System.out(1385): Data created: {id=7 com.gtug.test.MemoryTest$Data@4373b680}
      06-08 14:38:53.065: DEBUG/dalvikvm(1385): GC freed 26 objects / 1600 bytes in 179ms
      06-08 14:38:53.104: INFO/System.out(1385): Data created: {id=8 com.gtug.test.MemoryTest$Data@437381a8}
      06-08 14:38:53.185: DEBUG/dalvikvm(1385): GC freed 24 objects / 1504 bytes in 74ms
      06-08 14:38:53.224: INFO/System.out(1385): Data created: {id=9 com.gtug.test.MemoryTest$Data@4373aec8}
      06-08 14:38:53.235: INFO/System.out(1385): occupied mem 2 = 12600240
      06-08 14:38:53.235: INFO/System.out(1385): remove strong ref to object 0 and 1
      06-08 14:38:53.244: INFO/System.out(1385): thread started
      06-08 14:38:53.244: INFO/System.out(1385): objects created
      06-08 14:38:56.254: INFO/System.out(1385): run gc() -> overrided finalyze print
      06-08 14:38:56.324: DEBUG/dalvikvm(1385): GC freed 45 objects / 2512 bytes in 74ms
      06-08 14:38:56.334: INFO/System.out(1385): Data finalized: {id=1 com.gtug.test.MemoryTest$Data@4372b7e8}
      06-08 14:38:56.334: INFO/System.out(1385): Data finalized: {id=0 com.gtug.test.MemoryTest$Data@4373e658}
      06-08 14:38:58.184: DEBUG/dalvikvm(622): GC freed 119 objects / 5872 bytes in 79ms
      06-08 14:38:59.344: INFO/System.out(1385): occupied mem 3 = 12602504
      06-08 14:38:59.344: INFO/System.out(1385): run gc() second time to make object enqueued
      06-08 14:38:59.434: DEBUG/dalvikvm(1385): GC freed 45 objects / 2944 bytes in 85ms
      06-08 14:38:59.434: INFO/System.out(1385): >> removed ref = java.lang.ref.PhantomReference@4373a4c0
      06-08 14:38:59.434: INFO/System.out(1385): I see dead objects! --> {id=1 com.gtug.test.MemoryTest$Data@4372b7e8}
      06-08 14:38:59.434: INFO/System.out(1385): >> removed ref = java.lang.ref.PhantomReference@437343f8
      06-08 14:38:59.434: INFO/System.out(1385): I see dead objects! --> {id=0 com.gtug.test.MemoryTest$Data@4373e658}
      06-08 14:39:02.446: INFO/System.out(1385): collect memory
      06-08 14:39:02.524: DEBUG/dalvikvm(1385): GC freed 75 objects / 2101968 bytes in 76ms
      06-08 14:39:07.554: INFO/System.out(1385): occupied mem 4 = 10503728
      06-08 14:39:08.454: INFO/System.out(1385): thread ended<!--more-->
      

      happy coding!

      //DL

      © 2017 Android Tales

      Theme by Anders NorenUp ↑