Android多线程优劣,Android 开发中用到的几个多线程解析
在開(kāi)發(fā)工程中線程可以幫助我們提高運(yùn)行速度,Android開(kāi)發(fā)中我知道的線程有四個(gè)一個(gè)是老生長(zhǎng)談的Thread,第二個(gè)是asyncTask,第三個(gè):TimetTask,第四個(gè)是Looper,四個(gè)多線程各有個(gè)的有點(diǎn),Thread的運(yùn)行速度是最快的,AsyncTask的規(guī)范性是最棒的,其它兩個(gè)也有自己的優(yōu)點(diǎn),下面先貼上三個(gè)列子
1.Thread與Handler組合,比較常見(jiàn)
Handler主要是幫助我們來(lái)時(shí)時(shí)更新UI線程
這里在后天加載100張圖片,然后沒(méi)加載完成一個(gè)用handler 返回給UI線程一張圖片并顯示
最后加載完成返回一個(gè)List給UI線程 ,Handler就是一個(gè)后臺(tái)線程與UI線程中間的橋梁
package com.android.wei.thread;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class Activity01 extends Activity {
/** Called when the activity is first created. */
/**讀取進(jìn)度**/
public final static int LOAD_PROGRESS =0;
/**標(biāo)志讀取進(jìn)度結(jié)束**/
public final static int LOAD_COMPLETE = 1;
/**開(kāi)始加載100張圖片按鈕**/
Button mButton = null;
/**顯示內(nèi)容**/
TextView mTextView = null;
/**加載圖片前的時(shí)間**/
Long mLoadStart = 0L;
/**加載圖片完成的時(shí)間**/
Long mLoadEndt = 0L;
Context mContext = null;
/**圖片列表**/
private List list;
/**圖片容器**/
private ImageView mImageView;
//接受傳過(guò)來(lái)得消息
Handler handler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case LOAD_PROGRESS:
Bitmap bitmap = (Bitmap)msg.obj;
mTextView.setText("當(dāng)前讀取到第"+msg.arg1+"張圖片");
mImageView.setImageBitmap(bitmap);
break;
case LOAD_COMPLETE:
list = (List) msg.obj;
mTextView.setText("讀取結(jié)束一共加載"+list.size()+"圖片");
break;
}
super.handleMessage(msg);
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main);
mButton =(Button) findViewById(R.id.button1);
mTextView=(TextView) findViewById(R.id.textView1);
mImageView =(ImageView) this.findViewById(R.id.imageview);
mTextView.setText("點(diǎn)擊按鈕加載圖片");
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//調(diào)用方法
LoadImage();
}
});
}
public void LoadImage(){
new Thread(){
public void run(){
mLoadStart = System.currentTimeMillis();
List list = new ArrayList();
for(int i =0;i<100;i++){
Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon);
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 = i+1;
list.add(bitmap);
msg.obj = bitmap;
handler.sendMessage(msg);
}
mLoadEndt = System.currentTimeMillis();
Message msg = new Message();
msg.what = LOAD_COMPLETE;
msg.obj=list;
msg.arg1 = (int) (mLoadEndt - mLoadStart);
handler.sendMessage(msg);
}
}.start();
}
public Bitmap ReadBitmap(Context context,int resId){
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
}
2AsyncTask異步多線程
AsyncTask的規(guī)范型很強(qiáng),能夠時(shí)時(shí)反映更新的情況
它一般有這么幾個(gè)方法
* onPreExecute(), 該方法將在執(zhí)行實(shí)際的后臺(tái)操作前被UI 線程調(diào)用??梢栽谠摲椒ㄖ凶鲆恍?zhǔn)備工作,如在界面上顯示一個(gè)進(jìn)度條,或者一些控件的實(shí)例化,這個(gè)方法可以不用實(shí)現(xiàn)。
* doInBackground(Params...), 將在onPreExecute 方法執(zhí)行后馬上執(zhí)行,該方法運(yùn)行在后臺(tái)線程中。這里將主要負(fù)責(zé)執(zhí)行那些很耗時(shí)的后臺(tái)處理工作??梢哉{(diào)用 publishProgress方法來(lái)更新實(shí)時(shí)的任務(wù)進(jìn)度。該方法是抽象方法,子類(lèi)必須實(shí)現(xiàn)。
* onProgressUpdate(Progress...),在publishProgress方法被調(diào)用后,UI 線程將調(diào)用這個(gè)方法從而在界面上展示任務(wù)的進(jìn)展情況,例如通過(guò)一個(gè)進(jìn)度條進(jìn)行展示。
* onPostExecute(Result), 在doInBackground 執(zhí)行完成后,onPostExecute 方法將被UI 線程調(diào)用,后臺(tái)的計(jì)算結(jié)果將通過(guò)該方法傳遞到UI 線程,并且在界面上展示給用戶(hù).
* onCancelled(),在用戶(hù)取消線程操作的時(shí)候調(diào)用。在主線程中調(diào)用onCancelled()的時(shí)候調(diào)用。
為了正確的使用AsyncTask類(lèi),以下是幾條必須遵守的準(zhǔn)則:
1) Task的實(shí)例必須在UI 線程中創(chuàng)建
2) execute方法必須在UI 線程中調(diào)用
3) 不要手動(dòng)的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個(gè)方法,需要在UI線程中實(shí)例化這個(gè)task來(lái)調(diào)用。
4) 該task只能被執(zhí)行一次,否則多次調(diào)用時(shí)將會(huì)出現(xiàn)異常
package com.android.wei.thread;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class Activity02 extends Activity{
/**開(kāi)始StartAsync按鈕**/
Button mButton = null;
Context mContext = null;
//內(nèi)容顯示出來(lái)
TextView mTextView = null;
//Timer 對(duì)象
Timer mTimer = null;
/** timerTask 對(duì)象**/
TimerTask mTimerTask = null;
/**記錄TimerId**/
int mTimerId =0;
/**圖片列表**/
private List list;
/**圖片容器**/
private ImageView mImageView;
public void onCreate(Bundle s){
super.onCreate(s);
setContentView(R.layout.main);
mContext = this;
mButton =(Button) this.findViewById(R.id.button1);
mImageView =(ImageView)this.findViewById(R.id.imageview);
mTextView =(TextView) this.findViewById(R.id.textView1);
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
StartAsync();
}
});
}
public void StartAsync(){
new AsyncTask(){
protected void onPreExecute(){
//首先執(zhí)行這個(gè)方法,它在UI線程中,可以執(zhí)行一些異步操作
mTextView.setText("開(kāi)始加載進(jìn)度");
super.onPreExecute();
}
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
//異步后臺(tái)執(zhí)行,執(zhí)行完畢可以返回出去一個(gè)結(jié)果 Object 對(duì)象
//得到開(kāi)始加載得時(shí)間
list = new ArrayList();
for(int i =0;i<100;i++){
Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon);
final ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
byte[] image = os.toByteArray();
Bundle bundle = new Bundle();
bundle.putInt("index", i);
bundle.putByteArray("image", image);
publishProgress(bundle);
list.add(bitmap);
}
return list;
}
protected void onPostExecute(Object result){
//doInBackground 執(zhí)行之后在這里可以接受到返回結(jié)果的對(duì)象
List list = (List) result;
mTextView.setText("一共加載了"+list.size()+"張圖片");
super.onPostExecute(result);
}
protected void onProgressUpdate(Object... values){
//時(shí)時(shí)拿到當(dāng)前的進(jìn)度更新UI
Bundle bundle = (Bundle)values[0];
byte[] image = bundle.getByteArray("image");
Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
int index = bundle.getInt("index");
mTextView.setText("當(dāng)前加載進(jìn)度"+index);
mImageView.setImageBitmap(bitmap);
super.onProgressUpdate(values);
}
}.execute();
}
public Bitmap ReadBitmap(Context context,int resId){
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
}
3TimerTask
可以根據(jù)我們的設(shè)置來(lái)間隔性的運(yùn)行,可以很好的實(shí)現(xiàn)監(jiān)聽(tīng)功能一般也跟handler一起
package com.android.wei.thread;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TimerTaskActivity extends Activity{
/**執(zhí)行Timer進(jìn)度**/
public final static int LOAD_PROGRESS =0;
/**關(guān)閉TImer進(jìn)度**/
public final static int CLOSE_PROGRESS =1;
/**開(kāi)始TIMERTASK按鈕**/
Button mButton0 = null;
/**關(guān)閉TIMERTASK按鈕**/
Button mButton1 =null;
/**顯示內(nèi)容**/
TextView mTextView = null;
Context mContext = null;
/**timer對(duì)象**/
Timer mTimer = null;
/**TimerTask對(duì)象**/
TimerTask mTimerTask = null;
/**記錄TimerID**/
int mTimerID =0;
Handler handler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case LOAD_PROGRESS:
mTextView.setText("當(dāng)前得TimerID為:"+msg.arg1);
break;
case CLOSE_PROGRESS:
mTextView.setText("當(dāng)前Timer已經(jīng)關(guān)閉請(qǐng)重新啟動(dòng)");
break;
}
super.handleMessage(msg);
}
};
protected void onCreate(Bundle s){
setContentView(R.layout.timer);
mContext = this;
mButton0 = (Button) this.findViewById(R.id.button1);
mButton1 = (Button) this.findViewById(R.id.button2);
mTextView = (TextView) this.findViewById(R.id.textView1);
mTextView.setText("點(diǎn)擊按鈕開(kāi)始更新時(shí)間");
mButton0.setOnClickListener(new OnClickListener(){
public void onClick(View v){
StartTimer();
}
});
mButton1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
CloseTimer();
}
});
super.onCreate(s);
}
public void StartTimer(){
if(mTimer == null){
mTimerTask = new TimerTask(){
@Override
public void run() {
mTimerID ++;
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 =(int) (mTimerID);
handler.sendMessage(msg);
}
};
mTimer = new Timer();
//第一個(gè)參數(shù)為執(zhí)行的mTimerTask
//第二個(gè)參數(shù)為延遲得事件,這里寫(xiě)1000得意思是 mTimerTask將延遲1秒執(zhí)行
//第三個(gè)參數(shù)為多久執(zhí)行一次,這里寫(xiě)1000 表示沒(méi)1秒執(zhí)行一次mTimerTask的Run方法
mTimer.schedule(mTimerTask, 1000,1000);
}
}
public void CloseTimer(){
if(mTimer !=null){
mTimer.cancel();
mTimer = null;
}
if(mTimerTask!= null){
mTimerTask = null;
}
mTimerID =0;
handler.sendEmptyMessage(CLOSE_PROGRESS);
}
}
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Android多线程优劣,Android 开发中用到的几个多线程解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 查看so库中是否有某个定义_论Linux
- 下一篇: 上下定高 中间自适应_上下固定中间自适应