亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Android Handler

系統 1959 0

Android Handler

?

【轉載】

?

原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。 http://lichen.blog.51cto.com/697816/486402

?

?

?????? 此文是關于Handler的。 Handler主要接受子線程發送的數據, 并用此數據配合主線程更新UI。 當應用程序啟動時,Android首先會開啟一個主線程 (也就是UI線程) ,主線程為管理界面中的UI控件,進行事件分發, 比如說,你要是點擊一個 Button ,Android會分發事件到Button上,來響應你的操作。如果此時需要一個耗時的操作,例如: 聯網讀取數據,或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現假死現象, 如果5秒鐘還沒有完成的話,會收到Android系統的一個錯誤提示 "強制關閉"。

?

??????? 這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,Android主線程不是線程安全的,也就是說,更新UI只能在主線程 中更新,子線程中操作是危險的。這個時候,Handler就出現了,來解決這個復雜的問題。Handler運行在主線程中(UI線程中),它與子線程可以 通過Message對象來傳遞數據,這個時候,Handler就承擔著接受子線程傳過來的(子線程用sedMessage()方法傳遞)Message對 象(里面包含數據),把這些消息放入主線程隊列中,配合主線程進行更新UI。

?

?

????? Handler android 提供的對于異步消息處理的方案。 Handler 的特點是與調用者處于同一線程,如果 Handler 里面做耗時的動作,調用者線程會阻塞。 Android UI 操作不是線程安全的,并且這些操作必須在 UI 線程中執行。 ?

?

????? 所以, Handler 經常被用來在另外的線程中更新 UI 界面。因為 UI 操作必須在 UI 線程中完成,可以通過 Handler 在別的線程中向 UI 線程發送刷新消息, UI 線程收到消息后執行相關操作。主要用到下面兩個函數:

?

public final boolean sendMessage (Message msg) ?? ???? 發送消息

public void handleMessage(Message msg) ?????????????????? 處理消息

?

?????? Handler 對于 Message 的處理不是并發的。一個 Looper? 只有處理完一條 Message 才會讀取下一條,所以消息的處理是阻塞形式的。

?

??????? Handler一些特點:Handler可以分發Message對象和Runnable對象到主線程中, 每個Handler實例,都會綁定到創建他的線程中(一般是位于主線程),它有兩個作用: (1): 安排消息或Runnable 在某個主線程中某個地方執行, (2)安排一個動作在不同的線程中執行。

?

?????? Handler中分發消息經常使用post(Runnable)和sendMessage(Message)方法。

?

?????? 先是sendMessage的例子:

?

main.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<Button  
    android:id="@+id/startButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="開始演示"
    android:onClick="startIt"
    />
<ProgressBar 
	android:id="@+id/bar"
	style="?android:attr/progressBarStyleHorizontal"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content" 
	android:max="500"
	android:progress="0"
	/>
<TextView  
    android:id="@+id/text"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="演示信息:"
    />
</LinearLayout>
  
?

?

