方法一: view.post(Runnable action)

假如该方法是在子线程中

textView.post(new Runnable() {

@Override

public void run() {

textView.setText("更新textView");

//还可以更新其他的控件

imageView.setBackgroundResource(R.drawable.update);

}

});

这是view自带的方法,比较简单,如果你的子线程里可以得到要更新的view的话,可以用此方法进行更新。

view还有一个方法view.postDelayed(Runnable action, long delayMillis)用来延迟发送。

方法二: activity.runOnUiThread(Runnable action)

假如该方法是在子线程中

注意:context 对象要是 主线程中的MainActivity,这样强转才可以。

public void updateUI(final Context context) {

((MainActivity) context).runOnUiThread(new Runnable() {

@Override

public void run() {

//此时已在主线程中,可以更新UI了

}

});

}

如果没有上下文(context),试试下面的方法:

1.用view.getContext()可以得到上下文。

2.跳过context直接用new Activity().runOnUiThread(Runnable action)来切换到主线程。

方法三: Handler机制

首先在主线程中定义Handler,Handler mainHandler = new Handler();(必须要在主线程中定义才能操作主线程,如果想在其他地方定义声明时要这样写Handler mainHandler = new Handler(Looper.getMainLooper()),来获取主线程的 Looper 和 Queue )

获取到 Handler 后就很简单了,用handler.post(Runnable r)方法把消息处理放在该 handler 依附的消息队列中(也就是主线程消息队列)。

(1):假如该方法是在子线程中

Handler mainHandler = new Handler(Looper.getMainLooper());

mainHandler.post(new Runnable() {

@Override

public void run() {

//已在主线程中,可以更新UI

}

});

Handler还有下面的方法:

1.postAtTime(Runnable r, long uptimeMillis); //在某一时刻发送消息

2.postAtDelayed(Runnable r, long delayMillis); //延迟delayMillis毫秒再发送消息

(2): 假设在主线程中

Handler myHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch(msg.what) {

case 0:

//更新UI等

break;

case 1:

//更新UI等

break;

default:

break;

}

}

}

之后可以把 mainHandler 当做参数传递在各个类之间,当需要更新UI时,可以调用sendMessage一系列方法来执行handleMessage里的操作。

假设现在在子线程了

/**

*获取消息,尽量用obtainMessage()方法,查看源码发现,该方法节省内存。

*不提倡用Messenger msg=new Messenger()这种方法,每次都去创建一个对象,肯定不节省内存啦!

*至于为什么该方法还存在,估计还是有存在的必要吧。(留作以后深入研究)

*/

Message msg = myHandler.obtainMessage();

msg.what = 0; //消息标识

myHandler.sendMessage(msg); //发送消息

如上代码,只是发送了个消息标识,并没有传其他参数。

如果想传递参数,可以这样:

msg.what = 1;  //消息标识

msg.arg1=2;   //存放整形数据,如果携带数据简单,优先使用arg1和arg2,比Bundle更节省内存。

msg.arg2=3;   //存放整形数据

Bundle bundle=new Bundle();

bundle.putString("dd","adfasd");

bundle.putInt("love",5);

msg.setData(bundle);

msg.obj=bundle;   //用来存放Object类型的任意对象

myHandler.sendMessage(msg); //发送消息

总结: msg.obj它的功能比较强大一下,至于它和利用Bundle传递数据,那个会效率高一些,更节省内存一些。个人认为:从传递数据的复杂程度看,由简单到复杂依次使用,arg1, setData(), obj。会比较好一些。

当然可以用简化方法sendEmptyMessage(int what)来减少不必要的代码,这样写:

myHandler.sendEmptyMessage(0); //其实内部实现还是和上面一样

1

发送消息的其他方法有:

endEmptyMessageAtTime(int what, long uptimeMillis); //定时发送空消息

sendEmptyMessageDelayed(int what, long delayMillis); //延时发送空消息

sendMessageAtTime(Message msg, long uptimeMillis); //定时发送消息

sendMessageDelayed(Message msg, long delayMillis); //延时发送消息

sendMessageAtFrontOfQueue(Message msg); //最先处理消息(慎用)

方法四: 使用AsyncTask

/**

* 该类中方法的执行顺序依次为:onPreExecute, doInBackground, onPostExecute

*/

