zoukankan      html  css  js  c++  java
  • (十二)handler消息处理机制

    (一)android:layout_weight 在不同情况下的意义。

         当 android:layout_width  和 android:layout_height都不为0的时候,android:layout_weight代表的是控件渲染的优先级,值越大,渲染的优先级越低。默认android:layout_weight=0。

         当 android:layout_width  或 android:layout_height为0的时候,android:layout_weight才代表权重,值越大,权重越大。

    (二)网络图片查看器的功能需求:根据给定的URL地址,去访问网络获取图片, 将获取的图片显示在界面中。程序界面运行如下:

    (三)网络图片查看器的activity_main.xml文件

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools
    ="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.networkviewimage.MainActivity" > <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" /> <EditText android:id="@+id/et_path" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:text="http://f.hiphotos.baidu.com/image/pic/item/95eef01f3a292df535a659dabe315c6035a8739c.jpg" android:hint="请输入网络图片的地址" /> <Button android:text="浏览" android:id="@+id/bt_setImageView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:onClick="click" /> </LinearLayout>
    (三)
    MainActivity.java源码:
    package com.example.networkviewimage;
    
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    
    import java.net.URL;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
        protected static final int CHANGE_UI = 1;
        protected static final int ERROR = 2;
        public ImageView iv;
        public EditText et_path;
    
        // 创建消息处理器
        private Handler handler = new Handler() {
    
            @Override
            public void handleMessage(Message msg) {
                
                switch (msg.what) {
                case CHANGE_UI:
                    iv.setImageBitmap((Bitmap) msg.obj);
                    break;
                case ERROR:
                    Toast.makeText(MainActivity.this, "获取图片失败", 0).show();
                    break;
    
                }
            }
    
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            iv = (ImageView) this.findViewById(R.id.iv);
            et_path = (EditText) this.findViewById(R.id.et_path);
        }
    
        public void click(View v) {
            final String path = et_path.getText().toString().trim();
            if (TextUtils.isEmpty(path)) {
                Toast.makeText(this, "网络图片的路径不能为空", 0).show();
            } else {
                // 连接服务器,获得图片。由于访问网络是个耗时的错误,所以必须在子线程中访问网络(在androi4.0以上的特性)
                new Thread(new Runnable() {
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
    
                            URL url = new URL(path);
                            // 根据url发送http请求
                            HttpURLConnection conn = (HttpURLConnection) url
                                    .openConnection();
    
                            conn.setConnectTimeout(5000); // 设置连接的超时时间
                            conn.setReadTimeout(5000); // 设置读数据的超时时间
                            conn.setRequestMethod("GET"); // 设置请求方式
    
                            int code = conn.getResponseCode(); // 得到服务器返回的响应码,200代表0K,404代表资源没有找到,503代表服务器内部错误
                            if (code == 200) {
                                InputStream is = conn.getInputStream(); // 从服务器获得的数据流,在此为从服务器获得图片
                                Bitmap bitmap = BitmapFactory.decodeStream(is); // 把流里面内容转化为Bitmap
                                // iv.setImageBitmap(bitmap);
                                // 告诉主线程,帮我更改界面,内容是bitmap
                                Message msg = new Message();
                                msg.what = CHANGE_UI;   
                                msg.obj = bitmap;
    
                                handler.sendMessage(msg);
    
                            } else {
    
                                Message msg = new Message();
                                msg.what = ERROR;
    
                                handler.sendMessage(msg);
                            }
    
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            Message msg = new Message();
                            msg.what = ERROR;
                            handler.sendMessage(msg);
                            // Toast.makeText(MainActivity.this, "获取图片失败",
                            // 0).show();  土司也是UI,如果执行catch直接弹出Toast会出错
                        }
                    }
                }).start();
            }
    
        }
    }

    (五)由于需要访问网络,所以需要在AndroidManifest.xml加入权限: <uses-permission android:name="android.permission.INTERNET" />

    (六)需要注意的地方:

       1、访问网络是个耗时间的操作,必须在子线程执行。

       2、访问网络需要权限。

       3、UI操作只能在主线程执行,如果子线程要修改UI,则通过handler消息处理机制,首先在主线程创建一个消息处理器handler对象,然后子线程通过消息处理器handler发送一个消息给主线程,消息按时间顺序从小到大将被放在主线程的消息队列里面,主线程里面有一个looper消息的轮询器,如果轮询器发现了消息,则调用handlerMessage方法处理消息。大概原理机制如下图所示:

     
  • 相关阅读:
    03把IL编译成可执行文件
    02值类型
    报错:该字符串未被识别为有效的DateTime
    01使用ILDasm.exe将可执行文件反编译成IL代码
    MVC自定义路由02-实现IRouteConstraint限制控制器名
    MVC自定义路由01-为什么需要自定义路由
    报错:System.Data.Entity.Infrastructure.DbUpdateException 更新条目时出错
    输入网址背后发生的故事
    使用jquery加载部分视图02-使用$.ajax()
    使用jquery加载部分视图01-使用$.get()
  • 原文地址:https://www.cnblogs.com/fuyanan/p/4080201.html
Copyright © 2011-2022 走看看