美文网首页
八、线程间的通信Handler

八、线程间的通信Handler

作者: 浮生若梦OvO | 来源:发表于2019-06-20 22:01 被阅读0次

    一、主题与样式

    样式与主题: 主要是为了设置 app的显示效果

    • 样式:
    image.png

    而这里的样式, 都是 在values文件夹下的 styles.xml文件中定义好的


    image.png
    • 主题:是用来设置 activity的显示风格 .


      image.png

      同样的, 在 styles 文件中又 有了 apptheme , 并且可以 继承.


      image.png

    二、国际化

    应用程序中一些常见的字符、图片、类型值以及一些提示信息都应该符合当地的语言和阅读习惯,简称i18n。

    三、网络连接相关(重要)

    • 入门程序-网络图片查看器

    a、 网络连接不能在主线程中运行,主线程中是不允许干耗时的事儿的,需要将连接网络的代码 放到 子线程中去做.

    b、只有在创建 该 view对象 的 线程里才可以去 更新当前view 中的数据,只有在主线程中才可以去 修改UI界面
    由于涉及到线程间通信, 而线程间通信又涉及到线程的互斥,唤醒... 等操作, 这个代码写起来非常的复杂,所以,谷歌工程师提供了handler , 我们只需要去使用一些就可以了. 事实上 这里 的handler 内部也是 通过线程互斥来实现的.

    c、android中 还有 一套 保护机制

    为了提高用户的感受, 如果一个 应用程序 干了某个耗时的事儿 ,但是这个耗时的事儿又没有被检测

    出来, 并且 耗时也的确很长 , 那么这个时候, 系统就提供了另外的一套 保护机制.

    如果长时间应用程序无任何响应 , 那么会报ANR (application not responding ), 应用程序无响应 .

    在android 中不同的组件中 , ANR机制 生效的时间 也是不一样的 .

    在activity 中, ANR生效的 时间 是 5 秒钟

    在 service 中,ANR生效的 时间 是 10秒钟

    d、网络图片查看器的代码:

    public class  MainActivity extends Activity {
    
       private static final int SUCCESS = 0;
       protected static fina int ERROR = 1;
       EditText et_path;
       ImageView iv_pic;
    
        // 1、在主线程中创建handler的成员变量
    
        @Override
    
        protected void  onCreate(Bundle savedInstanceqState) {
    
             super.onCreate(savedInstanceState);
    
             setContentView(R.layout. activity_main);
    
              // 初始化
    
              et_path = (EditText) findViewById(R.id.et_path);
    
              iv_pic = (ImageView) findViewById(R.id.iv_pic );
    
        }
    
      private Handler handler = new Handler() {
    
              public void  handleMessage(android.os.Message msg) {
    
                   switch  (msg.what ) {
    
                   case SUCCESS  :
    
                     Bitmap bitmap = (Bitmap) msg. obj;
    
                      iv_pic.setImageBitmap(bitmap);
    
                      break ;
    
                   case ERROR  :
    
                     Toast. makeText(MainActivity.this, "对不起, 出错了.  " , 0).show();
    
                     break;
    
                  default:
    
                      break;
    
                 }
    
             };
    
        };
    
        String path;
    
        public void select(View v) {
    
              // 获取地制值
    
              path = et_path .getText().toString().trim();
    
              // 判断地址
    
              if (TextUtils.isEmpty( path)) {
    
                 Toast. makeText(this, "地址栏不能为空" , 0).show();
    
                  return;
             }
    
              // 连接网络,需要开启一个子线程
    
              new Thread() {
    
                  public void run() {
    
                      try{
    
                           // 1、创建URL对象,打开一个HTTP类型的连接
    
                          URL url = new URL(path );
    
                          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    
                           // 2、设置请求方式GET、POST,连接的超时时间等请求参数
    
                          conn.setRequestMethod( "GET");
    
                          conn.setReadTimeout(3000);
    
    // 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
    
                           // 判断响应码是不是200
    
                           int code = conn.getResponseCode();
    
                           if (code == 200) {
    
                               // 4、把二进制流的响应数据转换成需要的数据类型:
    
                              InputStream in = conn.getInputStream();
    
                               // 这个流是 一个 图片的数据, 那么需要将 流 转换为 图片
    
                              Bitmap bitmap = BitmapFactory.decodeStream(in);
    
                               // 5、将图片数据放到ImageView中显示
    
                               // iv_pic.setImageBitmap(bitmap);
    
                              Message msg = Message.obtain();
    
                              msg. obj = bitmap;
    
                               // 成功
    
                              msg. what = SUCCESS ;
    
                               handler.sendMessage(msg);
    
                          }
    
                     } catch (Exception e) {
    
                          Message msg = Message.obtain();
    
                          msg. what = ERROR ;
    
                           handler.sendMessage(msg);
    
                          e.printStackTrace();
    
                     }
    
                 };
    
             }.start();
    
        }
    
    }
    

    四、解析xml文件(手机号码吉凶测试)

    public class  MainActivity extends  Activity {
    
        protected static final int SUCCESS  = 0;
    
        protected static final int ERROR  = 1;
    
        EditText et_number;
    
        TextView tv_result;
    
        @Override
    
         protected void  onCreate(Bundle savedInstanceState) {
    
             super.onCreate(savedInstanceState);
    
             setContentView(R.layout. activity_main);
    
              // 初始化
    
              et_number = (EditText) findViewById(R.id.et_number);
    
              tv_result = (TextView) findViewById(R.id.tv_result );
    
        }
    
        private Handler handler = new Handler() {
    
              public void handleMessage(android.os.Message msg) {
    
                 switch (msg.what ) {
    
                 case SUCCESS :
    
                  Product value=  (Product) msg. obj;
    
                  tv_result.setText(value.toString());
    
                   break;
    
                 case ERROR :
    
                     Toast. makeText(MainActivity.this, "对不起,程序出错了" , 0).show();
    
                      break;
    
                  default:
    
                     break;
    
                 }
    
             };
    
        };
    
        public void ceshi(View v) {
    
             String number = et_number.getText().toString().trim();
    
               if  (TextUtils.*isEmpty*(number)) {
    
                 Toast. makeTextthis, "对不起,手机号码不能为空" , 0).show();
    
                return;
    
             }
    
              new Thread() {
    
                  public void run() {
    
                      try {
    
                          URL url = new URL("http://188.188.5.52:8080/phone.xml" );
    
                          HttpURLConnection conn = (HttpURLConnection) url
    
                                   .openConnection();
    
                           // 设置连接超时
    
                          conn.setConnectTimeout(3000);
    
                          conn.setRequestMethod( "GET");
    
                           // 获取相应状态吗
    
                           int code = conn.getResponseCode();
    
                           if (code == 200) {
    
                               // 拿到数据
    
                              InputStream in = conn.getInputStream();
    
                               // 使用pull解析器解析
    
                              XmlPullParser parser = Xml.newPullParser();
    
                               // 设置输入流和编码机
    
                              parser.setInput(in, "UTF-8");
    
                               // 获取标签的类型
    
                              int type = parser.getEventType();
    
                              Product p = new Product();
    
                               while (type != XmlPullParser.END_DOCUMENT ) {
    
                                    if (type == XmlPullParser.START_TAG ) {
    
                                        if (parser.getName().equals("product" )) {
    
                                           String ptype = parser.getAttributeValue(0);
    
                                           p.setType(ptype);
    
                                       } else if (parser.getName().equals("phonenum" )) {
    
                                           String phonenum = parser.nextText();
    
                                           p.setPhonenum(phonenum);
    
                                       } else if (parser.getName().equals("location" )) {
    
                                           String location = parser.nextText();
    
                                           p.setLocation(location);
    
                                       } else if (parser.getName().equals("phoneJx" )) {
    
                                           String phoneJx = parser.nextText();
    
                                           p.setPhoneJx(phoneJx);
    
                                       }
    
                                   }
    
                                   type = parser.next();
    
                              }
    
                               // handler帮助完成线程间的通信
    
                              Message msg = Message.*obtain*();
    
                              msg. obj = p;
    
                              msg. what = *SUCCESS* ;
    
                               handler.sendMessageAtFrontOfQueue(msg);
    
                          }
    
                     } catch (Exception e) {
    
                          e.printStackTrace();
    
                          Message msg = Message.obtain();
    
                          msg. what = ERROR ;
    
                          handler.sendMessageAtFrontOfQueue(msg);
    
                     }
    
                 };
    
             }.start();
    
        }
    
    }
    

    五、解析Json文件

    Json数据的两种格式 :

    第一种: json 对象 ---- {key:value,key:value,key:value}

    第二种: json 数组------- [value1,value2,value3,value4]

    第三种: 混合的数组中包含了 对象

    注:Json数据的key始终都是字符串,但value的值 比较随意。

    天气预报案例:将in流数据转换成Json数据?


    image.png
    image.png

    相关文章

      网友评论

          本文标题:八、线程间的通信Handler

          本文链接:https://www.haomeiwen.com/subject/rinlqctx.html