Android多线程

Android多线程(01)

 

 

一、             单线程模型:

Message Queue消息队列,用来存放Handler发布的消息。

 

             Looper扮演着Handler和消息队列之间桥梁的角色;程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列中;Looper也把消息队列中的消息广播给所有的Handler,Handler接收到消息后调用handleMessage方法进行处理。

二、             多线程实现:

Android是单线程模型,这意味着Android UI操作并不是线程安全的,当某些可能耗时的操作需要执行时,最好将其放入到一个新的线程中。

1.        Activity.runOnUiThread(Runnable())

如果当前线程是UI线程,则行动立即执行;否则行动是发布到UI线程的事件队列中。

runOnUiThread(new Runnable() {

// 如果是UI线程,操作将立即执行;如果不是UI线程,操作将放到UI线程的事件队列中执行

@Override

public void run() {

        Log.i(tag, "runOnUiThread run method execute.");

                                                  relativeLayout.setBackgroundResource(R.drawable.bg);

                                                  updateUIButton.setText(getString(R.string.restore_ui));

                                                  updateUI2Button.setText(getString(R.string.restore_ui));

        isClick = false;

        }

});

 

2.        Handler

在当前UI线程中创建一个新的线程UIThread,将封装的数据Bundle放入到Message中,并通过Handler.sendMessage(Message)将Message放入到消息队列中;使用Handler.handleMessage(Message)获取消息队列中的Message。

@SuppressLint("HandlerLeak")

private class UIHandler extends Handler {

        @Override

        public void handleMessage(Message msg) {

                 Log.i(tag, "handleMessage method execute.");

                 super.handleMessage(msg);

                 if (isClick) {

                         Bundle bundle = msg.getData();

                         int bgImage = bundle.getInt("bgImage");

                         relativeLayout.setBackgroundResource(bgImage);

                         updateUIButton.setText(getString(R.string.restore_ui));

                         updateUI2Button.setText(getString(R.string.restore_ui));

                                  isClick = false;

                         } else {

                         relativeLayout.setBackgroundDrawable(null);

                         updateUIButton.setText(getString(R.string.update_ui));

                         updateUI2Button.setText(getString(R.string.update_ui));

                         isClick = true;

                         }

        }

}

 

private class UIThread extends Thread {

        @Override

        public void run() {

                 Log.i(tag, "UIThread run method execute.");

                 Message message = new Message();

                 Bundle bundle = new Bundle();

                 bundle.putInt("bgImage", R.drawable.bg);

                 message.setData(bundle);

                 uiHandler.sendMessage(message);

        }

}

 

uiHandler = new UIHandler();

UIThread uiThread = new UIThread();

uiThread.start();

 

3.        View.post(Runnable())

         在当前UI主线程中,将Runnable加入到消息队列中。

                

updateUI3Button.post(new Runnable() {

        @Override

        public void run() {

                 Log.i(tag, "The post method execute.");

                 if (isClick) {

                 relativeLayout.setBackgroundResource(R.drawable.bg);

                 updateUIButton.setText(getString(R.string.restore_ui));

                 updateUI2Button.setText(getString(R.string.restore_ui));

                 updateUI3Button.setText(getString(R.string.restore_ui));

                 updateUI4Button.setText(getString(R.string.restore_ui));

                 isClick = false;

                 } else {

                 relativeLayout.setBackgroundDrawable(null);

                 updateUIButton.setText(getString(R.string.update_ui));

                 updateUI2Button.setText(getString(R.string.update_ui));

                 updateUI3Button.setText(getString(R.string.update_ui));

                 updateUI4Button.setText(getString(R.string.update_ui));

                 isClick = true;

                 }

        }

});

 

4.        View.postDelayed(Runnable(),longdelayMillis)

在当前UI主线程中,将Runnable加入到消息队列中,在设置的时间间隔delayMillis之后执行。

