Android消息机制与异步任务

 1. 消息机制:

 Message:   线程通信用于携带数据,数据载体
     创建对象:Message.obtain(what)
     属性:
     public int what  // id标识
     int arg1
     Object obj // 用于数据存储
     when:  当前时间+ 延迟时间(如果有)【处理时间消息】
     Handler target :  用来处理消息的Hander对象,就是发消息的Handler
     Runnable callback: 用来处理消息的回调器(一般不用)【Runnable什么时候在子线程中执行,被new Thread(Runnable)的时候】
     Message next: 指向下一个message的链表
     Message sPool:  用来缓冲使用处理过的Message对象,以便复用
     Handler: 
     Handler是 Message 的处理器,负责消息发送【把消息加入消息队列】和移除消息工作
     sendMessage(Message msg)  发送消息
     sendMessageDelayed(Message msg,long time): 发送延迟消息,不是延迟发送,而是立即发送,延迟处理
     removeMessages:移除未处理的消息 【把消息从消息队列中移除】
     MessageQueue:  优先级消息队列,先进先出
     优先级队列:按照when排序的优先级队列
     优先级队列:数据结构是链表, next指针指向下一个节点,更新的时候直接把链表断开指向其他的节点即可,不用排序
     比如发送了A消息,发送了B,有发送了C,C延迟3次,那么C插入到队列最后
     Looper: 循环器
     负责循环取出MessageQueue中当前需要处理的消息.
     交给对应的Handler 进行处理
     处理以后,把Message缓存到消息池,后面备用

Message.obtain(what): 从消息池中取出Messaeg,而不是New

Handler机制:
   Handler发送Message,放入消息队列MessageQueue, Looper从MeesageQueue中取出
   Message, 调用Handler 处理 , 处理完毕清理 Message, 放入Meesage 消息池备用

 //Handler 负责处理消息
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 100:
                    Toast.makeText(MainActivity.this,"chului",Toast.LENGTH_SHORT).show();

                    break;
            }
        }
    };
	   public void  testHander(){
        new Thread(){
            @Override
            public void run() {
                super.run();
                // 从消息队列中取出消息
                Message msg=Message.obtain();
                // Msg 标识
                msg.what= 100;
                // msg 携带内容
                msg.obj="携带内容";
                // handler负责发送消息
                handler.sendMessage(msg);
                //  发消息之前首先移除,做倒计时的时候
//                handler.removeMessages(100);
//                handler.sendEmptyMessage(100);

            }
        }.start();
    }

 2. AsyncTask:

就是对Handler 和 Thread的封装,比tread效率更高,里面封装了线程池
 如何使用:
   onPreExecute       // 在UI线程   显示loading
 doInBackground   // 在子线程       做耗时任务
onPostExecute(Void aVoid):   //  执行完毕

  如果doInBackground 下载时候要更新UI如何解决:
     调用 publishProgress(len);
     回调:
     onProgressUpdate(Integer... values)  在UI线程

  使用AsyncTask下载图片:

