Android中常见的一些问题bug

1. Android ScrollView嵌套RecyclerView的冲突解决或者显示不全的问题

  1. ScrollView替换成普通布局,然后RecycleView用的BaseMultiItemQuickAdapter多布局来写,也就是整个页面只有一个RecycleView,用来取代ScrollView,但是这样比较复杂。
  2. 对ScrollView和RecycleView的isNestedScrollingEnabled的值设置成false
scrollViewTrans.isNestedScrollingEnabled = false
RecyclerView.isNestedScrollingEnabled = false
  1. 如果方法2不行, 用NestedScrollView替换ScrollView,保证你的recycleView滑动起来刷刷的
  • Support库引用方式
android.support.v4.widget.NestedScrollView
  • AndroidX引用方式
androidx.core.widget.NestedScrollView

2. SharedPreferences文件的存储位置

  1. SharedPreferences是android的一种数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。
    大多数机器其存储位置在/data/data/<包名>/shared_prefs目录下
    少部分机器会将其存储在/dbdata/databases/<包名>/shared_prefs目录下
    大部分都写的是存储在/data/data/<包名>/shared_prefs目录下,需要查看该文件的朋友如果找不到的话,可以在/dbdata/databases/<包名>/shared_prefs目录下进行查找

3. WebView中使用setBuiltInZoomControls进行缩放并destroy webview时崩溃

  • 问题现象

webview使用settings.setBuiltInZoomControls(true) 进行控制缩放。由于某些原因需要在该activity的onDestroy方法里面调用webView.destroy()。当进入该webview并且进行缩放操作时,退出该activity程序crash

Uncaught Exception in main[1]
java.lang.IllegalArgumentException: Receiver not registered: 
android.widget.ZoomButtonsController$1@683fa71
at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:878)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1279)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:601)
at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:404)
at android.widget.ZoomButtonsController$2.handleMessage(ZoomButtonsController.java:178)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7237)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
(LogExceptionHandler.java:29)
settings代码如下:
settings = previewWebview.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setBuiltInZoomControls(true);
settings.setDefaultTextEncodingName("gbk");
  • 在activity的onDestroy方法中进行的操作:
@Override
protected void onDestroy() {
      super.onDestroy();
      previewWebview.destroy();
}
  • 解决方案
  1. 方法一 :
/**
 * 防止webview缩放时退出崩溃。
 */
@Override
public void finish() {
    ViewGroup view = (ViewGroup) getWindow().getDecorView();
    view.removeAllViews();
    super.finish();
}
  1. 在Activity的onDestroy里面加上 :
webview.setVisibility(View.GONE);

把WebView设置为GONE就可以了.

4. Android性能优化方面

  1. 布局优化
    • 减少布局文件的层级(测量/布局/绘制的时间减少):可以使用来减少嵌套,RelativeLayout从而达到减少层级的目的,另外在相同层级的情况下使LinearLayout(相比于RelativeLayout更高效)
    • 使用include标签复用,merge标签降低层级,ViewStub来实现懒加载,另外补充一个Space可以用来占位
  2. 绘制优化
    • 主要是避免执行大量的操作
    • 不要创建新的局部对象,因为onDraw可能会被频繁调用,会在一瞬间产生大量的临时对象,会导致占用过多内存,系统更加频繁的gc,降低执行效率
    • 不要做耗时的任务
内存泄漏优化
  1. 单例造成的内存泄漏
    优先使用Application的Context,如需使用Activity的Context,可以在传入Context时使用弱引用进行封装,然后,在使用到的地方从弱引用中获取Context,如果获取不到,则直接return即可。
  2. 类的静态变量持有大数据对象
    尽量避免使用静态变量存储数据,特别是大数据对象,建议使用数据库存储
  3. 非静态内部类的静态实例
    该实例的生命周期和应用一样长,这就导致该静态实例一直持有该Activity的引用,Activity的内存资源不能正常回收。此时,我们可以将该内部类设为静态内部类或将该内部类抽取出来封装成一个单例,如果需要使用Context,尽量使用Application Context,如果需要使用Activity Context,就记得用完后置空让GC可以回收,否则还是会内存泄漏
  4. Handler临时性内存泄漏
  • 使用一个静态Handler内部类,然后对Handler持有的对象(一般是Activity)使用弱引用,这样在回收时,也可以回收Handler持有的对象。
  • 在Activity的Destroy或者Stop时,应该移除消息队列中的消息,避免Looper线程的消息队列中有待处理的消息需要处理
  1. WebView
    WebView都存在内存泄漏的问题,在应用中只要使用一次WebView,内存就不会被释放掉。我们可以为WebView开启一个独立的进程,使用AIDL与应用的主进程进行通信,WebView所在的进程可以根据业务的需要选择合适的时机进行销毁,达到正常释放内存的目的

你可能感兴趣的:(Android中常见的一些问题bug)