Android---手动创建线程与GUI线程同步(二)

来源:互联网 发布:安卓版爱剪辑软件 编辑:程序博客网 时间:2024/06/10 17:58

本文在上一节Android---手动创建线程与GUI线程同步(一)的基础上来进行改进

上一节我们实现了在子线程中进行耗时工作,并通过Handler更改GUI中的UI,但是我们并不能通过它来获取后台工作线程返回数据。这时可以通过对上一节的代码进行改进。重写Handler的handleMessage方法,具体代码如下:

1>布局与上一节一致

代码如下:

<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="Thread用于耗时任务 + Handler用于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, "---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();Thread myThread = new Thread(backgroundThread);myThread.start();break;default:break;}}};class BackgroundThread implements Runnable {private MyHandler mMyHander = null;private HandlerThread mhandlerThread = null;public BackgroundThread() {// TODO Auto-generated constructor stubmhandlerThread = new HandlerThread("handler_thread");mhandlerThread.start();mMyHander = new MyHandler(mhandlerThread.getLooper());}@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++) {Bundle bundle = new Bundle();// 设置参数bundle.putString("info", "----后台处理情况--" + i);Message msg = mMyHander.obtainMessage();msg.setData(bundle);msg.sendToTarget();Log.d(TAG, "***"+Thread.currentThread().currentThread().getId()+"-send:" + "----后台处理情况--" + i);//myHandler.sendMessage(msg);try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class MyHandler extends Handler {// 构造函数public MyHandler() {}public MyHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);// 接收“后台”线程发送来的参数Bundle bundle = msg.getData();String str = bundle.getString("info");Log.d(TAG, "---"+Thread.currentThread().currentThread().getId()+"-receive:" + str);// 在这里不能设置TextView 的值,因为此时Handler没有运行在GUI线程中//show_info_tv.setText(str);}}@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-04 16:17:27.694  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---onCreate---06-04 16:17:27.694  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---initViews---06-04 16:17:30.239  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---Start Task Button Click---06-04 16:17:30.249  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ -----work thread ---1493706-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ -----work thread -backgroundThreadProcessing ---1493706-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--006-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--006-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--106-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--106-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--206-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--206-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--306-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--306-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--406-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--406-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--506-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--506-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--606-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--606-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--706-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--706-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--806-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--806-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--906-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--9

从Log日志来看,mMyHandler确定没有运行在GUI线程中,所以也就不能在使用更改UI了。

这里需要注意,这里用到的多线程并非由Runnable对象开启的,而是ThreadHandler对象开启的。Runnable对象只是作为一个封装了操作的对象被传递,并未产生新线程。

0 0
原创粉丝点击