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
原创粉丝点击