如何在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,例如 TextViewHandler 只是一种方法。

这是一个示例,它允许单个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界面

Android编程:如何在子线程中更新TextView控件

如何使用 Android 处理程序更新 UI 线程中的 TextView?

在多线程中,子线程更新主线程ui都有哪些方法及注意点

Android中线程与线程,进程与进程之间如何通信?