基础学习总结(七)--子线程及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 }
View Code

权限:<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 }
View Code
  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 }

原文地址:https://www.cnblogs.com/cuijl/p/4587992.html