Android编程易错问题总结

1.在P版本,如果不在Intent添加FLAG_ACTIVITY_NEW_TASK,将无法通过非Activity的Context启动一个Activity,并且会抛异常。

比如在Service中启动Activity,如果Intent不添加FLAG_ACTIVITY_NEW_TASK,就会抛异常

2. Android 6.0(api 23)已经不支持HttpClient了,使用apache-http客户端会报错

A.需要在应用的AndroidManifest.xml文件中添加:

B.不再使用apache-http客户端

使用HttpURLConnection或OKhttp替代apache-http

3.全屏透明时设置Activity方向限制,targetSdkVersion>=27

当targetSdkVersion<=26(O)时,全屏透明Activity设置screenOrientation方向属性没有影响。

当targetSdkVersion=27时,全屏透明Activity设置screenOrientation方向属性就会抛出异常。java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation。

当targetSdkVersion=27时,检查全屏透明Activity布局,做出适当调整或替代。然而这个bug只有在8.0中有,8.1中已经修复。

4. 允许安装未知来源应用

针对8.0 的应用需要在 AndroidManifest.xml 中声明 REQUEST_INSTALL_PACKAGES 权限,否则将无法进行应用内升级。

解决办法:manifest清单添加权限:

动态申请权限,然后回调处理安装

5.TextureView与SurfaceView用法区别(播放器缩放、移动)

SurfaceView和TextureView均继承于android.view.View,两者都能在独立的线程中绘制和渲染,在专用的GPU线程中大大提高渲染的性能。

区别:TextureView可缩放,移动,可加动画;SurfaceView是独立的一层View,更像是独立的一个Window,不能加上动画、平移、缩放,两个SurfaceView不能相互覆盖。由于SurfaceView的双缓冲功能,可以使画面更加流畅的运行,因此更适合视频播放器应用的开发

6.Android7.0调用系统相机崩溃

调用系统相机时出现android.os.FileUriExposedException这个错误提示,在application下加入标签声明FileProvider,获取图片路径的时候需要使用FileProvider.getUriForFile()方法代替Uri.fromFile()方法

7.Android Studio运行出现项目 错误:非法字符:“\ufeff”

主要原因是: eclipse可以自动把UTF-8+BOM文件转为普通的UTF-8文件,但Android Studio需要重新转换一下编码

解决方法:

将编码格式UTF-8+BOM文件转为普通的UTF-8文件。

在Android Studio右下角,将编码改为GBK,再转为UTF-8,可以解决。

8.List集合中contains方法总是返回false.

在用ArrayList类的caontains方法是遇到了问题,写了一个存放User类的ArrayList  但在调用list.contains(user)时总是返回false,去看了下ArrayList的源码发现,里面直接比对的对象,如下图:


正确比较方法:

9.浮点数运算:

0.33+0.37+0.2=?  0.8999999999999999

答:public   static   double   add(double   v1,double   v2){

    BigDecimal b1   =   new   BigDecimal(Double.toString(v1));

    BigDecimal b2   =   new   BigDecimal(Double.toString(v2));

    return   b1.add(b2).doubleValue();

}

10.转义字符的问题

String fileName="20191111-20191230.mp4";

String[] str=fileName.split(".");

Log.i("yanfei",str[0]);

转义字符问题,split需要加\\

String fileName="20191111-20191230.mp4";

if(fileName.contains(".")){

String[] str=fileName.split("\\.");

Log.i("yanfei",str[0]);

}

转义字符问题,contains不需要加\\

11.关于Activity关闭后,出现弹窗崩溃的问题

Activity com.yyy.MainActivity  has leaked window android.widget.xxxxx@43e40d10 that was originally added here

错误简介:这种错误一般是指activity已经关了,但又去弹框(dialog),造成的错误。一般出现在退出activity时发生。

解决办法:退出activity时,注意修改activity结束与dialog消失的处理逻辑,保证activity结束前dialog先消失,可以在activity finish()之前将dialog dismiss()掉;

12.静态接口回调导致内存溢出

解决办法:需要在Activity的ondestory里将静态对象mOnPermissionListener释放掉

13.Handler使用导致的内存溢出:

当Handler中有延迟的的任务或是等待执行的任务队列过长,由于消息持有对Handler的引用,而Handler又持有对其外部类的潜在引用,这条引用关系会一直保持到消息得到处理,而导致了Activity无法被垃圾回收器回收,而导致了内存泄露

解决办法:

1.将 Handler 声明为静态内部类,因为静态内部类不会持有外部类的引用,所以不会导致外部类实例出现内存泄露,如果需要有场景需要访问外部 Activity 对象,可以在 Handler 中添加对外部 Activity 的弱引用


2.也可以在生命周期结束的onDestroy方法中移除消息


14.静态Toast导致的内存泄漏

static修饰的toast对象,在show方法中这个对象同时对context持有了引用。toast是static修饰的,意味着toast将不会从内存中消失,那么其持有的引用对象context将一直保持强引用,也不会在内存中消失。如果传个占用大内存的Activity的context进来,那么将会导致大量的内存泄漏。

解决方法:

将context改为context.getApplicationContext(),由于ApplicationContext是一个全局的context,会在app运行期间一直存在,就不存在内存泄露的问题了

15.单例模式造成的内存泄漏,传入的Context如果是Activity或Service的实例,就会造成内存泄漏


解决方法:传入application的上下文实例

你可能感兴趣的:(Android编程易错问题总结)