Mxn 一日三省吾身,续之或者改之

Drawingcache解析

android为了提高滚动等各方面的绘制速度,可以为每一个view建立一个缓存,使用 View.buildDrawingCache为自己的view建立相应的缓存, 这个cache就是一个bitmap对象。利用这个功能可以对整个屏幕视图进行截屏并生成Bitmap,也可以 获得指定的view的Bitmap对象。在有的时候还会影响性能,例如如果自己实现一个Gallery效果,可能就会使用到view缓存。animateCache和scrollingCache 用于动画和滚动的缓存,使用不当也会造成性能下降。

要获得一个view的bitmap对象涉及到三个方法:setDrawingCacheEnabled、buildDrawingCache和getDrawingCache。所有的View都有这三种方法。 大部分view如果没有设置setDrawingCacheEnabled(true);来启用View的DrawingCache功能的话,那默认是不启用。

启用DrawingCache的话,使用getDrawingCache方法时,会先自动去调用buildDrawingCache方法建立DrawingCache,再将结果返回; 不启用DrawingCache的话,使用getDrawingCache方法时,会返回上一次使用buildDrawingCache方法所产生的结果。 如果在此之前都沒有使用过buildDrawingCache来建立DrawingCache的话,那么getDrawingCache就会返回null。 如果一开始没有启用DrawingCache,也是可以事先使用buildDrawingCache来建立DrawingCache,避免getDrawingCache返回null。

getDrawingCache源码如下:

 
  public Bitmap getDrawingCache() {
        return getDrawingCache(false);
    }
  public Bitmap getDrawingCache(boolean autoScale) {
          if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
              return null;
          }
          if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
              buildDrawingCache(autoScale);
          }
          return autoScale ? mDrawingCache : mUnscaledDrawingCache;
      }
    

可以看出getDrawingCache在设置了DrawingCache的情况下自动调用buildDrawingCache。

Android渐变研究

下面介绍一个android实现渐变的方式

GradientDrawable

用GradientDrawable实现渐变可以通过xml或者代码实现,xml实现需要在drawable下建立xml文件,在标签下建立标签。

例如gradlient_background.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <gradient android:startColor="#aa000000"
                      android:endColor="@android:color/transparent"
                      android:angle="90"
                />
        </shape>
    </item>
</selector>
     

设置方法如下:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:id="@+id/layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/gradlient_background"
        android:orientation="horizontal"
        />
</RelativeLayout>  
        

Android开发小技巧积累

类安全转换函数

在安卓开发中的类似如下类型转换编辑器不会给出警告和try,catch提示,但是极易引起app崩溃。

String a = "1.333" ;
int b = Integer.valueOf(a) ; 
      

以上代码中如果a含有字符,或者小数就会引起崩溃,正确做法是在工具类中自己写一个转换函数,加入try,catch和默认值处理:

 public final static int convertToInt(String value , int defaultValue){
        if(value == null || "".equals(value.trim())){
            return defaultValue ;
        }
        try{
            return Integer.valueOf(value);
        }catch (Exception e){
            try{
                return Double.valueOf(value).intValue() ;
            }catch(Exception e1){
                return defaultValue ;
            }
        }
    }
          

使用时调用 :

    int b = Utils.convertToInt(a,1) ;
       

Strictmode的使用

StrictMode通常用于抓取在应用程序的主线程中来操作磁盘或者网络访问的问题,比如界面操作和动画,在非UI线程中处理磁盘文件和网络 操作使得程序更快、响应更及时,在保证你的程序足够流程的同时,你还需要阻止ANR事件的发生。 ANR窗口产生的原因是多种多样的。 程序的主线程因为IO读写或网络阻塞而导致被阻塞了,外部存储设备被独占了或系统负荷过高都可能导致ANR。 从Android 2.3开始提供了一个新的类StrictMode,可以帮助开发者改进他们的Android应用,StrictMode可以用于捕捉发生在应用程序 主线程中耗时的磁盘、网络访问或函数调用,使主线程处理UI和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞,导致ANR窗口的发生。

下面是启用StrictMode的实例,可以在Application的OnCreate中添加,这样就能在程序启动的最初一刻进行监控了。

 private void setStrictMode() {
        if (Integer.valueOf(Build.VERSION.SDK) > 3) {
            Log.d(LOG_TAG, "Enabling StrictMode policy over Sample application");
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()    // 这里可以替换为.detectDiskReads().detectDiskWrites().detectNetwork()。
                                    // detectAll() 包括了磁盘读写和网络I/O
                    .penaltyLog()   //打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
                    .penaltyDeath()
                    .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
        }
    }
     

Onterminate和onlowmemory的使用

关于Application类有以下公开方法:

其中最常用的就是onCreaet()、onTerminate()以及onLowMemory()方法,onCreaet()它会在这个类实例化的时候调用(这个地方需要十分注意, 它只会在程序第一次启动的时候调用,不是每次都调用,因为Application类会在创建包的时候初始化),onTerminate()会在app关闭的时候调用, onLowMemory()是在内存过低的情况下调用的。那onTerminate()是干什么用的呢?网上介绍说是在程序终结的时候调用,从下面的实例中也是这样用的。 不过在Google的开发文档以及很多书籍对这个类的用法很少提及,但实际开发情况是如何的呢。