(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对象