(94277247)
在不影响当前Activity使用的情况下在其他线程中处理特定工作 异步消息处理
Handler handler=new Handler()
Runable updateThread=new Runnable(){
public void run(){
handler.postDelayed(updateThread,3000); 在3000毫秒以后再将对象加入消息队列(不一定马上执行)
}
}
在start按钮的onClick方法中有一句
handler.post(updateThread); 在此处第一次将消息队列添加进了队列
在end按钮的onClick方法中
handler.removeCallbacks(updateThread);
将线程从队列中移除
消息队列 将消息添加入队列 然后从头取出一条消息处理
每个Handler都有一个与之关联的消息队列
步骤:
创建Handler对象
调用post方法将要执行的线程对象添加到队列中
将要执行的操作写在线程对象run方法中
在run方法内部执行postDelayed或post方法 使循环
Handler中有2个队列
1个线程队列
1个消息队列
Message msg=updateBarHandler.obtainMessage();
得到一个消息对象
msg有arg1,arg2变量(整型) 可用来简单存值 用这2个成员变量传递消息 优点是系统性能消耗较少
msg.arg1=i;
updateBarHandler.sendMessage(msg); 将msg加入到消息队列中
复写handler中的handleMessage方法(每当调用sendMessage加入消息队列,然后用该方法取出msg对象)
调用结束 removeCallbacks(updateThread) 将线程对象从队列中移除
执行过程:
点按钮 执行onClick中的方法
通过post方法将线程加入到队列中
执行了线程中的run方法
通过obtainMessage获取msg对象 并给msg传值
调用sendMessage(msg)将消息加入消息队列
在handler的handleMessage方法中处理消息,并最后再将线程对象post到线程队列 形成循环
当调用removeCallbacks时 结束队列
---------------------------------------------------
Android中集成了一个apache组织提供的一个开源的访问互联网的客户端程序
HttpClient 可以使用它来发送数据
这里有两个方法,是往互联网传送数据时候用的
一个是传送普通文本的,一个是传送带附件的
这两个方法就可以满足我们正常的所有需求了
public class HttpRequester {
public static String post(String actionUrl, Map<String, String> params, FormFile[] files) {
try {
String BOUNDARY = "---------7d4a6d158c9"; //数据分隔线
String MULTIPART_FORM_DATA = "multipart/form-data";
URL url = new URL(/blog_article/actionUrl/index.html);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(6* 1000);
conn.setDoInput(true);//允许输入
conn.setDoOutput(true);//允许输出
conn.setUseCaches(false);//不使用Cache
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {//构建表单字段内容
sb.append("--");
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
sb.append(entry.getValue());
sb.append("\r\n");
}
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.write(sb.toString().getBytes());//发送表单字段数据
for(FormFile file : files){//发送文件数据
StringBuilder split = new StringBuilder();
split.append("--");
split.append(BOUNDARY);
split.append("\r\n");
split.append("Content-Disposition: form-data;name=\""+ file.getFormname()+"\";filename=\""+ file.getFilname() + "\"\r\n");
split.append("Content-Type: "+ file.getContentType()+"\r\n\r\n");
outStream.write(split.toString().getBytes());
outStream.write(file.getData(), 0, file.getData().length);
outStream.write("\r\n".getBytes());
}
byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//数据结束标志
outStream.write(end_data);
outStream.flush();
int cah = conn.getResponseCode();
if (cah != 200) throw new RuntimeException("请求url失败");
InputStream is = conn.getInputStream();
int ch;
StringBuilder b = new StringBuilder();
while( (ch = is.read()) != -1 ){
b.append((char)ch);
}
Log.i("ItcastHttpPost", b.toString());
outStream.close();
conn.disconnect();
return b.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String post(String actionUrl, Map<String, String> params, FormFile file) {
return post(actionUrl, params, new FormFile[]{file});
}
public static String post(String actionUrl, Map<String, String> params) {
HttpPost httpPost = new HttpPost(actionUrl);
List<NameValuePair> list = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {//构建表单字段内容
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200){
return EntityUtils.toString(httpResponse.getEntity());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
}
Handler主要用于异步消息的处理,发送消息与处理消息不是同时进行,用于处理相对耗时较长的操作
Handler在默认情况下 与调用它的Activity是处于同一线程的
post()方法其实相当于直接执行了线程的run方法 而不是调用Thread.start()
因此其实2者还是处于同一线程
可以通过Thread.currentThread().getId()来验证
当用标准Java实现线程(通过一个Runnable对象创建Thread)
2者是处于不同的线程(同样可通过getId验证)
关于Bundle对象(以String为键 其他数据类型为值的Map 和HashMap类似)
特殊的Map(键值类型固定 而非Object)
Android中另开线程
Looper 一般不用自己实现
HandlerThread类 实现了循环处理消息的功能
步骤
new一个HandlerThread对象
调用HandlerThread对象的start方法
创建MyHandler对象(继承Handler类),使用Looper对象(handlerThread.getLooper())
创建Message对象msg(myHandler.obtainMessage方法获得)
调用msg.sendToTarget();(发送到生成msg对象的Handler)
在msg上绑定数据 有msg.arg1 arg2 也可以msg.object这些传递简单数据
当传递比较大的数据时 就用msg.setData(Bundle data)方法
Bundle b=new Bundle();
b.putXXX来存值
在handleMesage方法中,用getData取得Bundle对象
再通过getXXX方法取得相应的值
注意 在调用getLooper方法前 必须先启动HandlerThread.start方法 否则取不到Looper对象