Demo.java

    package com.zhouzijing.android.demo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class Demo extends Activity{
	
	private final static String TAG = "DEMO";
	
	private TextView textView;
	private Button startButton;
	private ProgressBar progressBar;
	private MyHandler myHandler;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        textView=(TextView)findViewById(R.id.text);
        startButton = (Button)findViewById(R.id.startButton);
        
		progressBar=(ProgressBar)findViewById(R.id.bar);
		progressBar.setMax(100);
		myHandler=new MyHandler();
    }
    
    /**
     * [開始演示]的按鈕事件.
     * @param v
     */
    public void startIt(View v) {
    	Button btn = (Button)v;
    	//禁止演示按鈕重復點擊
    	btn.setClickable(false);
    	btn.setText("演示中...");
    	progressBar.setProgress(0);
    	textView.setText("演示信息:");
		new Thread(new MyThread(1)).start();
    }
    
    //在對UI進行更新時,執行時所在的線程為主UI線程 
  //繼承Handler類時,必須重寫handleMessage方法 
    class MyHandler extends Handler{
    	public MyHandler(){
    	}
    	public MyHandler(Looper l){
    		super(l);
    	}
    	@Override
    	public void handleMessage(Message msg) {
    		//執行接收到的通知,此時執行的順序是按照隊列進行,即先進先出 
    		Log.i(TAG,"Handler--The ThreadId is: "+Thread.currentThread().getId());
    		int what = msg.what;
    		//根據message的what屬性來進行處理
    		switch(what){
    		case 100:
    			Bundle b=msg.getData();
        		String textStr1=b.getString("textStr");
        		textView.append(textStr1);//更改TextView中的值 
        		int barValue=b.getInt("barValue");
        		progressBar.setProgress(barValue);//更改進度條當中的值 
        		if(barValue==100){
        			//允許演示按鈕點擊
            		startButton.setText("演示結束,可以點擊重新演示");
            		startButton.setClickable(true);
        		}
    			break;
    		default:
    			//其他message扔回上級處理.
    			super.handleMessage(msg);
    		}
    	}
    }
    
    //該線程將會在單獨的線程中運行 
    class MyThread implements Runnable{
    	int index=1;
    	
    	public MyThread(int index) {
			this.index = index;
		}
    	
		@Override
    	public void run() {
    		while(index<11){
    			Log.i(TAG,"Thread--The ThreadId is: "+Thread.currentThread().getId());
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			int what = 100;
    			//從系統message池中取出1個message對象,并設置what屬性.
    			Message msg = myHandler.obtainMessage(what);
    			Bundle b=new Bundle();
    			b.putString("textStr", "線程運行"+index+"次");
    			b.putInt("barValue", index*10);
    			index++;
    			msg.setData(b);
    			myHandler.sendMessage(msg);//通過sendMessage向Handler發送更新UI的消息 
    		}
    	}
    }
}


  

運行效果圖,如下:
Android Handler

?

?

簡單的說,Activity的onCreate方法里啟動一個線程,在這個線程的run方法里使用一個Message對象并使用Handler的 sendMessage方法發送到隊列中,最后在Activity里new一個Handler的內部類實現handMessage方法,使用這個方法把隊 列中的Message對象取出來以實現異步操作。

?

得到Message對象的方法:(1)new Message();(2)handler對象的obtainMessage();前者需要新建一個Message對象,而后者直接從系統的Message池中獲取1個(不用創建對象)。建議使用后者!

?

?

?

????? 然后是post的例子,這里稍微說一下,直接使用new Handler().post(Runnable)這樣的寫法并沒有新開線程。

?

xml配置文件

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<EditText 
	android:id="@+id/edtDownloadUrl"
	android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="http://www.zhouzijing.com/"
	/>
<Button  
    android:id="@+id/btnHandlerPostRunnable"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="開始下載"
    android:onClick="startIt"
    />
<ProgressBar 
	android:id="@+id/pBarDownload"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    style="?android:attr/progressBarStyleHorizontal"
	/>
<TextView 
	android:id="@+id/tvProgressBarPercent"
	android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
	/>
</LinearLayout>

  

?

由于下面代碼要訪問網絡和在sdcard上寫文件,因此需要在AndroidManifest.xml配置權限:

?

        <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  
?

?

代碼文件:

    package com.zhouzijing.android.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

public class HandlerPostRunnable extends Activity {

