Android---手动创建线程与GUI线程同步(三)
来源:互联网 发布:淘宝卖家的网址 编辑:程序博客网 时间:2024/06/10 00:19
Android---手动创建线程与GUI线程同步的第三种方法:
在GUI线程中调用runOnUiThread(Runnable runnable), 此时work Thread与GUI线程在同一个线程中, 所以,可以直接在work thread中更改GUI中的UI(此方法比较简单,适合work thread执行的任务比较简单,不耗进的任务。特别注意:当work thread 执行比较耗时的任务时,使用此方法会阻塞GUI线程,因为work thread 实际上也是在GUI线程中运行的)
1>布局与上二节都一样
1.1>效果如下:
1.2>代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.cxc.threadandhandler.MainActivity" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="work thread运行在GUI线程中" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/show_info_tv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="显示后台任务情况" /> <Button android:id="@+id/start_task_bt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Task" /> </LinearLayout></LinearLayout>
2>代码
2.1>MainActivity具体代码
package com.cxc.threadandhandler;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Looper;import android.os.Message;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {private static final String TAG = "com.cxc.threadandhandler.mainactivity";private TextView show_info_tv;private Button start_task_bt;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, "---main---" + Thread.currentThread().getId());Log.d(TAG, "---onCreate---");initViews();}private void initViews() {Log.d(TAG, "---initViews---");show_info_tv = (TextView) findViewById(R.id.show_info_tv);start_task_bt = (Button) findViewById(R.id.start_task_bt);start_task_bt.setOnClickListener(myButtonClickListener);}OnClickListener myButtonClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.start_task_bt:// to-do// 将耗时的操作移到子线程中Log.d(TAG, "---Start Task Button Click---");BackgroundThread backgroundThread = new BackgroundThread();runOnUiThread(backgroundThread);break;default:break;}}};class BackgroundThread implements Runnable {public BackgroundThread() {// TODO Auto-generated constructor stub}@Overridepublic void run() {// TODO Auto-generated method stubLog.d(TAG, "-----work thread ---" + Thread.currentThread().getId());backgroundThreadProcessing();}// 在后台执行一些处理的方法---耗时操作private void backgroundThreadProcessing() {// to-do 耗时操作Log.d(TAG, "-----work thread -backgroundThreadProcessing ---"+ Thread.currentThread().getId());for (int i = 0; i < 10; i++) {String text = show_info_tv.getText().toString();/* * 在GUI线程中调用runOnUiThread(Runnable runnable); 此时work Thread * 与GUI线程在同一个线程中, 所以,可以直接在work thread中更改GUI中的UI */text +=("*"+i);show_info_tv.setText(text );Log.d(TAG,"----:"+text);}}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}}
运行效果如下:
2.3>Log日志
06-01 20:42:26.879: D/com.cxc.threadandhandler.mainactivity(13839): ---main---106-01 20:42:26.879: D/com.cxc.threadandhandler.mainactivity(13839): ---onCreate---06-01 20:42:26.879: D/com.cxc.threadandhandler.mainactivity(13839): ---initViews---06-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): ---Start Task Button Click---06-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): -----work thread ---106-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): -----work thread -backgroundThreadProcessing ---106-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*006-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*106-01 20:42:33.499: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*206-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*306-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*406-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*4*506-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*4*5*606-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*4*5*6*706-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*4*5*6*7*806-01 20:42:33.504: D/com.cxc.threadandhandler.mainactivity(13839): ----:显示后台任务情况*0*1*2*3*4*5*6*7*8*9
3>分析从上面的Log可以看出work thread 确实运行在GUI线程中,所以可以直接在work thread 中直接更改GUI中的 UI控件,而不会引起" android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."异常
4>总结对于比较耗时的操作应该放到work thread 中运行,此时可以使用方法(二)来实现
0 0
- Android---手动创建线程与GUI线程同步(三)
- Android---手动创建线程与GUI线程同步(一)
- Android---手动创建线程与GUI线程同步(二)
- Java线程创建与同步
- 线程三、锁与同步
- 线程、创建线程、终止线程、线程同步
- 【进程线程与同步】5.3 创建与联接线程
- 三线程的互斥与同步
- MFC多线程与线程同步 (三)
- Java线程(三):同步与锁
- C++自学笔记之多线程的创建与线程同步
- Android 线程创建与销毁
- 线程同步与线程安全
- 线程同步与线程安全
- 线程的三种创建方式与线程池合用
- Android 线程同步与互斥
- 线程面试题之三:父子线程和子线程之间的同步与互斥
- 线程,同步与锁
- 跟着实例学习ZooKeeper的用法: 分布式锁
- 集合框架
- Linux系统学习第四章:文件压缩、打包与备份(一)压缩与打包:gzip、gcat、bzip2、bzcat、tar
- 跟着实例学习ZooKeeper的用法: Leader选举
- Asp.net MVC3 文本编辑器KindEditor使用及图片上传浏览
- Android---手动创建线程与GUI线程同步(三)
- 跟着实例学习ZooKeeper的用法: 缓存
- 一个数组保存了N个结构
- 链表基础知识
- android 滚动与设置接口方法
- centos下安装redis,并且设置自启动脚本
- Hibernate HelloWorld-06 单向多对一的映射关系
- 面试题29:数组中出现次数超过一半的数字
- 算法导论(二)堆排序