学习视频来源:
- https://www.bilibili.com/video/BV1sJ41127EMlongway777
- 模型图来源也全截取来自该Up的视频
- 补充资料传送门
- workmanager在子线程中同步执行
使用场景
- 防止后台滥用等等问题,对之前的后台任务方法进行体系化的封装
- 工作状态信息的观察,livedata,并且workmanager是个单例
- 添加依赖
- 左上角的小灯,放那个红波纹上报那个提示,worker实现两参数的主构造器
样例一:
1. 建立work类
class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
val TAG="Worker"override fun doWork(): Result {
Log.d(TAG, "doWork: started")Thread.sleep(3000)Log.d(TAG, "doWork: finined")return Result.success()}}
2. MainAC进行调用
class MainActivity : AppCompatActivity() {
//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
//1.内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().build()//2.加入队列workManager.enqueue(workRequest)}}
}
- 进行结果查看,ok没问题
3. 引入约束条件
- 官网传送门
- 修改MainAC,加入限定条件,断网测试
class MainActivity : AppCompatActivity() {
//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
//3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.build()//2. 加入队列workManager.enqueue(workRequest)}}
}
- 测试成功,断网后不执行,连点了四次。连上网后搞定运行。任务调入进去后,结束Activity,依然会执行。在最近使用将其划掉。依然可以【经过测试后发现意思是说:被后台杀死后,再次进入程序,任然会执行workmanager中的做法 推迟完成 。】
3. Activity传递数据给WorkManager[键值对]
- MainActivity
class MainActivity : AppCompatActivity() {
companion object{
const val INPUT_DATA_KEY="input_data_key"const val WORK_A_NAME="Work A"}//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
//3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to WORK_A_NAME))//5. 传入数据一个pairs对象 键值对.build()//2. 加入队列workManager.enqueue(workRequest)}}
}
- 修改worker类
class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
val TAG="Worker"override fun doWork(): Result {
val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(3000)Log.d(TAG, "doWork: $name finined")return Result.success()}}
- 输出成功结果
4. 既然可以传递进去,也可以传递出来
- Work类增设回调
class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
val TAG="Worker"override fun doWork(): Result {
val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(3000)Log.d(TAG, "doWork: $name finined")//增设返回数据return Result.success(workDataOf(OUTPUT_DATA_KEY to "$name output"))}
}
- Main添加观察者模式
class MainActivity : AppCompatActivity() {
companion object{
const val INPUT_DATA_KEY="input_data_key"const val OUTPUT_DATA_KEY="output_data_key"const val WORK_A_NAME="Work A"}val TAG="MainAC"//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
//3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to WORK_A_NAME))//5. 传入数据一个pairs对象 键值对.build()//2. 加入队列workManager.enqueue(workRequest)//6. 添加workmanager观察机制 通过请求自带的idworkManager.getWorkInfoByIdLiveData(workRequest.id).observe(this, Observer {
Log.d(TAG, "onCreate: $it.state")//会依次有ENQUEUED RUNNING SUCCEEDED三种状态if (it.state == WorkInfo.State.SUCCEEDED) {
Log.d(TAG, "onCreate: ${
it.outputData.getString(OUTPUT_DATA_KEY)}")}})}}
}
- 观察成功
5. 工作的可串接性----sharepreference测试存活
- 抽取约束与请求方法 传入键值对名
- 以sharepreference做测试
MainAC - 测试发现重启任然没问题,倘若某个work执行到一半,再次启动后会这个work的start开始执行
//9. 牛逼 给sharedpreference写监听器
class MainActivity : AppCompatActivity(),SharedPreferences.OnSharedPreferenceChangeListener {
companion object{
const val INPUT_DATA_KEY="input_data_key"const val OUTPUT_DATA_KEY="output_data_key"const val WORK_A_NAME="Work A"const val WORK_B_NAME="Work B"const val SHARED_PREFERENCES_NAME="shp_name"}val TAG="MainAC"//首先获取单例private val workManager=WorkManager.getInstance(this)val binding by lazy {
ActivityMainBinding.inflate(layoutInflater) }override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)setContentView(binding.root)val sp=getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)sp.registerOnSharedPreferenceChangeListener(this)updateView()binding.button.setOnClickListener {
val workRequestA = createWork(WORK_A_NAME)val workRequestB = createWork(WORK_B_NAME)//2. 加入队列//8. 变更添加方式
// workManager.enqueue(workRequest) 先完成A,再执行BworkManager.beginWith(workRequestA).then(workRequestB).enqueue()//6. 添加workmanager观察机制 通过请求自带的id
// workManager.getWorkInfoByIdLiveData(workRequest.id).observe(this, Observer {
// Log.d(TAG, "onCreate: $it.state")//会依次有ENQUEUED RUNNING SUCCEEDED三种状态
// if (it.state == WorkInfo.State.SUCCEEDED) {
// Log.d(TAG, "onCreate: ${it.outputData.getString(OUTPUT_DATA_KEY)}")
// }
// })}}//刷新两个textviewprivate fun updateView(){
val sp=getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)binding.textViewA.text=sp.getInt(WORK_A_NAME,0).toString()binding.textViewB.text=sp.getInt(WORK_B_NAME,0).toString()}//7. 抽取约束与请求方法,传入键值对的值名-对应不同工作private fun createWork(name:String): OneTimeWorkRequest {
//3. 还可以添加约束条件val constrains = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest = OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to name))//5. 传入数据一个pairs对象 键值对.build()return workRequest}//实现回调方法override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
updateView()}
}
MyWorker
class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
val TAG="Worker"override fun doWork(): Result {
val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(6000)//以传递过来的name作为key的nameval sp=applicationContext.getSharedPreferences(SHARED_PREFERENCES_NAME,Context.MODE_PRIVATE)var number=sp.getInt(name,0)sp.edit().putInt(name,++number).apply()Log.d(TAG, "doWork: $name finined")//增设返回数据return Result.success(workDataOf(OUTPUT_DATA_KEY to "$name output"))}
}