Android琐碎知识记录
  
  
使用最新的API,并支持新的硬件
  - 新的API效率更高
- 在运行时监测版本
- 使用接口或者平行Activity实现API兼容
对于使用接口和平行Activity的具体做法,记录如下:
平行Activity(The parallel Activity pattern)
  private static boolean shinyNewAPIS = 
  android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent startActivityIntent = null;
    if(!shinyNewAPIS)
      startActivityIntent = new Intent(this, legacyActivity.class);
    else
      startActivityIntent = new Intent(this, hcActivity.class);
      
    startActivity(startActivityIntent);
  }
接口(The Interfaces for backwards compatibility)
  private static boolean newSensorAPIsSupported = 
    Build,VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE;
  boolean gyroExists =
    getPackageManager().hasSystemFeature( PackageManager.FEATURE_SENSOR_GYROSCOPE );
  
  IOrientationSensorListener myListener;
  if ( gyroExists )
    myListener = new GyroOrientationSensorListener();
  else if ( newSensorAPIsSupported )
    myListener = new AccOrientationSensorListener();
  else 
    myListener = new AccOldOrientationSensorListener();
使用IntentFilter捕获网页链接( Capture links using Intent Filters )
  - Use Intent to capture links.
- Offer the best way to consume your content
- Deep link directly to quivalent content
  <activity android:name=".MyActivity">
    <intent-filter>
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="http"
            android:host="mysite.com"
            android:pathPrefix="/news/articles/" />
    </intent-filter>
  </activity>
内存管理( Memory Managerment )
Heap Size
对于Android应用来说,App的运行时可用内存最小是16M,但是真实出厂的设备内存往往高于这个值,比如
  - G1:16M
- *Droid:24M
- N1: 32M
- Xoom:48M
可以使用ActivityManager.getMemoryClass() 读取内存信息。
Large Heaps
一般的Android应用都有一个固定的内存上限,但是对一些特殊的设备(比如平板)屏幕尺寸非常大,即使仅仅展示一张图片所占用的内存也是很可观的,所以在Honeycomb开始引入了largeHeap可以为App分配更多的内存。
在 Honeycomb 以上的系统上可以在AndroidManifest.xml中添加  “largeHeap” 选项。
  <application 
    android:name="com.example.foobar"
    android:largeHeap="true"
    ...
  </application>
  - ActivityManager.getLargerMemoryClass()
这样可以申请更多的堆内存,申请更多的内存也会增加内存回收的负担,并且迫使其他的App因内存不足被杀死。
Garbage Collection
在垃圾回收方面,给App分贝更大的内存意味着更长的垃圾回收时间,在Gingerbreak之前,垃圾回收会有如下的弊端
  - Stop the world
- Full heap collection
- Pause times often > 100ms
在 Gingerbread 之后(包含)改进了上面的弊端
  - Concurrent(mostly)
- Partial collections
- Pause times usually <5ms
Bitmaps
Old way (pre-Honeycomb):
  - freed via recycled() or finalizer
- hard to debug
- full, stop-the-world GCs
这种方式必须手动调用 recycled 或者 等待垃圾回收才能回收内存。图片占用的内存是在native模块申请的,java对象指向native的内存。Bitmap对象和图片真实内存不再同一个区域。
New way:
  - freed synchronously by GC
- easier to debug
- concurrent & partial GCs
Bitmap和图片实际占用的内存都在托管代码部分。
Interpreting Log Message
有木有注意到Logcat中经常打印的信息,比如下面这样的Log 这条log包含了很多信息
D/dalvikvm( 9050 ): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
  - Reason for GC
    
      - GC_CONCURRENT
- GC_FOR_MALLOC
- GC_EXTERNAL_ALLOC
- GC_HPROF_DUMP_HEAP
- GC_EXPLICIT
 
- Amount freed “freed 2049K”
- Heap statistics “65% free 3571K/9991K”
- External memory statistics “external 4703K(allocated)/5261K(a sort of soft limit)” bitmap pixel data or nio buffer
- Pause time
Heap Dumps
  - Binary dump of all object
- Create with: DDMS , android.os.Debug.dumpHprofData()
- Convert to standard HPROF format: hprof-conv orig.hprof converted.hprof
- Analyze with MAT, jhat,etc
MAT
MAT是一个Java程序的内存分析工具,使用它可以发现很多内存泄露的问题,在Android界还是很牛逼的。首先有些基本概念需要明确。
  - Shallow heap 指当前对象占用内存的大小
- Retained heap 指当前对象和所持引用的对象(life owned by current object)的大小加
在MAT里面是使用 Dominator(支配者) Tree ( closest object on every path to node)来描述Retained heap 的,比如

左边是内存中的引用关系,右边是DominatorTree,所有的对象都是依赖A对象而活着的,但是D对象既可以依赖B也可以依赖C活着,所以它不依赖于B,C,而是依赖于A。
使用MAT查泄漏:
  - 在DominatorTree视图中,查找RetainedHeap最大的对象,然后找到它的GC-Root (exclude weak reference)。
     
- 在Histogram视图中,查找内存占用最大的对象 => List Objects => GC-Root
   
- 在Histogram视图中查找对象实例的数量,通过数量判断是否溢出
   
可疑对象
  - References to Activity,Context,View,Drawable,…
- Non-static innerr classes(eg: Runnable (延迟执行的Runnable持有一个已经摧毁了的Activity对象)) 小心!
- Caches
Tips:
  - Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
- Try using the context-application instead of a context-activity
- Avoid non-static inner classes in an activity if you don’t control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with a WeakReference to the outer class, as done in ViewRoot and its W inner class for instance
- A garbage collector is not an insurance against memory leaks
Advanced Android audio techniques
Video
  - Native audio signal processing
- Tips on power and resource usage
- What’s new in Froyo?
- Roadmap
AudioTrack Overview
  - Raw PCM audio API
- Streaming or static buffers
- Can set callbacks to refill buffer
- Retrieve play position
- Useful for games or streaming audio
Dalvik Virtual Machine Internals
Video
  - Intro
- Memory
- CPU
- Advice
- Conclusion
A JIT Compiler for Android’s Dalvik VM
Video
Overview
  - View live session notes and ask questions on Google Wave: http:/bit.ly/blzjnF
- Dalvik Environment
- Trace vs. Method Granularity JITs
- Dalvik JIT 1.0
- Future directions for the JIT
- Performance Case Studies
- Profiling JIT’d code
- Built-in Self-Verification Mode
nTop 
    02 April 2015