基础学习总结(七)--子线程及Handler
使用子线程获取网络图片
1.采用httpUrlConnection直连方式获取图片
2.采用子线程方式获取
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity" > 7 8 <ImageView android:id="@+id/iv_icon" 9 android:layout_width="fill_parent" 10 android:layout_height="0dip" 11 android:layout_weight="1" /> 12 13 <LinearLayout 14 android:layout_width="fill_parent" 15 android:layout_height="wrap_content" 16 android:orientation="horizontal" > 17 18 <EditText android:id="@+id/et_url" 19 android:layout_width="0dip" 20 android:layout_height="wrap_content" 21 android:layout_weight="1" /> 22 23 <Button android:id="@+id/btn_submit" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:textSize="20sp" 27 android:text="Go" /> 28 29 30 </LinearLayout> 31 </LinearLayout>
1 public class MainActivity extends Activity implements OnClickListener { 2 private final int SUCESS = 0; 3 private final int ERROR=-1; 4 private EditText etUrl; 5 private ImageView ivIcon; 6 7 8 private Handler hand=new Handler(){ 9 /* 10 * 接收信息 11 * */ 12 @Override 13 public void handleMessage(Message msg){ 14 super.handleMessage(msg); 15 if(msg.what==SUCESS){//识别访问handle的程序集 16 ivIcon.setImageBitmap((Bitmap)msg.obj);//设置bitmap显示图片 17 }else if(msg.what==ERROR){ 18 Toast.makeText(MainActivity.this, "抓取异常", 0).show(); 19 } 20 } 21 }; 22 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 29 ivIcon = (ImageView)findViewById(R.id.iv_icon); 30 etUrl = (EditText)findViewById(R.id.et_url); 31 32 findViewById(R.id.btn_submit).setOnClickListener(this); 33 } 34 35 @Override 36 public void onClick(View v) { 37 // TODO Auto-generated method stub 38 final String url=etUrl.getText().toString(); 39 //Bitmap bitmap=getImageFormat(url); 40 //ivIcon.setImageBitmap(bitmap);//设置image显示图片 41 new Thread(new Runnable(){ 42 @Override 43 public void run(){ 44 Bitmap bitmap=getImageFormat(url); 45 if(bitmap!=null){ 46 Message msg=new Message(); 47 msg.what=SUCESS;//设置handle区别码 48 msg.obj=bitmap;//将二进制数据放入msg 49 hand.sendMessage(msg); 50 }else{ 51 Message msg=new Message(); 52 msg.what=ERROR; 53 hand.sendMessage(msg); 54 } 55 } 56 }).start(); 57 58 } 59 60 /** 61 * 根据url链接网络获取图片返回 62 * */ 63 private Bitmap getImageFormat(String url){ 64 HttpURLConnection conn=null; 65 try { 66 URL mUrl=new URL(url); 67 conn =(HttpURLConnection)mUrl.openConnection(); 68 //设置传值方式 69 conn.setRequestMethod("GET"); 70 //设置链接超时时间 71 conn.setConnectTimeout(10000); 72 //设置等待时间 73 conn.setReadTimeout(5000); 74 75 conn.connect(); 76 int code=conn.getResponseCode();//获得服务器响应对象 77 if(code==200){ 78 //访问成功 79 InputStream is=conn.getInputStream();//获得服务器返回的二进制数据 80 Bitmap bitmap = BitmapFactory.decodeStream(is);//将二进制流转换为bitmap图片 81 82 return bitmap; 83 }else{ 84 Log.i("MainActivity","链接不正常了..."); 85 } 86 87 } catch (Exception e) { 88 // TODO Auto-generated catch block 89 e.printStackTrace(); 90 }finally{ 91 if(conn!=null){ 92 conn.disconnect(); 93 } 94 } 95 96 return null; 97 } 98 99 }
权限:<uses-permission android:name="android.permission.INTERNET"/>
在不使用子线程的方式下:等待超时后程序异常
addroid not responding(应用程序无响应)因子程序等待阻塞了主线程 ANR异常
异常:
CalledFrowWrongThreadException:Only the original thread that creaded a view hierarchy can touch its views
只有原始的线程(主线程或ui线程)才能修改view对象
handler处理过程
1 public class MainActivity extends Activity { 2 3 private EditText etUserName; 4 private EditText etPassword; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11 etUserName = (EditText) findViewById(R.id.et_username); 12 etPassword = (EditText) findViewById(R.id.et_password); 13 } 14 15 public void doGet(View v) { 16 final String userName = etUserName.getText().toString(); 17 final String password = etPassword.getText().toString(); 18 19 new Thread( 20 new Runnable() { 21 22 @Override 23 public void run() { 24 // 使用get方式抓去数据 25 final String state = NetUtils.loginOfGet(userName, password); 26 27 // 执行任务在主线程中 28 runOnUiThread(new Runnable() { 29 @Override 30 public void run() { 31 // 就是在主线程中操作 32 Toast.makeText(MainActivity.this, state, 0).show(); 33 } 34 }); 35 } 36 }).start(); 37 } 38 39 public void doPost(View v) { 40 final String userName = etUserName.getText().toString(); 41 final String password = etPassword.getText().toString(); 42 43 new Thread(new Runnable() { 44 @Override 45 public void run() { 46 final String state = NetUtils.loginOfPost(userName, password); 47 // 执行任务在主线程中 48 runOnUiThread(new Runnable() { 49 @Override 50 public void run() { 51 // 就是在主线程中操作 52 Toast.makeText(MainActivity.this, state, 0).show(); 53 } 54 }); 55 } 56 }).start(); 57 } 58 }
1 public class NetUtils { 2 3 private static final String TAG = "NetUtils"; 4 5 /** 6 * 使用post的方式登录 7 * @param userName 8 * @param password 9 * @return 10 */ 11 public static String loginOfPost(String userName, String password) { 12 HttpURLConnection conn = null; 13 try { 14 URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet"); 15 16 conn = (HttpURLConnection) url.openConnection(); 17 18 conn.setRequestMethod("POST"); 19 conn.setConnectTimeout(10000); // 连接的超时时间 20 conn.setReadTimeout(5000); // 读数据的超时时间 21 conn.setDoOutput(true); // 必须设置此方法, 允许输出 22 // conn.setRequestProperty("Content-Length", 234); // 设置请求头消息, 可以设置多个 23 24 // post请求的参数 25 String data = "username=" + userName + "&password=" + password; 26 27 // 获得一个输出流, 用于向服务器写数据, 默认情况下, 系统不允许向服务器输出内容 28 OutputStream out = conn.getOutputStream(); 29 out.write(data.getBytes()); 30 out.flush(); 31 out.close(); 32 33 int responseCode = conn.getResponseCode(); 34 if(responseCode == 200) { 35 InputStream is = conn.getInputStream(); 36 String state = getStringFromInputStream(is); 37 return state; 38 } else { 39 Log.i(TAG, "访问失败: " + responseCode); 40 } 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } finally { 44 if(conn != null) { 45 conn.disconnect(); 46 } 47 } 48 return null; 49 } 50 51 /** 52 * 使用get的方式登录 53 * @param userName 54 * @param password 55 * @return 登录的状态 56 */ 57 public static String loginOfGet(String userName, String password) { 58 HttpURLConnection conn = null; 59 try { 60 String data = "username=" + URLEncoder.encode(userName) + "&password=" + URLEncoder.encode(password); 61 URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data); 62 conn = (HttpURLConnection) url.openConnection(); 63 64 conn.setRequestMethod("GET"); // get或者post必须得全大写 65 conn.setConnectTimeout(10000); // 连接的超时时间 66 conn.setReadTimeout(5000); // 读数据的超时时间 67 68 int responseCode = conn.getResponseCode(); 69 if(responseCode == 200) { 70 InputStream is = conn.getInputStream(); 71 String state = getStringFromInputStream(is); 72 return state; 73 } else { 74 Log.i(TAG, "访问失败: " + responseCode); 75 } 76 } catch (Exception e) { 77 e.printStackTrace(); 78 } finally { 79 if(conn != null) { 80 conn.disconnect(); // 关闭连接 81 } 82 } 83 return null; 84 } 85 86 /** 87 * 根据流返回一个字符串信息 88 * @param is 89 * @return 90 * @throws IOException 91 */ 92 private static String getStringFromInputStream(InputStream is) throws IOException { 93 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 94 byte[] buffer = new byte[1024]; 95 int len = -1; 96 97 while((len = is.read(buffer)) != -1) { 98 baos.write(buffer, 0, len); 99 } 100 is.close(); 101 102 String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 103 104 // String html = new String(baos.toByteArray(), "GBK"); 105 106 baos.close(); 107 return html; 108 } 109 }
作者:大胖儿在努力
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。