学习笔记(一)

对多线程的认识

创建线程的方法

继承Thread和实现Runnable。用Runnable接口创建的线程可以处理同一资源,而用Thread类创建的线程则各自独立处理,各自拥有自己的资源。

线程池。在执行大量异步任务时提高性能

AsyncTask。基于线程池和Handler的。调用execute()方法启动异步,

rxJava

// HandlerThread是集成了Looper和MessageQueue的线程,使用方法和普通线程一样

// IntentService是Service和HandlerThread的结合,使用HandlerThread来处理后台任务

线程池的分类

newCacheThreadPool

newFixThreadPool

newSingleTheadExecutor

newScheduleThreadPool

线程安全

使用原子类

synchronized。wait,notify,notityAll。wait与锁的机制配套实现,wait函数必须在有关键字synchronized修饰的同步块中使用。

Lock

volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性。当变量被多个线程使用时,使用volatile修饰,这样可以保证变量可见。

线程同步

sleep。使一个正在运行的线程处于睡眠状态,

wait,notify,notityAll。使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁。唤醒一个处于等待状态的线程。唤醒所有处于等待状态的线程

线程间的通信方式

AsyncTask机制

Handler机制

rxJava

handler机制

handler通过sendMessage或post方法,将message插入到MessageQueue中。Looper循环地从MessageQueue中查询Message,如果时间到就从MessageQueue中取出Message并交给相应的handler处理。MessageQueue并非队列而是链表,插入Message时,会把时间较前的Message插入到前面位置。

Bitmap的处理

在加载图片时先进行边界压缩。新建Option,先读出图片的宽和高,再根据所需的宽和高来设置option的缩放比,再把图片加载出来。

在上传图片到服务器前对图片进行压缩,使用Bitmap的compress方法。

加载图片时可以使用BitmapFactory的decodeStream方法,因为使用其他方法加载图片都会用到createBitmap方法,这个方法会用到较多内存。

图片缓存处理,三级缓存。

对四个组件的认识

Activity 的四种启动模式

1、standard模式。每次启动activity时,都新建activity,并放入任务栈中。

2、singleTop模式。启动activity时,如果activity在任务栈顶,就调用activity的onNewIntent方法,如果不在栈顶,就新建activity并放入任务栈。

3、singleTask模式。启动activity时,如果activity在任务栈中,就把activity上的其他activity移出栈,同时调用activity的onNewIntent方法。如果activity不在任务栈中,就新建activity并放入任务栈。

4、singleInstance模式。启动activity时,会新建一个任务栈,将activity放入新的任务栈中。并保证新的任务栈只有一个activity。

Service的两种启动方式

startService 启动的服务:不能进行通信。service会一直无限期运行下去,使用stopService停止服务;

bindService 启动的服务:可以进行通信。使用unbindService停止服务,绑定到serivce上的组件可以是一个或多个(Activity),组件被销毁时,会解除与Service的绑定,也可以调用unbindService来解除绑定;

broadcaseReceiver用于系统或app发出的广播事件。broadcastReceiver注册方式有两种,在androidmainfest中注册称为静态注册,在代码里注册的动态注册。静态注册后,app可以一直接收广播,动态注册时当activity或service被销毁时就不能接收广播。

contentPrivoder是内容提供者,在android中如果想将自己的数据提供给别的应用,那么只能通过contentPrivoder来实现。contentPrivoder是应用程序间共享数据的接口。

Android内存泄露及管理

内存溢出 out of memory:是指程序在申请内存时,没有足够的内存空间供其使用,出现OOM

内存泄露 memory leak:是指程序在申请内存后,无法释放已申请的内存空间

内存泄露

1、单例(主要原因还是因为一般情况下单例都是全局的,有时候会引用一些实际生命周期比较短的变量,导致其无法释放)

2、静态变量(同样也是因为生命周期比较长)

3、Handler内存泄露,非静态内部类会持有外部对象的引用。因为非静态内部类方法的调用需要依赖外部对象的创建。

4、匿名内部类(匿名内部类会引用外部类,导致无法释放,比如各种回调)

5、资源使用完未关闭(BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap)

6、线程,当线程没有执行完,就结束activity,会造成内存泄露

7、注册/反注册未成对使用(注册广播接受器、EventBus等,记得解绑。)

解决内存泄露

1、使用weakReference和solfReference。weakReference是当GC回收扫到这个对象时就会回收,solfReference在系统内存不足是会被回收。

2、handler使用时,在activity的onDestroy方法里清空messageQueue里的message和runnable。或者声名handler为静态内部类。

3、bitmap在读取图片时,可以先缩放再加载。在bitmap不使用时,recycle掉。

4、cursor和stream在等资源在使用完成时要关闭。

5、线程不再需要继续执行的时候要及时关闭。

6、将内部类、匿名内部类设置为静态。

7、记得反注册

检测内存泄露的工具:LeakCanary

APP优化

布局优化:尽量不要过于复杂的嵌套。可以使用

内存优化:参考内存泄露和内存溢出部分

图片优化:图片进行缩放的比例,不用的图片记得调用图片的recycle()方法

ANR

产生原因:

(1)5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).

(2)BroadcastReceiver在10s内无法结束

(3)Service 20s内无法结束(低概率)


解决方式:

(1)不要在主线程中做耗时的操作,而应放在子线程中来实现。如onCreate()和onResume()里尽可能少的去做创建操作。

(2)应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。

(3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。

(4)service是运行在主线程的,所以在service中做耗时操作,必须要放在子线程中。

常用的设置模式

单例模式

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

2、建造模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

3、代理模式

对用户进行权限管理,比如游客和登陆的用户都可以访问主界面,这时可以通过代理模式来分别对主界面进行操作。

4、观察者模式

一个对象发生改变时,所有依赖于它的对象自动做相应改变

5、工厂模式

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。例如:BitmapFactory

如何做屏幕自适应

宽高限定符适配:穷举市面上所有的Android手机的宽高像素值

动态修改density值:修改density值使得设备有相同的dp值,一般把屏幕宽度设置成360dp。 https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

你可能感兴趣的:(学习笔记(一))