android分開兩個線程做事,android開發教程之handle實現多線程和異步處理

這次淺談一下Handler,為什么會出現Handler這個功能特性呢?首先,在之前的基本控件,基本都是在Activity的onCreate(Bundle savedInstanceState)方法中調用和處理的,但是,在有些情況,比如在網絡上下載軟件等一些需要等待響應時間比較長的操作,如果同樣放在Activity的該方法中的話,那么在執行該方法的時候,整個Activity是不可動的,用戶只能干等著,這樣的用戶體驗是十分差的,這種處理方式帶來的最好結果是等待了一段時間后,得到了想要的結果,不好的情況就是等了N久,也沒有出現結果,有的甚至會使Activity報錯,為了避免這些情況的發生,所以引入了Handler的特性,他就像是一個線程隊列,它也是一種異步的消息處理。

首先我們先看一個例子,通過例子來對Handler進行認識。

布局文件中是兩個按鈕,分別是start和stop,分別控制線程的開始和停止。

代碼如下:

在Activity中的代碼如下:

代碼如下:

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class HandlerDemo1Activity extends Activity {

Button startButton = null;

Button endButton = null;

Handler handler = new Handler();

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

startButton = (Button)findViewById(R.id.start);

startButton.setOnClickListener(new StartListener());

endButton = (Button)findViewById(R.id.end);

endButton.setOnClickListener(new EndListener());

}

class StartListener implements OnClickListener{

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

handler.post(HandlerThread);

}

}

class EndListener implements OnClickListener{

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

handler.removeCallbacks(HandlerThread);

}

}

Runnable HandlerThread = new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

System.out.println("HandlerThread is Running......");

handler.postDelayed(HandlerThread, 3000);

}

};

}

我們可以看到,在Activity中對兩個按鈕分別綁定了事件監聽器,還創建了Handler的一個實例,以及創建了一個匿名內部類,是一個實現Runnable接口的線程HandlerThread。

當start按鈕按下時,即會執行handler.post(HandlerThread);這一句代碼,之前說過,Handler用一個線程隊列,這句代碼即是把HandlerThread這個線程加入了handler的線程隊列中,因為加入的這個HandlerThread是第一個線程,因此它會馬上執行它的run()方法。在run()方法中,handler.postDelayed(HandlerThread, 3000);又再一次將HandlerThread放入handler的線程隊列中,這里設置了3000ms的延遲。這樣,整個程序會不斷地運行,且每隔3000ms在LogCat中打印出"HandlerThread is Running......"。

但是,值得注意的是,不要以為現在handler的出現,使得這些打印操作所在的線程和主線程分開了,其實不然,這里根本沒有兩個線程在跑,這些打印出來的內容,也是主線程跑出來的。我們可以做個試驗,在onCreate函數之后以及打印語句的地方把當前的Thread的名字通過Thread.currentThread.getName()打印出來,可以看到,都是相同的,都是main,這就意味著都是主線程跑出來的。我們知道一個線程的啟動需要start()方法,而在這個程序中并沒有對HandlerThread進行start,而是直接調用了run()方法了。所以只是main線程在跑就不足為奇了。

從上面的例子來看,這個Handler如果這樣用的話,并不是我們想要的效果,因為它沒有實現異步,還是在一個主線程中運行。

因此,我們必須換一種方式來使用Handler。

要實現Handler的異步多線程,就需要了解另兩個類,一個是Message類,另一個是Looper類。

每個Handler對象中都有一個消息隊列,隊列中就是存放的Message對象,可以使用obtainMessage()來獲得消息對象。同時,Message對象是用來傳遞使用的,它能傳遞兩個整型和一個Object,盡量使用Message的arg1與arg2兩個整型來傳遞參數,那樣系統消耗最小(API如是說),如果傳遞數據量比較大,則可以使用setData(Bundle a)的方法,其中的Bundle對象可以粗略的看成是一個Map對象,但它的Key都是String,而value是有限的一些類型,可以再API里查看。

Looper類有能夠循環地從消息隊列中取得消息的功能,我們可以在一個線程中使用Looper,這樣,該線程就可以循環的在消息隊列里取得消息,知道消息隊列為空為止。但我們一般不直接創建和使用Looper,在Android提供的HandlerThread類中,就實現了Looper的功能,所以我們只要使用HandlerThread這個類就可以了,我們用HandlerThread的對象調用getLooper()來得到該線程的Looper對象。