updateUI4Button.postDelayed(new Runnable() {

        @Override

        public void run() {

                 Log.i(tag, "The postDelayed method execute.");

                 if (isClick) {

                 relativeLayout.setBackgroundResource(R.drawable.bg);

                 updateUIButton.setText(getString(R.string.restore_ui));

                 updateUI2Button.setText(getString(R.string.restore_ui));

                 updateUI3Button.setText(getString(R.string.restore_ui));

                 updateUI4Button.setText(getString(R.string.restore_ui));

                 isClick = false;

                 } else {

                 relativeLayout.setBackgroundDrawable(null);

                 updateUIButton.setText(getString(R.string.update_ui));

                 updateUI2Button.setText(getString(R.string.update_ui));

                 updateUI3Button.setText(getString(R.string.update_ui));

                 updateUI4Button.setText(getString(R.string.update_ui));

                 isClick = true;

                 }

        }

}, 5000);

 

5.        AsyncTask<Params,Progress,Result>

AsyncTask比Handler更轻量级,适用于简单的异步处理,其定义了三种泛型参数:

1)       Params:启动任务执行的输入参数,比如HTTP的URL;

2)       Progress:后台任务执行的百分比;

3)       Result:后台任务执行的最终返回结果,比如String。

使用AsyncTask类,必须遵守以下准则:

1)       Task的实例必须在UI线程中执行;

2)       execute方法必须在UI线程中调用;

3)       不要手动调用onPreExecute(),doInBackground(Integer… params),onProgressUpdate(Integer… values)和onPostExecute(String result);

4)       该Task只能调用一次,否则多次调用会出现异常。

MyAsyncTask myAsyncTask = new MyAsyncTask(textView, progressBar, activity);

myAsyncTask.execute(1000,900);

 

package com.xuwan.android01;

import android.app.Activity;

import android.os.AsyncTask;

import android.util.Log;

import android.widget.ProgressBar;

import android.widget.TextView;

 

/**

* @author SJC

*

*/

public class MyAsyncTask extends AsyncTask<Integer, Integer, String> {

private static String tag = "MyAsyncTask";

private TextView textView;

private ProgressBar progressBar;

private Activity activity;

 

/**

* 构造方法

*

* @param textView

* @param progressBar

*/

public MyAsyncTask(TextView textView, ProgressBar progressBar,Activity activity) {

super();

this.textView = textView;

this.progressBar = progressBar;

this.activity = activity;

}

 

/** 该方法运行于UI主线程中 **/

@Override

protected void onPreExecute() {

Log.i(tag, "The onPreExecute method execyte.");

textView.setText(activity.getString(R.string.on_pre_execute));

}

 

/**

* 后台执行,执行比较耗时的操作 <br/>

* 参数params对应AsyncTask中的第一个参数,类型为Integer<br/>

* 返回值对应AsyncTask中的第三个参数,类型为String<br/>

* 该方法并不运行于UI线程中,主要用于异步操作,在该方法中不能对UI进行操作,<br/>

* 但可以调用publishProgress方法触发onProgressUpdate方法对UI进行操作

**/

@Override

protected String doInBackground(Integer... params) {

Log.i(tag, "The doInBackground method execute.");

textView.setText(activity.getString(R.string.do_in_background));

NetOperator netOperator = new NetOperator();

int i = 0;

for (i = 10; i <= 100; i += 10) {

           netOperator.operate();

           publishProgress(i);

}

Log.i(tag, "params:" + params[0] + "|" + params[1]);

return i + params[0].intValue() + "";

}

 

/**

* 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。

* 此方法在主线程执行,任务执行的结果作为此方法的参数返回

**/

@Override

protected void onPostExecute(String result) {

Log.i(tag, "The onPostExecute method execute.");

textView.setText(activity.getString(R.string.on_post_execute));

Log.i(tag, "result:" + result);

}

 

/**

* 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。<br/>

* 参数values对应AsyncTask中第二个参数,类型为Integer

**/

@Override

protected void onProgressUpdate(Integer... values) {

Log.i(tag, "The onProgressUpdate method execute.");

int value = values[0];

progressBar.setProgress(value);

}

 

/** 用户调用取消的操作 **/

@Override

protected void onCancelled() {

Log.i(tag, "The onCancelled method execute.");

super.onCancelled();

}

}

 

                          

三、             总结:

1.        Android系统是单线程系统,为了实现多线程效果,采用了message queue;


2.        为实现多线程,可采用runOnUiThread、Handler、post、postDelay和AsyncTask技术实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值