总结Android 开发中一些很有用但你不知道的方法

vimxcy 7年前
   <ul>     <li> <p>setBackgroundResource(0) 可以移除 View 的背景色</p> </li>     <li> <p>Resources.getSystem().getDisplayMetrics().density 可以不用 Context 也能获取屏幕密度哦</p> </li>     <li> <p>通过重载 ViewGroup 的 dispatchDraw 可以实现一个简单的蒙版效果。 例如下拉刷新时,可以在 contentView 上加一层遮罩。 canvas.drawRect(0, mContentView.getTranslationY(), getWidth(), getHeight(), mMaskPaint);</p> </li>     <li> <p>new 出来的 View 可以用 View.generateViewId() (API 17 以上可用) 生成 id,系统保证唯一</p> </li>     <li> <p>使用 GridView时 android:padding 和android:clipToPadding="false" 配合使用效果更好哦。</p> </li>     <li> <p>在布局文件中,如果只是为了占位,可以用 Space 来取代 View。 最棒的一点是Space可以跳过 Draw 这个过程。</p> </li>     <li> <p>TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics) 方便dp, px, sp 之间的转换。</p> </li>     <li> <p>Activity.startActivities() 这个方法最直接的理解就是使用intent开启多个Activity</p> </li>     <li> <p>TextUtils.isEmpty() 如果传入的String 为NULL或者Length为0的话就返回 true。</p> </li>     <li> <p>Html.fromHtml() 如果你对Html熟悉的话,可以很迅速通过这个方法处理一些富文本操作。比如超链接和图文排版等处理。</p> </li>     <li> <p>TextView.setError() 设置文本框错误提醒</p> </li>     <li> <p>Build.VERSION_CODES 有些时候我们的app需要根据不同的SDK版本进行执行不同的操作</p> </li>     <li> <p>PhoneNumberUtils.convertKeypadLettersToDigits 这个方法简单粗暴,会将输入的字母根据键盘上的映射转换为数字。</p> </li>     <li> <p>ArgbEvaluator ArgbEvaluator.evaluate(float fraction, Object startValue, Object endValue);根据一个起始颜色值和一个结束颜色值以及一个偏移量生成一个新的颜色,分分钟实现类似于微信底部栏滑动颜色渐变。</p> </li>     <li> <p>ValueAnimator.reverse() 顺畅的取消动画效果</p> </li>     <li> <p>DateUtils.formatDateTime()) 这个方法可以输出相应格式化的时间或者日期</p> </li>     <li> <p>Pair 这个类 可以用来存储存储一”组”数据。但不是key和value的关系。</p> </li>     <li> <p>SparseArray 目前有很多地方从性能优化方说使用SparseArray来替换hashMap,来节省内存,提高性能。</p> </li>     <li> <p>Linkify.addLinks() 这个类可以更方便的为文本添加超链接。</p> </li>     <li> <p>android.media.ThumbnailUtils这个类主要是用来处理缩略图相关的工作,比如:用来获取媒体(图片、视频)的缩略图;</p> </li>     <li> <p>Bitmap.extractAlpha ();返回一个新的Bitmap,capture原始图片的alpha值。有的时候我们需要动态的修改一个元素的背景图片又不希望使用多张图片的时候,通过这个方法,结合Canvas和Paint可以动态的修改一个纯色Bitmap的颜色。</p> </li>     <li> <p>模块间有消息需要传递时,使用LocalBroadcastManager替代Listener进行模块解耦。除了解耦,这样发送消息和执行消息差一个线程循环,可以减小方法的调用链,我这就碰到一次方法调用链太长导致StackOverflow的问题。</p> </li>     <li> <p>静态变量不要直接或者间接引用Activity、Service等。这会使用Activity以及它所引用的所有对象无法释放,然后,用户操作时间一长,内存就会狂升。</p> </li>     <li> <p>Handler机制有一个特点是不会随着Activity、Service的生命周期结束而结束。也就是说,如果你Post了一个Delay的Runnable,然后在Runnable执行之前退出了Activity,Runnable到时间之后还是要执行的。如果Runnable里面包含更新View的操作,程序崩溃了。</p> </li>     <li> <p>不少人在子线程中更新View时喜欢使用Context.runOnUiThread,这个方法有个缺点,就是一但Context生命周期结束,比如Activity已经销毁时,一调用就会崩溃。</p> </li>     <li> <p>SharedPreferences.Editor.commit这个方法是同步的,一直到把数据同步到Flash上面之后才会返回,由IO操作的不可控,尽量使用apply方法代替。apply只在API Level>=9才会支持,需要做兼容。不过,最新的  support v4  包已经为我们做好了处理,使用  SharedPreferencesCompat.EditorCompat.getInstance().apply(editor)  即可。</p> </li>     <li> <p>PackageManager.getInstalledPackages这个方法经常使用,你可能不知道,当获取的结果数量比较多的时候,在某些机型上面调用它花费的时间可能秒级的,所以尽量在子线程中使用。另外,如果结果太多,超过系统设置的Binder数据最大传输量的上限,则会发生TransactionException,如果你使用这个方法获取机器上的己安装应用列表,最好做一下预防。</p> </li>     <li> <p>如果使用Context.startActivity启动外部应用,最好做一下异常预防,因为寻找不到对应的应用时,会抛出异常。如果你要打开的是应用内的Activity,不防使用显式Intent,这样能提高系统搜索目标Activity的效率。</p> </li>     <li> <p>Application的生命周期就是进程的生命周期。只有进程被干掉时,Application才会销毁。哪怕是没有Activity、Service在运行,Application也会存在。所以,为了减少内存压力,尽量不要在Application里面引用大对象、Context等。</p> </li>     <li> <p>getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);设置全屏方法一定要在setContentView之后</p> </li>     <li> <p>viewpager 的 setCurrentItem 一定要在 setAdapter 方法之后调用才会有效果.</p> </li>     <li> <p>判断手机是不是飞行模式 boolean isEnabled = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;</p> </li>     <li> <p>遍历HashMap的最佳方法</p> </li>    </ul>    <pre>  public static void printMap(Map mp) {     </pre>    <pre>  for (Map.Entry m : mp.entrySet()) {             System.out.println(m.getKey() + ":" + m.getValue());</pre>    <pre>     }  }</pre>    <ul>     <li> <p>使用Java在一个区间内产生随机整数数</p> </li>     <li> <pre>  public static int randInt(int min, int max) {   </pre> </li>     <li> <pre>  Random rand = new Random();        int randomNum = rand.nextInt((max - min) + 1) + min;         return randomNum;  }</pre> </li>     <li> <p>如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。</p> </li>     <li> <p>transient关键字修饰变量可以限制序列化。</p> </li>     <li> <p>当使用JakeWharton的TabPageIndicator时,如果需要先做一些耗时的操作,然后再展示TabPageIndicator的话,需要先设置mIndirector.setVisibility(View.GONE);然后耗时任务结束以后再mIndirector.setVisibility(View.VISIBLE);否则会报错</p> </li>     <li> <p>类继承之间的调用顺序 父类static成员 -> 子类static成员 -> 父类普通成员初始化和初始化块 -> 父类构造方法 -> 子类普通成员初始化和初始化块 -> 子类构造方法</p> </li>     <li> <p>华为手机无法显示log解决方案,.拨号界面输入(*#*#2846579#*#*) Service menu will appear.Go to "ProjectMenu" -> "Background Setting" -> "Log Setting"Open "Log switch" and set it to ON.Open "Log level setting" and set the log level you wish.</p> </li>     <li> <p>后台service经常因为重启之类的出现onStartCommand()中的Intent传递的参数为null, 通过在onStartCommand()中的返回值改成return super.onStartCommand(intent, Service.START_REDELIVER_INTENT, startId); 可以解决问题。下面介绍几个flag的意思</p>      <table>       <thead>        <tr>         <th>flag</th>         <th>解释</th>        </tr>       </thead>       <tbody>        <tr>         <td>START_STICKY</td>         <td>如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。</td>        </tr>        <tr>         <td>START_NOT_STICKY</td>         <td>“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。</td>        </tr>        <tr>         <td>START_REDELIVER_INTENT</td>         <td>重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。</td>        </tr>        <tr>         <td>START_STICKY_COMPATIBILITY</td>         <td>START_STICKY的兼容版本,但不保证服务被kill后一定能重启。</td>        </tr>       </tbody>      </table> </li>     <li> <p>不能在Activity没有完全显示时显示PopupWindow和Dialog</p> </li>     <li> <p>在多进程之间不要用SharedPreferences共享数据,虽然可以(MODE_MULTI_PROCESS),但极不稳定</p> </li>    </ul>    <p> </p>    <p>来自:http://mp.weixin.qq.com/s/N7o12OwAbIjPmaHbm4greA</p>    <p> </p>