志在指尖
用双手敲打未来

实现子线程更新UI

Android中线程按功用分的话,能够分为两个,一个是主线程(UI线程),其他的都是子线程
主线程不能执行那些耗时过长的代码或任务(执行耗时过长的代码会呈现应用未响应的提示),所以都是运用子线程来执行耗时过长的代码,比方说下载文件等任务
普通状况,子线程中执行过长的代码,都是需求停止更新UI操作。
但是Android中,为了避免平安,是不允许在子线程更新UI的,但是我们能够运用到Android官方给予的API来完成子线程更新UI的操作(实质上,这些API也是切换回了主线程来停止更新UI)
例子:点击一个按钮,过了1s后完成了下载任务,返回了数据,此数据会显现在界面上
详细解释:
点击按钮,之后开启一个子线程来模仿下载过程(线程休眠1s),之后任务执行终了会返回数据(一个String),运用返回的数据更新UI
新建一个办法,用来模仿下载任务
复制/**
*模仿下载
*/
fundownload():String{
Thread.sleep(1000)
return”thisisdata”
}
下面的运用6种方式和上面的模仿下载任务的办法,来完成上面例子的效果
1.Activity.runOnUiThread()
runOnUiThread是Activity中的办法,只要当前对象是Activity,就能够直接运用,假如当前的对象不是Activity,需求找到Activity对象,才干执行此办法
runOnUiThread办法的参数为一个Runnable接口,我运用的kotlin,所以有很多东西都是省略了
设置按钮的点击事情,点击按钮开启一个线程
复制btn_start.setOnClickListener{
thread{
valdata=download()
runOnUiThread({
//这里停止更新UI操作
tv_show.text=data
})
}
}
Java版
复制btn_start.setOnClickListener(newOnClickListener(){
newThread(newRunnable(){
Stringdata=download();
runOnUiThread(newRunnable(){
@Override
publicvoidrun(){
tv_show.setText(data);
}
})
}).start();
});
2.View.post()
post办法是View对象的办法,参数也是接纳一个runnable接口
这里我选用的view对象是需求停止更新textview的自身,当然也能够选用其他的View对象,只需是在当前Activity的对象都能够
复制btn_start.setOnClickListener{
thread{
valdata=download()
//选择当前Activity的View对象都能够
tv_show.post{
tv_show.text=data
}
}
}
3.View.PostDelayed()
此办法和上面的post办法相似,只是多一个参数,用来完成延迟更新UI的效果
复制btn_start.setOnClickListener{
thread{
valdata=download()
tv_show.postDelayed({
tv_show.text=data
},2000)
}
}
上面的代码完成的效果是点击按钮之后,过了3s后才会看到界面发作改动
4.Handler.post()
new一个Handler对象(全局变量)
复制privatevalhandler=Handler()
运用post办法更新UI,此post办法和之前的post办法一样,参数都是为Runnable接口
复制btn_start.setOnClickListener{
thread{
valdata=download()
handler.post{
tv_show.text=data
}
}
}
5.AsyncTask(引荐)
阐明
AsyncTask是一个笼统类,必需创立一个子类类继承它
这里引见一下关于AsyncTask的三个泛型参数和几个办法
泛型参数能够为恣意类型,为空的话运用Void
参数阐明
params参数泛型,doInBackground办法的参数
progress进度泛型,onProgressUpdate办法的参数
result结果泛型,onPostExecute办法的参数
笼统办法阐明:
办法名阐明
onPreExectute()此办法中,常常停止初始化操作,如进度条显现
doInBackground(Params…)此办法必需完成,
onProgressUpdate(Progress…)停止更新UI的操作
publishProgress(Progress…)在doInBackground办法中调用,调用此办法后会回调执行onProgressUpdate办法停止更新UI
onPostExcute(Result)任务完毕之后停止更新UI
简单来说,假如子类继承了AsyncTask,它的笼统办法的参数都会变成泛型对应的类型
例子
下面的代码是取自我的APP,简单地阐明一下AsyncTask<String,DownloadingItem,DownloadedItem>
我传入的是3个泛型参数分别为String,DownloadingItem,DownloadedItem,分别对应的params,progress和result泛型
这里我是依据本人的需求而两个类DownloadingItem和DownloadedItem,从下面的代码能够看到,笼统办法的参数变为了我们的泛型的类型
复制internalinnerclassDownloadingTask:AsyncTask<String,DownloadingItem,DownloadedItem>(){
overridefunonPreExecute(){
//一些初始化操作
}
overridefundoInBackground(varargparams:String?):DownloadedItem{
//params是一个参数数组,假如创立DownloadingTask对象只传入了一个参数,直接取下标为0的那个即可(需求转型)
//耗时操作(如下载操作),取得进度数据
//将新的进度数据传送到onProgressUpdate办法,更新UI
publishProgress(messageItem)
//任务执行终了,返回结果(回调onPostExecute办法)
}
overridefunonProgressUpdate(varargvalues:DownloadingItem?){
//这里运用最新的进度来停止相关UI的更新
//values是一个DownloadingItem数组,取末尾那个即为最新的进度数据
}
overridefunonPostExecute(result:DownloadedItem?){
//下载胜利提示或者是其他更新UI的操作
}
}
执行:
执行Task的时分需求在主线程(UI线程调用)
复制DownloadingTask().execute(“参数”)
批量下载:
复制//允许在同一时辰有5个任务正在执行,并且最多可以存储50个任务
privatevalexec=ThreadPoolExecutor(5,50,10,TimeUnit.SECONDS,LinkedBlockingQueue<Runnable>())
DownloadingTask().executeOnExecutor(exec,url)
6.Handler机制完成(中心)
其实,Handler机制是子进程更新UI的中心
我们上面的五种完成子进程更新UI的方式,都是基于Handler机制完成的
详细机制本文就不多说了,网上有许多的机制阐明,这里就只讲一下完成的步骤
Message中有几个属性,what,arg1,arg2,这三个都是接纳一个Int,所以,传送数据不是很友好,这里就不准备完成之前的例子效果了
what表示来源,arg1和arg2用来传送Int数据
1.重写Handler类中的handleMessage办法
普通都是规则好一个Int的常量,来表示what
复制privatevalhandler=object:Handler(){
overridefunhandleMessage(msg:Message?){
if(msg.what==1){
//来源为1,则
}
}
}
2.发送Message
复制valmsg=handler.obtainMessage()
//普通都是规则好一个Int的常量,来表示what
msg.what=1
//传送Int数据
msg.arg1=20
handler.sendMessage(msg)

未经允许不得转载:IT技术网站 » 实现子线程更新UI
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载