我們來看下面這個例子

代碼如下:

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.Looper;

import android.os.Message;

public class HandlerDemo2Activity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

System.out.println("Activity---->"+Thread.currentThread().getName());

HandlerThread handlerThread = new HandlerThread("HandlerThread");//創建一個HandlerThread對象,它是一個線程

handlerThread.start();//啟動線程

MyHandler myHandler = new MyHandler(handlerThread.getLooper());//創建一個MyHandler對象,該對象繼承了Handler,從下面的MyHandler類中可以看到,調用的是Handler父類的Handler(Looper looper)的構造函數,而這里傳進去的Looper對象是從HandlerThread中取得的。

Message msg = myHandler.obtainMessage();//獲得消息對象

msg.sendToTarget();//把得到的消息對象發送給生成該消息的Handler,即myHandler,當myHandler接收到消息后,就會調用其handleMessage的方法來處理消息

}

class MyHandler extends Handler{

public MyHandler() {//構造函數

// TODO Auto-generated constructor stub

}

public MyHandler(Looper looper){//構造函數

super(looper);//實現了父類的該構造函數

}

@Override

public void handleMessage(Message msg) {//當這個Handler接收到Message對象的時候,會自動調用這個方法,來對Message對象進行處理

// TODO Auto-generated method stub

System.out.println("Handler---->"+Thread.currentThread().getName());

}

}

}

上面的代碼在LogCat中System.out的執行結果為:

Acitivity---->main

Handler---->HandlerThread

這就說明了,使用Handler,結合Looper和Message,可以實現與主線程的分離,從而可以實現多線程和異步處理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541265.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541265.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541265.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

夏夜

兒時的夏夜畢竟是最有夏夜的味道。屋堂的煤油燈啪嗒的跳動,忽明忽暗,真怕它脆弱的明亮突然變黑暗。屋外彎月星稀,月光優雅的撒在平靜的湖面上,清純而又溫和。水鳥在湖岸邊慵懶的伸了伸脖子。正享受著夏夜的寧靜和清涼。調皮的小孩…

Python operator.lt()函數與示例

operator.lt()函數 (operator.lt() Function) operator.lt() function is a library function of operator module, it is used to perform "less than operation" on two values and returns True if the first value is less than the second value, False, otherw…

android實現滑動切換圖,Android:使用ViewPager實現左右滑動切換圖片加點點

圖片發自簡書App1、引入android-support-v4.jar包&#xff0c;在主布局里加入< ?xml version"1.0" encoding"utf-8"?>< RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.…

div的替代品

人們在標簽使用中最常見到的錯誤之一就是隨意將HTML5的<section>等價于<div>——具體地說&#xff0c;就是直接用作替代品(用于樣式)。在XHTML或者HTML4中&#xff0c;我們常看到這樣的代碼&#xff1a; <!-- HTML 4-style code --> <div id"wrapper…

threadgroup_Java ThreadGroup list()方法與示例

threadgroupThreadGroup類的list()方法 (ThreadGroup Class list() method) list() method is available in java.lang package. list()方法在java.lang包中可用。 list() method is used to list or display information (like name, priority, thread group, etc.) to the st…

html的柱狀圖去除右邊縱坐標,excel如何把次坐標軸逆序

excel2010設置水平坐標軸逆序類型,但垂直坐標軸刻設置水平坐標軸逆序且垂直坐標軸軸仍位于圖表左側的步驟是&#xff1a;打開帶有圖表的Excel工作表&#xff1b;在圖表區域的水平軸標簽位置雙擊鼠標左鍵&#xff0c;打開“設置坐標軸格式”&#xff1b;勾尋逆序類別”&#xff…

jhipster項目遷移websocket

2019獨角獸企業重金招聘Python工程師標準>>> 1、 在項目目錄下命令行安裝 兩個組件 bower install sockjs-client bower install stomp-websocket 2、在index.html 中加入組件js的引用 <script src"bower_components/sockjs-client/dist/sockjs.js">…

Java包hashCode()方法及示例

包類hashCode()方法 (Package Class hashCode() method) hashCode() method is available in java.lang package. hashCode()方法在java.lang包中可用。 hashCode() method is used to return the hashcode of the package calculated from the package name. hashCode()方法用…

html 圖片上放置按鈕,用CSS在圖片上再加一個小按鈕

