美文网首页
2018-09-18 - Android开发手册

2018-09-18 - Android开发手册

作者: 耑意儿 | 来源:发表于2018-09-18 18:08 被阅读216次

开发手册 - 小知识补充

额。。。贪多嚼不烂,感慨还是需要一条一条慢慢学习进去。毕竟每一条都是知识点

目录:
1、Android组件
2、UI与布局
3、进程、线程与消息通信
4、文件与数据库
5、Bitmap、Drawable 与动画
6、安全
7、其他

一、Android组件

1.1、Activity之间需要传递大数据量的时候避免使用Intent+Parcelable的方式。

EventBus替代,以避免造成TransactionTooLargeException
Lisa's EventBus Demo

1.2、耗时操作
  • 避免在Service#onStartCommand()/onBind()方法中执行耗时操作。
    • 如果有耗时操作,用IntentService来替代Service或者采用其他的异步机制
  • 避免在BroadcastReceiver#onReceive()中执行耗时操作
    • 有耗时工作,创建IntentService完成。
      BroadcastReceiver#onReceive()方法耗时超过10秒可能被系统杀死
  • 不要在onPause()中执行耗时操作。
    • 如果在onPause方法中做耗时操作,可能会影响页面跳转,造成卡顿
1.3、避免使用隐式Intent广播敏感信息。避免被其他APP接收

仅限于应用内的广播,用LocalBroadcastManager#sendBroadcast()

LocalBroadcastManager.getInstance(context)
                     .registerReceiver(receiver, filter);
LocalBroadcastManager.getInstance(context)
                     .unregisterReceiver(receiver);
1.4、不要在Activity.onDestroy()执行资源释放工作

因为onDestroy()执行的时间可能比较晚。
Activity#onPause()/onStop()中用Activity.isFinishing()方法来判断是否APP处于预备销毁的阶段,然后做对应的资源销毁工作。

而且,假设Activity的引用还被其他部分所持有,那么很可能会一直不执行onDestroy()方法,在这种情况下如果资源释放工作都放在onDestroy()里面,很可能导致内存溢出。

    @Override
    protected void onPause() {
        super.onPause();
        if(isFinishing()){
            // 资源可以释放了。。。
        }
    }
  • Activity.isFinishing()
    • true : Activity处于待回收状态
    • false:Activity处于活跃状态
  • Activity.isDestroyed()
    • true:Activity已经执行过onDestroy()方法
    • false:Activity还没执行onDestroy()方法
1.5、如果要创建Service,尽量用IntentService
1.6、全局定义一个Toast对象,避免出现连续显示吐司时无法取消上一次吐司。
  • 原来的ToastUtils:
public class ToastUtils {

    private ToastUtils() {
            /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    public static boolean isShow = true;

    public static void showShort(Context context, CharSequence message) {
        if (isShow){
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        }
    }
}
  • 改良后的ToastUtils:
**
 * Toast要全局定义统一的一个对象,避免出现Toast无法销毁的情况
 * @author Lisa
 * @date 2018/9/18
 */

public class ToastUtils {

    private Toast mToast;
    private static ToastUtils mToastUtils;

    private ToastUtils(Context context) {
        mToast = Toast.makeText(context.getApplicationContext(), null, Toast.LENGTH_SHORT);
    }

    public static synchronized ToastUtils getInstanc(Context context) {
        if (null == mToastUtils) {
            mToastUtils = new ToastUtils(context);
        }
        return mToastUtils;
    }
    /**
     * 显示toast
     *
     * @param toastMsg
     */
    public void showToast(String toastMsg) {
        mToast.setDuration(Toast.LENGTH_LONG);
        mToast.setText(toastMsg);
        mToast.show();
    }

    /**
     * 显示toast
     *
     * @param toastMsg
     */
    public void showShortToast(String toastMsg) {
        mToast.setDuration(Toast.LENGTH_SHORT);
        mToast.setText(toastMsg);
        mToast.show();
    }

    /**
     * 显示toast
     *
     * @param toastMsg
     */
    public void showLongToast(String toastMsg) {
        mToast.setDuration(Toast.LENGTH_LONG);
        mToast.setText(toastMsg);
        mToast.show();
    }

    /**
     * 取消toast,在activity的destory方法中调用
     */
    public void destory() {
        if (null != mToast) {
            mToast.cancel();
            mToast = null;
        }
        mToastUtils = null;
    }

}

最后在Activity#onDestroy()调用销毁Toast

