如何在android一条单独线程,更新ui ?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在android一条单独线程,更新ui ?相关的知识,希望对你有一定的参考价值。
如何在android一条单独线程,更新ui ?
方法有两种:通过继承Thread类,重写Run方法来实现
通过继承接口Runnable实现多线程
主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
Handler的主要作用:主要用于异步消息的处理
Handler的运行过程:
当(子线程)发出一个消息之后,首先进入一个(主线程的)消息队列,发送消息的函数即刻返回,而在主线程中的Handler逐个的在消息队列中将消息取出,然后对消息进行处理。这样就实现了跨线程的UI更新(实际上还是在主线程中完成的)。
这种机制通常用来处理相对耗时比较长的操作,如访问网络比较耗时的操作,读取文大文件,比较耗时的操作处理等。
在大白话一点的介绍它的运行过程:
启动应用时Android开启一个主线程
(也就是UI线程) , 如果此时需要一个耗时的操作,例如:
联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象(这也就是你在主线程中直接访问网络时会提示你异常的原因,如我们上篇文章所述Android主线程不能访问网络异常解决办法)。 参考技术A 用AsyncTask异步类吧,我给你贴个DEMO
class AsyncLoader extends AsyncTask<Integer, Integer, Integer>
int index;
public AsyncLoader(int index)
//下面是显示用正在加载中的DIALOG联网布局引用的代码
// this.index = index;
//dialog = new AlertDialog.Builder(activity).show();
// dialog.setContentView(infoUtil.getDialogProgressView());
@Override
//这步被用于执行较长时间的后台计算。异步任务的参数也被传到这步。计算的结果必须在这步//返回,将传回到上一步。在执行过程中可以调用publishProgress(Progress...)来更新任务的进//度。在执行完onPreExecute() 方法后执行
protected Integer doInBackground(Integer... params)
//这个事获取服务器数据的方法
getData(index);
return 1;
@Override
//异步类的静态方法在UI线程上调用任务后立即执行。这步通常被用于设置任务,例如在用户界//面显示一个进度条。
protected void onPreExecute()
super.onPreExecute();
@Override
//当后台计算结束时,调用 UI线程。后台计算结果作为一个参数传递到这步,也就是//doInBackground(Integer... params)的结果
protected void onPostExecute(Integer result)
super.onPostExecute(result);
if (dialog != null && dialog.isShowing())
//这个是那个正在加载中的DIALOG对话框,消失以后开始执行更新UI
dialog.dismiss();
//这个事里面要更新的UI的操作
updateUI(index);
@Override
//后台调用UI线程,执行时间不确定
protected void onProgressUpdate(Integer... values)
super.onProgressUpdate(values);
@Override
protected void onCancelled()
super.onCancelled();
参考技术B Android不允许在其他子线程更新主线程的UI,只能在主线程中进行UI操作。除了SurfaceView特殊,可以在线程中更新,否则其他UI操作只能在主线程中进行。 参考技术C android中非UI线程是不能对UI进行操作的,你可以在单独线程执行耗时操作,然后通过Handler去更新UI。或者你可以使用AsyncTask。 参考技术D android中非UI线程是不能对UI进行操作的,你可以在单独线程执行耗时操作,然后通过Handler去更新UI。或者你可以使用AsyncTask。本回答被提问者和网友采纳
如何使用 Android 处理程序更新 UI 线程中的 TextView?
【中文标题】如何使用 Android 处理程序更新 UI 线程中的 TextView?【英文标题】:How to use an Android Handler to update a TextView in the UI Thread? 【发布时间】:2013-03-19 02:55:43 【问题描述】:我想从 Android 应用程序中的异步任务更新TextView
。使用Handler
执行此操作的最简单方法是什么?
有一些类似的问题,例如:Android update TextView with Handler,但是例子很复杂,似乎没有答案。
【问题讨论】:
【参考方案1】:有几种方法可以更新您的 UI 并从 UI 线程外部修改 View
,例如 TextView
。 Handler
只是一种方法。
这是一个示例,它允许单个Handler
响应各种类型的请求。
在类级别定义一个简单的Handler
:
private final static int DO_UPDATE_TEXT = 0;
private final static int DO_THAT = 1;
private final Handler myHandler = new Handler()
public void handleMessage(Message msg)
final int what = msg.what;
switch(what)
case DO_UPDATE_TEXT: doUpdate(); break;
case DO_THAT: doThat(); break;
;
在您的一个函数中更新 UI,该函数现在位于 UI 线程上:
private void doUpdate()
myTextView.setText("I've been updated.");
在您的异步任务中,向Handler
发送消息。有几种方法可以做到这一点。这可能是最简单的:
myHandler.sendEmptyMessage(DO_UPDATE_TEXT);
【讨论】:
Handler class should be static otherwise memory leaks might occur
警告呢?
请找到 Blog post 和这个答案 (***.com/questions/11407943/…) 以了解更多信息
我在这里推荐 weakHandler 以避免泄漏。 github.com/badoo/android-weak-handler【参考方案2】:
您也可以通过这种方式从后台线程更新 UI 线程:
Handler handler = new Handler(); // write in onCreate function
//below piece of code is written in function of class that extends from AsyncTask
handler.post(new Runnable()
@Override
public void run()
textView.setText(stringBuilder);
);
【讨论】:
以上是关于如何在android一条单独线程,更新ui ?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Android AsyncTask 更改活动 UI?
如何在Android开发中用AsyncTask异步更新UI界面