描述
项目中图书馆功能需要下载大量资源到本地设备,以节省流量。
文件不大,但是数量巨多!
封装完下载类后,出现了一个机型适配的问题,没想到是华为!
下载到一定数量文件后,会莫名其妙的停止下载,再次点击下载还会闪退!
通过查日志发现 OOM ,百思不得解
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory
详细报错
2019-03-26 14:12:31.608 28699-30821/com.***.*** E/AndroidRuntime: FATAL EXCEPTION: Thread-362
Process: com.***,***, PID: 28699
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:753)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:970)
at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1611)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:342)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:562)
at java.util.concurrent.ScheduledThreadPoolExecutor.execute(ScheduledThreadPoolExecutor.java:654)
at okhttp3.internal.http2.Http2Connection$ReaderRunnable.applyAndAckSettings(Http2Connection.java:738)
at okhttp3.internal.http2.Http2Connection$ReaderRunnable.settings(Http2Connection.java:710)
at okhttp3.internal.http2.Http2Reader.readSettings(Http2Reader.java:289)
at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.java:141)
at okhttp3.internal.http2.Http2Reader.readConnectionPreface(Http2Reader.java:80)
at okhttp3.internal.http2.Http2Connection$ReaderRunnable.execute(Http2Connection.java:607)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.lang.Thread.run(Thread.java:784)
2019-03-26 14:12:31.618 744-2650/? E/iMonitor: FaultDetect: DUMPTOOL_PRINTF return.
2019-03-26 14:12:31.619 744-2650/? E/iMonitor: FaultDetect: DUMPTOOL_PRINTF return.
2019-03-26 14:12:31.619 744-2650/? E/iMonitor: FaultDetect: DUMPTOOL_PRINTF return.
2019-03-26 14:12:31.619 744-2650/? E/iMonitor: FaultDetect: DUMPTOOL_PRINTF return.
解决
通过查询资料 《栈内存溢出: java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory》,发现是华为手机限制了线程的最大创建数量,而我这边下载处理时,OkHttpClient() 的创建也没有采用单例。
解决方案
OkHttpClient() 的创建采用单例,即可解决。
/**
* 开始下载文件
*/
fun load(params: Array<out String>) {
if (!NetworkUtil.isNetConnect(activity)) {
callback?.error(code = -2, msg = "网络错误,请重试~")
return
}
/**
* 改为 单例,否则个别华为手机 会 OOM
*/
// val httpClient = OkHttpClient()
call = httpClient.newCall(Request.Builder().url(params[0]).get().build())
注释掉每次下载都 OkHttpClient() 的代码,改为单例,就解决了。
/**
* 单例下载
*/
companion object {
val httpClient = OkHttpClient()
}