// 1 主activity HhActivity.java
package hh.hh.hh;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
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.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
//public class HelloWorldActivity extends Activity {
public class HhActivity extends Activity {
/** 标签 */
private TextView textView;
Button btn, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9;
ProgressBar progressbar;
private String tag;
/** Runnable */
private Runnable runnable = new Runnable() {
@Override
public void run() {
// logThreadId(); // 打印当前线程ID
textView.setText(tag + ", I'm Join!"); // 执行UI操作
setTitle(tag + ", I'm Join!");
// textView.setBackgroundResource(R.drawable.ic_launcher);
}
};
/** 实现消息循环的线程(在Android索引文档android.os.Looper的概述里有介绍) */
private class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
// logThreadId(); // 打印当前线程ID
Log.i(tag, msg.getData().getString("key"));
// textView.setText(tag + ", I'm Summer!");
}
};
Looper.loop();
}
}
/** 重写Handler的消息处理方法 */
private class MyHandler extends Handler {
// 带有参数的构造函数
public MyHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// process incoming messages here
// logThreadId(); // 打印当前线程ID
Log.i("xia", msg.getData().getString("key"));
}
}
/** 读取网页任务 */
private class LoadHtmlTask extends AsyncTask<String, Integer, String> {
private Context mContext;
private ProgressDialog dialog; // 进度框
public LoadHtmlTask(Context context) {
this.mContext = context;
initDialog(); // 初始化进度对话框
}
/** 初始化进度对话框 */
private void initDialog() {
dialog = new ProgressDialog(mContext);
dialog.setMax(100); // 设置最大进度值
dialog.setTitle("Loading..."); // 设置标题
dialog.setCancelable(false); // 设为返回键不可取消
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 设为进度条样式
// 增加取消按钮及其事件
dialog.setButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.dismiss(); // 取消显示
cancel(true); // 取消并中断任务
}});
}
/** doInBackground之前,在主线程执行 */
@Override
protected void onPreExecute() {
//logThreadId("onPreExecute()"); // 打印当前线程ID
dialog.show(); // 显示进度对话框
}
/** onPreExecute()之后,在后台线程执行 */
@Override
protected String doInBackground(String... params) {
//logThreadId("doInBackground"); // 打印当前线程ID
// 未传入参数直接返回
if (null == params || params.length <= 0) {
return "请确认输入了网址参数!";
}
try {
Thread.currentThread().sleep(5000);
// 创建HttpGet对象,params[0]为url
HttpGet httpGet = new HttpGet(params[0]);
// 发送Http Get请求,并返回HttpResponse对象
HttpResponse response = new DefaultHttpClient()
.execute(httpGet);
// 判断响应状态,200表示成功响应
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity(); // 获取返回结果
long length = entity.getContentLength(); // 获取内容长度(google获取不到)
boolean getLen = length > 0 ? true : false; // 判断是否获取了内容长度
InputStream is = entity.getContent(); // 获取响应内容
if (is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
long count = 0;
while ((ch = is.read(buf)) != -1 && !isCancelled()) { // 同时还未取消
baos.write(buf, 0, ch);
count += ch;
if (getLen) { // 获取了内容长度时
// 调用publishProgress()更新进度
publishProgress((int) ((count / (float) length) * 100));
}
}
is.close();
baos.close();
return new String(baos.toByteArray()); // 返回结果
}
return "无返回内容!";
} else {
return "服务器未响应或失败!";
}
} catch (Exception e) {
e.printStackTrace();
}
return "程序异常啦!";
}
/** 调用了publishProgress(),在主线程执行 */
@Override
protected void onProgressUpdate(Integer... values) {
// logThreadId("onProgressUpdate"); // 打印当前线程ID
dialog.setProgress(values[0]);
}
/** 未调用了cancel(),doInBackground()结束后,在主线程执行 */
@Override
protected void onPostExecute(String result) {
//logThreadId("onPostExecute(result)"); // 打印当前线程ID
dialog.dismiss(); // 取消显示
showMsg(result); // 显示结果
}
/** 调用了cancel(),doInBackground()结束后,在主线程执行 */
@Override
protected void onCancelled() {
//logThreadId("onCancelled"); // 打印当前线程ID
showMsg("用户取消了该任务!");
}
/** 提示框显示消息 */
private void showMsg(String message) {
// message内容过多时,提示框显示会延迟,例如sina
new AlertDialog.Builder(mContext)
.setTitle("消息")
.setMessage(message)
.setNegativeButton("关闭",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
}).show();
}
}
/** 2 Android异步线程——AsyncTask */
public void methodSeven(View v) {
tag = "methodFour";
new LoadHtmlTask(this).execute("http://www.baidu.com"); // 执行读取网页任务
// new LoadHtmlTask(this).execute("http://www.google.com");
// 获取不到内容长度
// new LoadHtmlTask(this).execute("http://www.sina.com"); // 获取大量网页数据
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tag = "UIThreadActivity";
btn = (Button) findViewById(R.id.btn);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn4 = (Button) findViewById(R.id.btn4);
btn5 = (Button) findViewById(R.id.btn5);
btn6 = (Button) findViewById(R.id.btn6);
btn7 = (Button) findViewById(R.id.btn7);
btn8 = (Button) findViewById(R.id.btn8);
progressbar = (ProgressBar) findViewById(R.id.pro);
textView = (TextView) findViewById(R.id.textview);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
blockUi(textView);// 仅仅是阻塞了一会儿,不报异常。
}
});
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
updateUi(textView);// 报异常。子线程不能更新ui.
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodOne(textView);// handler.post(runnable);
}
});
btn3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodTwo(textView);// textView.post(runnable);
}
});
btn4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodThree(textView);// runOnUiThread(runnable);
}
});
btn5.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodFour(textView);// runOnUiThread(runnable);
}
});
btn6.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodFive(textView);// runOnUiThread(runnable);
}
});
btn7.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodSix(textView);// runOnUiThread(runnable);
}
});
btn8.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
methodSeven(textView);//runOnUiThread(runnable);
}
});
}
/** 1.1 UI线程阻塞 */
public void blockUi(View v) {
tag = "blockUi";
// logThreadId(); // 打印当前线程ID
/* 读取网页内容并显示 */
textView.setText("开始读取网页!"); // 该步可能未显示,为什么?http://www.google.com.hk/
String document = loadHtml("http://m.weather.com.cn/data5/city090507.xml"); // 耗时操作:读取网页源码
textView.setText(null == document ? "读取失败!" : document); // 显示网页源码
/**
* * 1.观察按钮呈按下状态持续时间<br>
* * 2.尝试在按钮呈按下状态时,进行按键和触屏操作<br>
* */
}
/** 1.2 非主线程更新UI */
public void updateUi(View v) {
tag = "updateUi";
new Thread(runnable).start();
}
/** 2.1 方法1:Handler */
public void methodOne(View v) {
tag = "methodOne";
// Can't create handler inside thread that has not called
// Looper.prepare();
final Handler handler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
// logThreadId(); // 打印当前线程ID
handler.post(runnable);
// handler.postDelayed(runnable, 1000);
}
}).start();
}
/** 2.2 方法2: View.post(Runnable) */
public void methodTwo(View v) {
tag = "methodTwo";
new Thread(new Runnable() {
@Override
public void run() {
// logThreadId(); // 打印当前线程ID
textView.post(runnable);
// textView.postDelayed(runnable, 1000);
}
}).start();
}
/** 2.3 方法3:Activity.runOnUiThread(Runnable) */
public void methodThree(View v) {
tag = "methodThree";
new Thread(new Runnable() {
@Override
public void run() {
// logThreadId(); // 打印当前线程ID
runOnUiThread(runnable);
}
}).start();
}
/** 1.1 Thread实现消息循环 */
public void methodFour(View v) {
tag = "methodFour";
// 创建一个LooperThread对象,实现了消息循环
LooperThread thread = new LooperThread();
// 必须启动这个线程
thread.start();
// 创建一个消息对象并设置信息
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("key", "1.1 Thread实现消息循环");
msg.setData(bundle);
// 发送消息对象
thread.mHandler.sendMessage(msg);
}
/** * 读取网页源码 */
private String loadHtml(String urlStr) {
String result = null;
try {
URL u = new URL(urlStr);
// new URL("http://m.weather.com.cn/data5/city08.xml");
byte[] b = new byte[256];
InputStream in = null;
// FileWriter writera = null;//new FileWriter("c:/a.txt", true);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
try {
in = u.openStream();
int i;
while ((i = in.read(b)) != -1) {
bo.write(b, 0, i);
}
result = bo.toString();
bo.reset();
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
} finally {
if (in != null) {
in.close();
return null;
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
return result;
}
/** 1.2 Handler与Looper相关联 */
public void methodFive(View v) {
tag = "methodTwo";
// 生成一个HandlerThread对象,使用Looper来处理消息队列
HandlerThread thread = new HandlerThread("MyThread");
// 必须启动这个线程
thread.start();
// 将一个线程绑定到Handler对象上,则该Handler对象就可以处理线程的消息队列
MyHandler myhandler = new MyHandler(thread.getLooper());
// 从Handler中获取消息对象
Message msg = myhandler.obtainMessage();
// 设置消息对象信息
Bundle bundle = new Bundle();
bundle.putString("key", "summer -->> 1.2 Handler与Looper相关联");
msg.setData(bundle);
// 将消息对象发送给目标对象Handler
msg.sendToTarget();
}
/** 1.3 Hanlder与Thread实现异步 */
public void methodSix(View v) {
tag = "methodThree";
/* 初始化进度条 */
progressbar.setProgress(0);
// progressbar.setVisibility(View.VISIBLE);
// 新线程执行某操作
new ProgressThread(0).start();
}
/** 更新UI */
private Handler meHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
int tempint = msg.getData().getInt("key");
//if(tempint==100)
//progressbar.dismiss();
progressbar.setProgress(msg.getData().getInt("key"));
}
};
/** 新线程任务 */
private class ProgressThread extends Thread {
private int progress;
public ProgressThread(int progress) {
this.progress = progress;
}
@Override
public void run() {
try {
while (progress <= 100) {
progress += 5; // 进度+5
// doSomething(); // 执行耗时操作
Thread.sleep(100);
// 从Handler中获取消息对象
Message msg = meHandler.obtainMessage();
// 设置消息对象信息
Bundle b = new Bundle();
// 向Handler发送消息,更新UI
b.putInt("key", progress);
msg.setData(b);
meHandler.sendMessage(msg);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//Service中不能直接使用Toast提示信息,推荐如下方式:
//private Handler handler;
//Override
//public void onCreate() {
//Log.i("onCreate", "==onCreate==");
//super.onCreate();
//handler = new Handler(Looper.getMainLooper()); // 使用应用的主消息循环
//}
///**
//* Toast提示(service中toast不能直接显示)
//*/
//private void showToast(final int resId, final Object... formatArgs) {
// handler.post(new Runnable() {
// public void run() {
// Toast.makeText(getApplicationContext(),
// getString(resId, formatArgs), Toast.LENGTH_SHORT)
// .show();
// }
// });
// // 以下方式只能显示一次
// // Looper.prepare();
// // Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
// // Looper.loop();
// }
//}
// try {
// StringBuffer doc = new StringBuffer();
// URL url = new URL(urlStr);
// URLConnection conn = url.openConnection();
// BufferedReader reader = new BufferedReader(new InputStreamReader(
// conn.getInputStream()));
// String line = null;
// while ((line = reader.readLine()) != null)
// doc.append(line);
// reader.close();
// return doc;
// } catch (IOException e) {
// e.printStackTrace();
// }
// return null;
// }
// }
// }
// @Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
// URL url=null;
// URLConnection connection=null;
// InputStream is=null;
// try {
// url = new URL("http://m.weather.com.cn/data/101070201.html");
// connection = url.openConnection();
// connection.setConnectTimeout(5000);
// connection.connect();
// is = connection.getInputStream();
// InputStreamReader isr = new InputStreamReader(is);
// Log.i("xua", isr.toString()) ;
// is.close();
// isr.close();
//
// } catch (MalformedURLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// private String xxx(int xx){
// int a = xx;
// int b = 10;
// int c = a + b;
// String out = "result";
// String result = out + c;
// System.out.println("");
// int d = a*a+b*b;
// textview.setText(""+d);
// return result;
// }
// }
// 2 布局文件main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ProgressBar
android:id="@+id/pro"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></ProgressBar>
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ᅰ�ᄈᆪ"
></Button>
<Button
android:id="@+id/btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ᅲᅮᅬ뽀ᅱᄆ푸잓ᆲᄆᄄᄡ■"
></Button>
<Button
android:id="@+id/btn2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="handler.post(runnable)"
></Button>
<Button
android:id="@+id/btn3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="textView.post(runnable)"
></Button>
<Button
android:id="@+id/btn4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="runOnUiThread(runnable)"
></Button>
<Button
android:id="@+id/btn5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Threadᅧ쇠ᅱᅬᅬᄁᆳᄏᄋ"
></Button>
<Button
android:id="@+id/btn6"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Handlerᅮ→Looperᅬ¢ᄍᆰ "
></Button>
<Button
android:id="@+id/btn7"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="progressbar "
></Button>
<Button
android:id="@+id/btn8"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="异步线程——AsyncTask"
></Button>
<!--<Button
android:id="@+id/btn9"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="progressbar "
></Button>
-->
</LinearLayout>