parent
b378d9e3f2
commit
3cc9b09055
@ -0,0 +1,157 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.task |
||||
|
||||
import android.os.Handler.Callback |
||||
import android.os.Looper |
||||
import com.arialyy.aria.core.inf.IThreadStateManager |
||||
import com.arialyy.aria.core.listener.IEventListener |
||||
import com.arialyy.aria.exception.AriaException |
||||
import timber.log.Timber |
||||
import java.util.concurrent.atomic.AtomicInteger |
||||
|
||||
class BlockManager( |
||||
val mListener: IEventListener, |
||||
val looper: Looper, |
||||
private val blockNum: Int, |
||||
val blockParentDir: String |
||||
) : IThreadStateManager { |
||||
private val blockList = mutableListOf<BlockState>() |
||||
private val canceledNum = AtomicInteger(0) // 已经取消的线程的数 |
||||
private val stoppedNum = AtomicInteger(0) // 已经停止的线程数 |
||||
|
||||
private val failedNum = AtomicInteger(0) // 失败的线程数 |
||||
|
||||
private val completedNum = AtomicInteger(0) // 完成的线程数 |
||||
|
||||
private var progress: Long = 0 //当前总进度 |
||||
|
||||
private val callback = Callback { msg -> |
||||
checkLooper() |
||||
when (msg.what) { |
||||
IThreadStateManager.STATE_STOP -> { |
||||
stoppedNum.getAndIncrement() |
||||
if (isStopped) { |
||||
quitLooper() |
||||
} |
||||
} |
||||
IThreadStateManager.STATE_CANCEL -> { |
||||
canceledNum.getAndIncrement() |
||||
if (isCanceled) { |
||||
quitLooper() |
||||
} |
||||
} |
||||
IThreadStateManager.STATE_FAIL -> { |
||||
failedNum.getAndIncrement() |
||||
if (hasFailedBlock()) { |
||||
val b = msg.data |
||||
mListener.onFail( |
||||
b.getBoolean(IThreadStateManager.DATA_RETRY, false), |
||||
b.getSerializable(IThreadStateManager.DATA_ERROR_INFO) as AriaException? |
||||
) |
||||
quitLooper() |
||||
} |
||||
} |
||||
IThreadStateManager.STATE_COMPLETE -> { |
||||
completedNum.getAndIncrement() |
||||
if (isCompleted) { |
||||
Timber.d("isComplete, completeNum = %s", completedNum) |
||||
if (mTaskRecord.isBlock || mTaskRecord.threadNum === 1) { |
||||
if (mergeFile()) { |
||||
mListener.onComplete() |
||||
} else { |
||||
mListener.onFail(false, null) |
||||
} |
||||
quitLooper() |
||||
break |
||||
} |
||||
mListener.onComplete() |
||||
quitLooper() |
||||
} |
||||
} |
||||
IThreadStateManager.STATE_RUNNING -> { |
||||
val b = msg.data |
||||
if (b != null) { |
||||
val len = b.getLong(IThreadStateManager.DATA_ADD_LEN, 0) |
||||
progress += len |
||||
} |
||||
} |
||||
IThreadStateManager.STATE_UPDATE_PROGRESS -> if (msg.obj == null) { |
||||
progress = updateBlockProgress() |
||||
} else if (msg.obj is Long) { |
||||
progress = msg.obj as Long |
||||
} |
||||
} |
||||
false |
||||
} |
||||
|
||||
/** |
||||
* 退出looper循环 |
||||
*/ |
||||
private fun quitLooper() { |
||||
looper.quit() |
||||
} |
||||
|
||||
fun addBlockState(state: BlockState) { |
||||
blockList.add(state) |
||||
} |
||||
|
||||
fun getBlockState(): BlockState { |
||||
return blockList.removeFirst() |
||||
} |
||||
|
||||
override fun hasFailedBlock(): Boolean { |
||||
Timber.d("isFailed, blockBum = ${blockNum}, completedNum = ${completedNum.get()}, ") |
||||
return failedNum.get() != 0 |
||||
} |
||||
|
||||
override fun isCompleted(): Boolean { |
||||
// Timber.d("isCompleted, blockBum = ${blockNum}, completedNum = ${completedNum.get()}, ") |
||||
return completedNum.get() == blockNum |
||||
} |
||||
|
||||
override fun getCurrentProgress(): Long { |
||||
return progress |
||||
} |
||||
|
||||
override fun updateCurrentProgress(currentProgress: Long) { |
||||
progress = currentProgress |
||||
} |
||||
|
||||
/** |
||||
* 所有子线程是否都已经停止 |
||||
*/ |
||||
override fun isStopped(): Boolean { |
||||
// Timber.d("isStopped, blockBum = ${blockNum}, stoppedNum = ${stoppedNum.get()}, completedNum = ${completedNum.get()}, failedNum = ${failedNum.get()}") |
||||
return stoppedNum.get() + completedNum.get() + failedNum.get() == blockNum |
||||
} |
||||
|
||||
override fun isCanceled(): Boolean { |
||||
// Timber.d("isStopped, blockBum = ${blockNum}, canceledNum = $canceledNum") |
||||
return canceledNum.get() == blockNum |
||||
} |
||||
|
||||
override fun getHandlerCallback(): Callback { |
||||
return callback |
||||
} |
||||
|
||||
private fun mergeFile(): Boolean { |
||||
if (blockNum == 1){ |
||||
|
||||
return true |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.task |
||||
|
||||
class BlockState(val blockId: Int, val blockPath: String) { |
||||
|
||||
companion object { |
||||
/** |
||||
* dir/.fileName.blockId |
||||
*/ |
||||
const val BLOCK_PATH = "%s/.%s.%d" |
||||
|
||||
const val BLOCK_SIZE = 1024 * 1024 * 5 |
||||
} |
||||
|
||||
var curProgress: Long = 0 |
||||
} |
Loading…
Reference in new issue