 ToastUtils.getInstanc(getActivity()).destory();
1.7、使用 Adapter 注意事项

如果使用了 ViewHolder 做缓存,在 getView()的方法中无论这项convertView的每个子控件是否需要设置属性(比如某个 TextView 设置的文本可能为 null,某个按钮的背景色为透明,某控件的颜色为透明等),都需 要为其显式设置属性(Textview的文本为空也需要设置 setText(""),背景透明也需要 设置),否则在滑动的过程中,因为 adapter item 复用的原因,会出现内容的显示错乱。

二、UI与布局

2.1、布局
  • ViewGroup不得不多重嵌套时,RelativeLayout可有效降低嵌套数

    • measure、layout、draw耗费的总时间尽量控制在16ms以内。
    • Hierarchy Viewer 工具查看多余的ViewStetho似乎也可以看。
      • AndroidStudio3.1开始Layout Inspector替代了Hierarchy Viewer。不管怎么说我用Stetho看好了
  • 文本大小用sp,View大小用dp,文字大小不要小于12sp

  • 不要多次在子View和父View中一起设置背景造成过度绘制。不需要用的布局及时隐藏掉。

  • 学习用Merge\ViewStub来优化布局,尽可能减少UI层级

    • 优先用FrameLayout,然后再考虑LineayLayout\RelativeLayout.
  • 在需要时刻刷新某一区域的组件时,避免layout全局刷新

    • 具体看开发手册
2.2、用DialogFragment替代Dialog/AlertDialog

使对话框或浮层的生命周期能够随着Activity的生命周期走。

2.3、源文件统一用UTF-8进行编码
2.4、尽量不要使用 AnimationDrawable

三、进程、线程与消息通信

3.1、线程与线程池
  • 线程要由线程池提供
  • 线程池用ThreadPoolExecutor创建
  • 要给每条线程命名,方便回溯
  • 要设置线程存活时间setKeepAliveTime,尽早释放资源

四、文件与数据库

4.1、不要硬编码文件路径

/sdcard/storage....在项目中都不要这样直接写这样的路径。

 android.os.Environment#getExternalStorageDirectory() 
 android.os.Environment#getExternalStoragePublicDirectory()
 android.content.Context#getFilesDir()
 android.content.Context#getCacheDir
4.2、SharedPreserences只存放简单的数据类型

其他的考虑用文件或数据库

4.3、大数据写入数据库时,请使用事务或其他能够提高 I/O 效率的机制,保证执行速度。
4.4、多线程操作写入数据库时,需要使用事务,避免出现同步问题

五、BitmapDrawable 与动画

5.1、图片加载
  • 异步加载
  • 列表展示时做好图片缓存
  • png图片要用压缩工具压缩以减小包体积,tinyPng 、webp
    • 在AndroidStudio中选中要压缩的图片,右击选择convertToWebp
5.2、Bitmap使用
  • 用完及时recycle释放资源
  • 使用 ARGB_565 代替 ARGB_888可解决一定的OOM问题
5.3、如果为了节省包体积,可以在不影响UI效果的前提下,省略低密度图片。
5.4、动画
  • 页面退出时要关闭停止动画
    • onPause()\ onStop()中停止动画
  • 动画或其他异步任务结束时,在回调中要注意判断资源是否已被释放掉了,避免空指针
  • 动画执行结束要释放相关资源:View.clearAnimation()

anim.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation arg0) {
    //判断一下资源是否被释放了 
        if (v != null) {
         v.clearAnimation(); 
        }
    }
});

六、安全

6.1、IntentPendingIntent
  • 用于构造PendingIntentIntent要指定ComponentName或者Action
  • 用于构造PendingIntentIntent不可以是隐式的Intent
6.2、AndroidManifest
  • android:allowbackup 属性设置为 false,防止 adb backup 导出数据。
  • Receiver/Provider在毫无权限控制的情况下,不要将 android:export 设置为 true。
  • 内部使用的组件,将android:export 设置为 false。
6.3、应用上线注意事项:
  • 不要把敏感信息打印到日志中,线上版本要关闭调试接口
  • 确保把android:debuggable属性设置为false
6.4、加密
  • 秘钥不要硬编码到程序中
  • 使用 AES/DES/DESede 加密算法时,不要使用默认的加密模式 ECB,应显示指定使用 CBC 或 CFB 加密模式。
  • 不要用不安全的Hash算法(MD5、SHA-1)做加密,用SHA-256安全系数更高

七、其他

7.1、不要用System.out.println("")打印
7.2、Log要定义好Tag

相关文章

网友评论

      本文标题:2018-09-18 - Android开发手册

      本文链接:https://www.haomeiwen.com/subject/ushmnftx.html