private File apkFile;
    private ProgressDialog dialog;
    Bitmap newBitmap=null;
    public void testasync(){
        new AsyncTask<Void,Integer,Void>(){

            // 在UI线程
            @Override
            protected void onPreExecute() {

                dialog = new ProgressDialog(MainActivity.this);
                dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                dialog.show();

                //  storage/sdcard/Android/package_name/files/1.png
                apkFile = new File(getExternalFilesDir(null), "1.png");
                if(apkFile.exists()){
                    apkFile.delete();
                }
                super.onPreExecute();
            }
            // 在子线程
            @Override
            protected Void doInBackground(Void... params) {


                try {
                    //1. 得到连接对象
                    String path = "http://192.168.2.110:8080/Web001/1.png";
                    URL url = new URL(path);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    //2. 设置
                    //connection.setRequestMethod("GET");
                    connection.setConnectTimeout(5000);
                    connection.setReadTimeout(10000);
                    //3. 连接
                    connection.connect();
                    //4. 请求并得到响应码200
                    int responseCode = connection.getResponseCode();
                    if(responseCode==200) {
                        //设置dialog的最大进度
                        dialog.setMax(connection.getContentLength());

                        //5. 得到包含APK文件数据的InputStream
                        InputStream is = connection.getInputStream();


                        // 如果是图片,不使用进度条,那么可以这么使用
                     //   newBitmap=BitmapFactory.decodeStream(is);


                        //6. 创建指向apkFile的FileOutputStream
                        FileOutputStream fos = new FileOutputStream(apkFile);
                        //7. 边读边写
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while((len=is.read(buffer))!=-1) {
                            fos.write(buffer, 0, len);
                            //8. 显示下载进度
                            dialog.incrementProgressBy(len);
                            // 现在在子线程下载
                            // 如何更新UI进度条,调用这个方法,那么就会触发
                            // onProgressUpdate 方法在UI线程
                            publishProgress(len);
                            //休息一会(模拟网速慢)
                            //Thread.sleep(50);
                            SystemClock.sleep(50);
                        }

                        fos.close();
                        is.close();
                    }
                    //9. 下载完成, 关闭, 进入3)
                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return null;
            }
            // 在 UI线程
            @Override
            protected void onProgressUpdate(Integer... values) {
                dialog.incrementProgressBy(values[0]);
                super.onProgressUpdate(values);
            }
            // 执行完毕在主线程
            @Override
            protected void onPostExecute(Void aVoid) {
                dialog.dismiss();
                Bitmap bitmap=  BitmapFactory.decodeFile(apkFile.getAbsolutePath());
                myview.setImageBitmap(bitmap);
              //  myview.setImageBitmap(newBitmap);

                super.onPostExecute(aVoid);
            }
        }
                .execute();
    }

效果:

 

3. Json使用

结构:
 Json数组:[ value,value2]     相当于Java的数组
 Json对象:{ key:value}        相当于Java的对象、或者Map
 value数据类型:
  数值 、字符串、null、jons数组 [] 、json对象 {}
 ** Json数据解析
  Android原生 API只可以把 Json转化为对象 
  3.1.使用Android原生Api   Json转实体类、 Json转List<X>

// Android原生Api  JsontoBean
    public void jsonToBean()  throws JSONException{
        String jsonString = "{\"id\":2, \"name\":\"大虾\"}";
        JSONObject jsonObject=new JSONObject(jsonString);
        int id= jsonObject.getInt("id");
        String name = jsonObject.getString("name");
        Person p=new Person(id,name);
        Log.e("denganzhi",p.toString());
    }
   // Android原生Api  Json转化为List<X>
    public void jsonToLIstBean() throws JSONException {
        String jsonString = "[{\"id\":3, \"name\":\"大虾\"},"
                + "{\"id\":5, \"name\":\"大虾2\"}]";
        List<Person> list=new ArrayList<>();
        JSONArray jsonArray=new JSONArray(jsonString);
        for (int i=0;i<jsonArray.length();i++){
            JSONObject jsonObject=  jsonArray.getJSONObject(i);
            int id= jsonObject.getInt("id");
            String name = jsonObject.getString("name");
            Person p=new Person(id,name);
            list.add(p);
        }
        Log.e("denganzhi",list.toString());
    }

3.2.使用Gson   Json转实体类、 Json转List<X>  、Json 转化Map 

 //Gson 使用
    public void sendMsg(View view) {
        // Json转化为Json对象或者List对象
        String jsonString = "{\"id\":2, \"name\":\"大虾\"}";
        // 转化为实体类
        Person p1 = new Gson().fromJson(jsonString,Person.class);
        String jsonStringArr = "[{\"id\":3, \"name\":\"大虾\"},"
                + "{\"id\":5, \"name\":\"大虾2\"}]";
        // 转化为List
        List<Person> list = new Gson().fromJson(jsonStringArr,new TypeToken<List<Person>>(){}.getType());
        Log.e("denganzhi","p1:"+p1);
        Log.e("denganzhi",list.toString());
        // 对象、List  转化为json字符串
        Log.e("denganzhi",new Gson().toJson(p1));
        // 问题,如果服务器修改了属性名,和本地实体类属性对不上, Json转化为Map
        Map<String,Object> map=new Gson().fromJson(jsonString,new TypeToken<Map<String,Object>>(){}.getType());
        testasync();
        Log.e("denganzhi",new Gson().toJson(p1));
    }
发布了75 篇原创文章 · 获赞 68 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/dreams_deng/article/details/104721595
今日推荐