	private EditText edtDownloadUrl;
	private ProgressBar pBarDownload;
	private TextView tvProgressBarPercent;
	private Button btnHandlerPostRunnable;
	private int fileSize = 0;
	private int progress = 0;
	private final String TAG = "HandlerPostRunnable";
	private Handler handler = new Handler();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.handler_post_runnable);
		//定義組件
		edtDownloadUrl = (EditText)findViewById(R.id.edtDownloadUrl);
		pBarDownload = (ProgressBar)findViewById(R.id.pBarDownload);
		tvProgressBarPercent = (TextView)findViewById(R.id.tvProgressBarPercent);
		btnHandlerPostRunnable = (Button)findViewById(R.id.btnHandlerPostRunnable);
	}

	//開始演示-按鈕事件
	public void startIt(View v) {
		Button btn = (Button)v;
		btn.setText("下載中...");
		btn.setClickable(false);
		downloadFile(edtDownloadUrl.getText().toString());
	}
	/**
	 * 獲取文件名.
	 * @param url
	 * @return
	 */
	private String getFileNameFromUrl(String url) {
		String fileName =  url.substring(url.lastIndexOf("/") + 1);
		return fileName;
	}

	/**
	 * 下載文件.
	 * @param url
	 */
	private void downloadFile(final String url) {
		new Thread() {
			public void run() {
				HttpClient client = new DefaultHttpClient();
				HttpGet get = new HttpGet(url);
				HttpResponse response = null;
				FileOutputStream fos = null;
				try {
					response = client.execute(get);
					HttpEntity entity = response.getEntity();
					InputStream is = entity.getContent();
					if (is != null) {
						File file = new File(
								Environment.getExternalStorageDirectory(),
								getFileNameFromUrl(url));
						fos = new FileOutputStream(file);
						fileSize = (int)entity.getContentLength();
						progress = 0;
						downloadStart();
						byte[] buf = new byte[1024];
						int ch = -1;
						while ((ch = is.read(buf)) != -1) {
							fos.write(buf, 0, ch);
							progress = progress+ch;
							downloading();
						}
					}
					fos.flush();
					fos.close();
					fos = null;
					downloadFinished();
				} catch (Exception e) {
					Log.e(TAG, e.getMessage(), e);
					downloadError(e);
				} finally {
					if (fos != null) {
						try {
							fos.close();
						} catch (IOException e) {
							Log.e(TAG, e.getMessage(), e);
						}
						fos = null;
					}
				}
			}
		}.start();
	}
	
	// 下載開始
	private void downloadStart() {
		handler.post(new Runnable() {
			public void run() {
				pBarDownload.setMax(fileSize);
				pBarDownload.setProgress(0);
			}
		});
	}
	/**
	 * 設置下載進度百分比,
	 */
	private void setDownloadPercent() {
		float percent = (float)progress/(float)fileSize*100;
		int iPercent = (int)percent;
		tvProgressBarPercent.setText(String.valueOf(iPercent)+"%");
	}
	
	// 下載中.
	private void downloading() {
		handler.post(new Runnable() {
			public void run() {
				pBarDownload.setProgress(progress);
				setDownloadPercent();
			}
		});
	}

	// 下載成功結束
	private void downloadFinished() {
		handler.post(new Runnable() {
			public void run() {
				pBarDownload.setProgress(fileSize);
				btnHandlerPostRunnable.setText("下載成功,點擊再開始下載");
				btnHandlerPostRunnable.setClickable(true);
				setDownloadPercent();
				new AlertDialog.Builder(HandlerPostRunnable.this)
				.setTitle("提示").setMessage("下載成功")
				.setPositiveButton("確定", null).show();
			}
		});
	}

	// 下載失敗
	private void downloadError(final Exception err) {
		handler.post(new Runnable() {
			public void run() {
				btnHandlerPostRunnable.setText("下載失敗,點擊再開始下載");
				btnHandlerPostRunnable.setClickable(true);
				new AlertDialog.Builder(HandlerPostRunnable.this)
						.setTitle("提示").setMessage("下載失敗:"+err.getMessage())
						.setPositiveButton("確定", null).show();
			}
		});
	}
}
  
?

代碼運行結果如下圖:

?


Android Handler

?

?

?

?

Android Handler


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 另类色综合 | 亚洲性事 | 亚洲国产系列久久精品99人人 | 欧洲一级做a爱在线观看 | 一本大道香蕉久在线不卡视频 | 在线观看亚洲成人 | 亚洲日本一区二区三区在线不卡 | 国产色啪午夜免费视频 | 成人久久精品 | 奇米影视999 | 欧美特级特黄a大片免费 | 欧美大屁股精品毛片视频 | 日日艹夜夜艹 | 亚洲激情网| 国产精品成人免费视频不卡 | 久久精品免费观看久久 | 亚洲精品区一区二区三区四 | 国产亚洲欧美日韩综合另类 | 日韩久久久精品首页 | 一级一级18女人毛片 | 99久久成人| 久久久精品视频在线观看 | 亚洲国产成人在线 | 欧美成人看片一区二区三区 | 国产高清精品在线 | 久久久国产99久久国产久 | 欧美色99 | 日韩欧美亚洲中字幕在线播放 | 亚洲日本高清成人aⅴ片 | 99热久久国产精品这 | 国产欧美二区三区 | 国产va免费精品 | 国产成人亚洲影视在线 | 99久热在线精品视频播放6 | 这里只有精品视频在线 | 国产精品社区 | 日日噜噜噜夜夜爽爽狠狠 | 婷婷色在线 | 国产免费成人在线视频 | 欧美成综合网网站 | 一级网站在线观看 |