private class MyAsyncTask extends AsyncTask {

/**

* 主线程中执行

* 在execute()被调用后首先执行

* 一般用来在执行后台任务前对UI做一些标记

*/

@Override

protected void onPreExecute() {

super.onPreExecute();

System.out.println("MyAsyncTask.onPreExecute");

}

/**

* 子线程中执行,执行一些耗时操作,关键方法

* 在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。

*/

@Override

protected String doInBackground(String... params) {

System.out.println("MyAsyncTask.doInBackground");

//只是模拟了耗时操作

int count = 0;

for (int i = 0; i < 10; i++) {

try {

count++;

publishProgress((count % 100) * 10);

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// publishProgress((int) ((count / (float) total) * 100));

return "耗时操作执行完毕";

}

/**

* 主线程中执行

* 在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件中

*/

@Override

protected void onProgressUpdate(Integer... values) {

super.onProgressUpdate(values);

progressBar.setProgress(values[0]);

textView.setText("loading..." + values[0] + "%");

System.out.println("MyAsyncTask.onProgressUpdate");

}

/**

* 在主线程中,当后台操作结束时,此方法将会被调用

* 计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

*/

@Override

protected void onPostExecute(String aVoid) {

super.onPostExecute(aVoid);

System.out.println("MyAsyncTask.onPostExecute aVoid=" + aVoid);

textView.setText(aVoid);

}

/**

* 主线程中执行

* 当异步任务取消后的,会回调该函数。在该方法内可以更新UI

*/

@Override

protected void onCancelled() {

super.onCancelled();

System.out.println("MyAsyncTask.onCancelled");

progressBar.setProgress(0);

textView.setText("0");

}

@Override

protected void onCancelled(String s) {

super.onCancelled(s);

}

}

注意:doInBackground方法是在子线程中,所以,我们在这个方法里面执行耗时操作。同时,由于其返回结果会传递到onPostExecute方法中,而onPostExecute方法工作在UI线程,这样我们就在这个方法里面更新ui,达到了异步更新ui的目的。

对于android的异步加载数据及更新ui,我们不仅可以选择AsyncTask异步任务,还可以选择许多开源的网络框架,如: 点击进入了解更多 xUtils3,AsyncHttpClient,Okhttp,Volley,…,

这些优秀的网络框架让我们异步更新ui变得非常简单,而且,效率和性能也非常高。当然这些网络框架绝不仅仅就这么个功能,异步更新UI这只是他们的冰山一角!

文章来源: www.oschina.net,作者:chenhongjiang,版权归原作者所有,如需转载,请联系作者。

原文链接:https://my.oschina.net/hongjiang/blog/3168221

android开发返回主线程,安卓回到主线程的几种方式相关推荐

  1. Android创建子线程和回调主线程的几种方式

    一. 创建子线程//通过继承threadpublic class JNThread1 extends Thread {public JNThread1(String name){super(name) ...

  2. android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...

    只要参与过安卓项目开发一两年的朋友们应该清楚,为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行,如果贸然在子线程做了UI操作结果会怎样?我们随便写下了如下测试代码. 不出意外的话,代码执 ...

  3. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

  4. [Android] 任意时刻从子线程切换到主线程的实现

    [Android] 任意时刻从子线程切换到主线程的实现 - Android移动开发技术文章_手机开发 - 红黑联盟 转载于:https://www.cnblogs.com/melons/p/57919 ...

  5. 【Android】子线程切回主线程的方法梳理

    [Android]子线程切回主线程的方法梳理 view.post(Runnable action) textView.post(() -> {textView.setText("更新t ...

  6. 【EventBus】事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )

    文章目录 前言 一.根据不同的线程模式进行不同的线程切换操作 二.完整代码示例 前言 发布线程发布事件之后 , 消息中心需要转发这些事件 , 并执行相应的订阅方法 ; 在转发的过程中 , 需要针对订阅 ...

  7. DLL内线程同步主线程研究(子线程代码放到主线程执行)

    DLL内线程同步主线程研究(子线程代码放到主线程执行) 我们在实际项目中经常会用到多线程编程,比如Socket编程等,在创建的线程内同步主线程一般使用Synchronize方法实现子线程操作放到主线程 ...

  8. 关于handler子线程通知主线程的几种写法

    以下是我一年实习中总结的几种子线程中通知主线程的方法 runOnUiThread 注意:context 对象要是 主线程中的Activity,这样强转才可以. runOnUiThread(new Ru ...

  9. C#多线程下, 子线程如何让主线程执行方法

    C#多线程下, 子线程如何让主线程执行方法 重现一下当时我的需求: 我开了多个线程, 来监视一个变量, 然后去执行一些方法. 看起来没什么毛病, 但是运行起来会报错 此对象被其他线程占用 一开始想着可 ...

最新文章

  1. java8 同步队列_秋招之路8:JAVA锁体系和AQS抽象队列同步器
  2. Java 并发编程笔记(一)
  3. Java中带有NetSuite数据实体的对象关系映射(ORM)
  4. MySQL Date and Time Functions(日期和时间)
  5. Spring3 报org.aopalliance.intercept.MethodInterceptor问题解决方法
  6. ssms .net3.5_SSMS 18.4中SQL Server查询存储选项
  7. java发送html附件_Java发送邮件(图片、附件、HTML)
  8. 第七届开源操作系统年度技术会议(OS2ATC)盛大开幕,从编译器到软件定义卫星精彩议题大曝光!...
  9. 自己做的一个水印生成类
  10. 分享Silverlight/WPF/Windows Phone一周学习导读(12月27日-1月2日)
  11. 不用编程实现PLC之间通讯-西门子与三菱以太网实时通讯
  12. 词法分析与词性标注学习之笔记(二)----词性标注
  13. [XMAN2018排位赛]AutoKey
  14. 嘉兴 机器人仓库 菜鸟_菜鸟在嘉兴推出全新智能仓 在“双11”启用超级机器人仓群...
  15. 【Python常见 面试题】实现三位数的水仙花数,Python入门案例学习
  16. 解压war包和重新压缩war包
  17. 文档转换 云服务器,文档转换服务
  18. 触控面板 开发_长信科技研发内核不断升级 成触控显示一体化领军企业
  19. #今日论文推荐#CVPR 2022 | 只需要一组预训练参数,所有恶劣天气一次解决
  20. 这或许是全网最全时间序列特征工程构造的文章了

热门文章

  1. matlab如何在地图上绘制圆圈
  2. 曲面等值线上任意一点的曲率公式
  3. CSDN年度总结:相遇,相识,相认,相知(菜鸟的CSDN进阶之路)
  4. windows 10删除指纹解锁
  5. 华为云物联网平台微信小程序开发教程2.0【完整详细教程】
  6. 一本书掌握自动内存回收的机制《垃圾回收的算法与实现》(好书分享更新中)
  7. Win键相关的快捷键
  8. 谈谈100层会碎的两颗玻璃球
  9. 在 Java 文件中播放声效
  10. [leetcode]排列组合子集(python)