很簡單的&#xff0c;嗯&#xff0c;就是要做成這樣的&#xff1a;用CSS&#xff0c;當然得用層了&#xff0c;就是在圖片上再加一個層&#xff0c;用來放那個按鈕&#xff0c;按鈕又有兩種方式可以放&#xff0c;一種是直接用圖片img標簽&#xff0c;一種是通過背景圖片放上去…

html點擊導航變色,點擊導航后,當前導航的顏色變色

html>Documentnav ul {padding: 0;list-style: none;}nav ul li {text-decoration: none;width: 70px;line-height: 50px;text-align: center;float: left;background-color: #000;color: #fff;cursor: pointer;}.gray {background-color: rgba(0,0,0,0.6);}首頁實戰路徑猿問…

Java掃描儀toString()方法及示例

掃描儀類toString()方法 (Scanner Class toString() method) toString() method is available in java.util package. toString()方法在java.util包中可用。 toString() method is used to string denotation of this Scanner and it contains information related to tracing.…

怎么將oracle的sql文件轉換成mysql的sql文件

怎么將sql文件導入PowerDesigner中的方法(將oracle的sql文件轉換成mysql的sql文件)呢&#xff1f; 怎么將xx.sql文件的數據庫結構導入powerdesigner 的方法呢? 現講下。 工具/原料 PowerDesigner軟件&#xff0c;oracle數據庫 方法/步驟 將要導入的庫的所有表的表結構(不要表數…

ios html圖片相對路徑,iOS 下加載本地HTML/js/css/image 等路徑問題

今天在項目中遇到一個問題&#xff1a;我將H5的文件拖入項目中&#xff0c;在webView上添加H5,運行時發現H5的樣式與圖片等都沒屏幕快照 2016-07-06 11.33.22.png有了。經過多種測試后發現&#xff1a;是路徑的問題。在ios項目下添加本地HTML/js/css/image 當拖入項目時有兩種選…

nextfloat_Java Random nextFloat()方法與示例

nextfloat隨機類nextFloat()方法 (Random Class nextFloat() method) nextFloat() method is available in java.util package. nextFloat()方法在java.util包中可用。 nextFloat() method is used to generate the next pseudo-random float value between the range 0.0 and …

mac自己定義tree命令

編輯文件: vim ~/.bash_profile 在文件末尾追加: alias tree"find . -print | sed -e s;[^/]*/;|____;g;s;____|; |;g" 應用配置: source ~/.bash_profile 轉載于:https://www.cnblogs.com/gavanwanggw/p/6962533.html

Java Hashtable keySet()方法與示例

哈希表類keySet()方法 (Hashtable Class keySet() method) keySet() method is available in java.util package. keySet()方法在java.util包中可用。 keySet() method is used to return a set of keys to be viewed in a set in this Hashtable. keySet()方法用于返回要在此H…

el-calendar 怎么設置上一年和下一年_為什么香港碩士一年的含金量那么高?

為什么香港碩士研究生只讀一年但含金量更高&#xff1f;近些年來香港留學大熱&#xff0c;其中一個原因就是香港的授課式碩士研究生僅需一年就可以拿到學位。對于學生來說&#xff0c;在享受到國際一流的教學資源和工作機會的同時&#xff0c;既節省時間又節約金錢&#xff0c;…

武漢市江岸區2021年高考成績查詢,2021年武漢各區一、二、三批次高中有哪些(名單)...

5月5日至9日是武漢市中考網上報名填報志愿的日子&#xff0c;填報志愿之前應提前了解本區的一批次、二批次和三批次學校的名單&#xff0c;了解其歷年錄取分數線&#xff0c;并選中最合適最理想的一所學校進行填寫&#xff0c;下面我們來看詳細名單。武漢各區一、二、三批次高中…

《Java設計模式》之橋接模式

Bridge模式的概念 Bridge 模式是構造型的設計模式之中的一個。Bridge模式基于類的最小設計原則&#xff0c;通過使用封裝&#xff0c;聚合以及繼承等行為來讓不同的類承擔不同的責任。它的主要特點是把抽象&#xff08;abstraction&#xff09;與行為實現&#xff08;implement…

Java Formatter locale()方法與示例

Formatter類的locale()方法 (Formatter Class locale() method) locale() method is available in java.util package. locale()方法在java.util包中可用。 locale() method is used to returns the locales assign by the construction of this Formatter. locale()方法用于返…