• HttpURLConnection 传输数据和下载图片


    一、传输字符串数据

             在Android中HttpURLConnection传输数据是必不可少的,我们继续在“AsyncTask(异步任务)”案例的基础上添加。

      案例:

          首先我们做一个jsp的服务端,文件名为test1.jsp。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%><% 
        
        String a = "1234567";
        
        String lastId = request.getParameter("lastId");
        if (lastId==null){
            lastId = "0";
        }
        
        int int_a = Integer.valueOf(a);
        int int_lastId = Integer.valueOf(lastId);
        
        out.print(int_a + int_lastId);
    %>

       1、定义一个String类型的变量用来返回给客户端的字符串"1234567"。

       2、通过客户端的lastId的参数值来判断是否请求。

       3、通过out.print返回数据给客户端。

           MainActivity.java文件:

    public class MainActivity extends Activity {
        private SimpleAdapter sa;
        private Button btn;
        private TextView tv;
        private List<Userinfos> list=new ArrayList<Userinfos>();
    
        private List<Map<String,Object> > messageList2 = new ArrayList<Map<String,Object> >();
        private BaseAdapter adapter;
        private ListView lv;  
        private Runnable doInBackground1;
        private Runnable doInBackground2;
        private Runnable doInBackground3;
        private Handler handler;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            //这里是UI主线程 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //gdnf_class@126.com
           
            for (int i = 0; i < 5; i++) {
                Userinfos u = new Userinfos();
                u.setName("小明"+i);
                u.setSex("男"+i);
                list.add(u);
            }
            lv=(ListView)this.findViewById(R.id.listView1);
     
            tv=(TextView)findViewById(R.id.textView1);
            btn=(Button)findViewById(R.id.button1);
            btn.setOnClickListener(new OnClickListener(){
    
                  //模拟数据访问产生数据
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Take tk=new Take(MainActivity.this);//同步任务
                    tk.execute(list,adapter);//参数是传给doInBackground
                  
                }});
            adapter=new BaseAdapter(){
    
                @Override
                public int getCount() {
                    // TODO Auto-generated method stub
                    return list.size();
                }
    
                @Override
                public Object getItem(int position) {
                    // TODO Auto-generated method stub
                    return null;
                }
    
                @Override
                public long getItemId(int position) {
                    // TODO Auto-generated method stub
                    return 0;
                }
    
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    // TODO Auto-generated method stub
                    LayoutInflater inflater = MainActivity.this.getLayoutInflater();
                    View vw;
            
                    if(convertView==null)
                    {
                        Log.i("View","创建对象");
                        vw = inflater.inflate(R.layout.item, null);
                        
                    }
                    else
                    {
                        vw=convertView;
                    }
                    TextView tv_username = (TextView)vw.findViewById(R.id.username);
                    TextView tv_sex = (TextView)vw.findViewById(R.id.sex);
                    tv_username.setText(list.get(position).getName());
                    tv_sex.setText(list.get(position).getSex());
                    return vw;
                    
                }};
        
                 lv.setAdapter(adapter);
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
            
        }
      
    }

              通过 Button的点击事件,传参数是传给doInBackground,进入客户端的后台进行操作。

        Take.java文件:

    public class Take extends AsyncTask{
        private MainActivity activity;
        private  BaseAdapter adapter;
        private List<Userinfos> list=new ArrayList<Userinfos>();
        private static final String URL_STR="http://android2017.duapp.com/test1.jsp";
        private String errorMessage = "";
        private String lastId = "5";
        protected Take(MainActivity activity)
        {
            this.activity=activity;
        }
        //后台运行(数据库,蓝牙,互联网)
        @Override
        protected Object doInBackground(Object... params) {
      
            list = (List<Userinfos>) params[0];
            adapter = (BaseAdapter) params[1];
            try {
                //发送数据
                 注释二URL ul = new URL(URL_STR);
                HttpURLConnection http = (HttpURLConnection) ul.openConnection();
                // 对连接进行配置
                http.setDoInput(true);// 输入
                http.setDoOutput(true);// 输出
                http.setRequestMethod("POST");
                // 防止读取脏数据
                http.setUseCaches(false);
                // 获取一个输出流
                OutputStream os = http.getOutputStream();
                // DataOutputStream数据输出流
                DataOutputStream str = new DataOutputStream(os);
                str.writeBytes("lastId=" + URLEncoder.encode(lastId, "UTF-8"));// 編碼
                str.flush();// 刷新,将数据发到缓冲区。
                str.close();if (http.getResponseCode() == 200) {
                    //读取数据
                    // 输入流
                     注释二InputStream inst = http.getInputStream();// 
                    // reader(注意UTF-8读)
                    InputStreamReader isr = new InputStreamReader(inst, "UTF-8");
                    // 缓冲区,防止读死
                    BufferedReader br = new BufferedReader(isr);
                    String ReadOneline = null;
                    // 多行数据时,减少不断创建String对象
                    StringBuffer sb = new StringBuffer();
                    while ((ReadOneline = br.readLine()) != null) {
                        sb.append(ReadOneline);
                    }
                    inst.close();
                    isr.close();
                    br.close();
                    http.disconnect();
                    return sb.toString();
        
                    
                } else {
    
                    errorMessage = "服务器繁忙,请稍后再试(" + http.getResponseCode() + ")";
                    return "errorserver";
    
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                errorMessage = e.getMessage();
                return "errorclient";
            }
        
        }
        //准备
        @Override
        protected void onPreExecute() {
            Toast.makeText(activity, "今晚有约", Toast.LENGTH_SHORT).show();
            super.onPreExecute();
        }
        //做完后执行
       @Override
      protected void onPostExecute(Object result) {
            // result的值为doInBackground方法的返回值
            String tr = result.toString();
            Log.i("d",""+tr);
            TextView tv = (TextView) activity.findViewById(R.id.textView1);
            /* tv.setText("访问完成!"+tr); */
            //空指针
            if ("errorclient".equals(tr)) {
                if (errorMessage.indexOf("No add") != -1) {
                    tv.setText("网络不通");
                } else {
                    tv.setText("访问网络时其它异常:" + errorMessage);
                }
    
            } else if ("errorserver".equals(tr)) {
                tv.setText(errorMessage);
            } else {
                tv.setText(tr);
            }
    
      }
       //分步完成
       //onProgressUpdate更新进度条
       @Override
    protected void onProgressUpdate(Object... values) {
        // TODO Auto-generated method stub
            Log.i("dd", "进入分步");
            int bar = Integer.parseInt(values[0].toString());
            bar = (bar + 1) * 20;
            ProgressBar progressBar = (ProgressBar) activity
                    .findViewById(R.id.progressBar1);
            progressBar.setProgress(bar);
            adapter.notifyDataSetChanged();
            // 这里是UI主线程
        }
    }

    1、URL_STR是我们发布服务的地址。

    2、我们通过地址加上参数lastid

    3、通过HttpURLConnection等相关设置连接服务发起请求。

    4、OutputStream等流来传递和读取数据(注:由于上一章详解过在这就不多说) 

    5、通过onPostExecute方法将读取到的数据赋值给textView1

    二、下载图片:

                互联网传递二进制流

    我们添加一take2img的类同样继承于AsyncTask,进行相关的操作。

    take2img.java文件:

        //下载图片
            private MainActivity activity;
            private  BaseAdapter adapter;
            private static final String URL_img_STR = "http://cms-bucket.nosdn.127.net/c476803813014a5fa865f22c0faa340320161208080029.jpeg";
            private String errorMessage = "";
            private Bitmap bitmap;
        
            protected Take2img(MainActivity activity)
            {
                this.activity=activity;
            }
        @Override
        protected Object doInBackground(Object... params) {
            try {
                URL ul=new URL(URL_img_STR);
                Log.i("d","dddddd2");
                HttpURLConnection http = (HttpURLConnection)ul.openConnection();//创建连接对象
                // 对连接对象进行配置
                http.setDoInput(true);// 输入         
                http.setDoOutput(false);// 输出
                http.setRequestMethod("GET");
                if (http.getResponseCode() == 200) {
                
                    InputStream inst=http.getInputStream();
                    bitmap= BitmapFactory.decodeStream(inst);
                
                    inst.close();
                    http.disconnect();
                    return "ere";
                } else {
    
                    errorMessage = "服务器繁忙,请稍后再试(" + http.getResponseCode() + ")";
                    return "errorserver";
    
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
            return null;
        }
      //做完后执行
           @Override
          protected void onPostExecute(Object result) {
                // result的值为doInBackground方法的返回值
                String tr = result.toString();
                TextView tv = (TextView) activity.findViewById(R.id.textView1);
                /* tv.setText("访问完成!"+tr); */
                if ("errorclient".equals(tr)) {
                    if (errorMessage.indexOf("No add") != -1) {
                        tv.setText("网络不通");
                    } else {
                        tv.setText("访问网络时其它异常:" + errorMessage);
                    }
    
                } else if ("errorserver".equals(tr)) {
                    tv.setText(errorMessage);
                } else {
                    tv.setText(tr);
                    ImageView img=(ImageView) activity.findViewById(R.id.imageView1);
                    img.setImageBitmap(bitmap);
                }
    
                super.onPostExecute(result);
          }
          
    
    }

    1、URL_img_STR 网络图片路径。

    2、由于是读取图片所以设置输出为false,GET请求。

    3、通过HttpURLConnection等相关设置连接服务发起请求。

    4、设置Bitmap变量缓存图片。

    5、通过onPostExecute方法设置imageView1图片。

     效果图:

             

                

    三、传递集合(JSON格式)

         首先我们将test1.jsp修改一下:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%><%@ page import="java.util.*,com.fasterxml.jackson.databind.*"%><% 
        
                //解决中文问题,以及缓存问题
                //http1.1浏览器
                response.setHeader("Cache-Control", "no-cache");
                //http1.0浏览器
                response.setHeader("Prama", "no-cache");
                //提醒过期1.0,1.1都支持
                response.setDateHeader("Expires", 0);
                //控制输出流
                response.setCharacterEncoding("UTF-8");
                //告之浏览器
                response.setHeader("content-type","text/json;charset=UTF-8");
                //保证获取过来的参数为UTF8,否则乱码
                request.setCharacterEncoding("utf-8");
                
        
        String a = "1234567";
        
        
        
        
        String lastId = request.getParameter("lastId");
        if (lastId==null){
            lastId = "3";
        }
        int count = Integer.valueOf(lastId);
        
        class User {
            
            private String username;
            private String sex;
            public String getUsername() {
                return username;
            }
            public void setUsername(String username) {
                this.username = username;
            }
            public String getSex() {
                return sex;
            }
            public void setSex(String sex) {
                this.sex = sex;
            }
        }
        List<User> userList = new ArrayList<User>();
        for(int i=0;i<count;i++){
            User u = new User();
            u.setUsername("明明"+i);
            u.setSex("女"+i);
            userList.add(u);
        }
        ObjectMapper mapper = new ObjectMapper();
        String jsonStr = mapper.writeValueAsString(userList);
        out.print(jsonStr);
        /*
        int int_a = Integer.valueOf(a);
        int int_lastId = Integer.valueOf(lastId);
        
        out.print(int_a + int_lastId);
        */
    %>

    1、创建一个User类,添加了username,sex两个字段,通过List<user>对该类赋值添加数据。

    2、设置了一个count变量通过 request.getParameter("lastId")方法获取客户端传递过来的lastId参数值。

    3、同过map 的writeValueAsString方法转换成JSON格式。

    4、通过out.print()方法返回给客户端。

    take.java文件:

    public class Take extends AsyncTask{
        private MainActivity activity;
        private  BaseAdapter adapter;
        private List<Userinfos> list=new ArrayList<Userinfos>();
        private static final String URL_STR="http://android2017.duapp.com/test1.jsp";
        private String errorMessage = "";
        private String lastId = "5";
        protected Take(MainActivity activity)
        {
            this.activity=activity;
        }
        //后台运行(数据库,蓝牙,互联网)
        @Override
        protected Object doInBackground(Object... params) {
     
            list = (List<Userinfos>) params[0];
            adapter = (BaseAdapter) params[1];
            try {
                  
                URL ul = new URL(URL_STR);
                HttpURLConnection http = (HttpURLConnection) ul.openConnection();
                // 对连接进行配置
                http.setDoInput(true);// 输入
                http.setDoOutput(true);// 输出
                http.setRequestMethod("POST");
                // 防止读取脏数据
                http.setUseCaches(false);
                // 获取一个输出流,
                OutputStream os = http.getOutputStream();
                // DataOutputStream数据输出流
                DataOutputStream str = new DataOutputStream(os);
                str.writeBytes("lastId=" + URLEncoder.encode(lastId, "UTF-8"));// 編碼
                str.flush();// 刷新,将数据发到缓冲区。
                str.close();
            
                
                if (http.getResponseCode() == 200) {
                                                
                    Log.i("状态","200");
                    
                    //读取数据
                    // 输入流
                    InputStream inst = http.getInputStream(); 
                    // reader(注意UTF-8读)
                    InputStreamReader isr = new InputStreamReader(inst, "UTF-8");
                    // 缓冲区,防止读死
                    BufferedReader br = new BufferedReader(isr);
                    String ReadOneline = null;
                    // 多行数据时,减少不断创建String对象
                    StringBuffer sb = new StringBuffer();
                    while ((ReadOneline = br.readLine()) != null) {
                        sb.append(ReadOneline);
                    }
                    
                    
                    
                    
                    //读取JSON数据
                    list.clear();
                    JSONArray jso = new JSONArray(sb.toString());
                    for (int i = 0; i < jso.length(); i++) {
                        JSONObject jo = (JSONObject) jso.get(i);
                        Userinfos us=new Userinfos();
                        us.setName(jo.getString("username"));
                        us.setSex(jo.getString("sex")  );
                        list.add(us);
                    }
                    
                    
                    inst.close();
                    isr.close();
                    br.close();
                    http.disconnect();
                    return sb.toString();
                    
                } else {
    
                    errorMessage = "服务器繁忙,请稍后再试(" + http.getResponseCode() + ")";
                    return "errorserver";
    
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                errorMessage = e.getMessage();
                return "errorclient";
            }
        
        }
       //做完后执行
       @Override
      protected void onPostExecute(Object result) {
            // result的值为doInBackground方法的返回值
            String tr = result.toString();
            Log.i("d",""+tr);
            TextView tv = (TextView) activity.findViewById(R.id.textView1);
            /* tv.setText("访问完成!"+tr); */
            //空指针
            if ("errorclient".equals(tr)) {
                if (errorMessage.indexOf("No add") != -1) {
                    tv.setText("网络不通");
                } else {
                    tv.setText("访问网络时其它异常:" + errorMessage);
                }
    
            } else if ("errorserver".equals(tr)) {
                tv.setText(errorMessage);
            } else {
                tv.setText(tr);
                adapter.notifyDataSetChanged();
            }
    
      }
     
    }

    1、URL_STR服务端网站地址。

    2、通过HttpURLConnection等相关设置连接服务发起请求。

    3、ReadOneline读取数据,JSONArray转换数据通过循环获取数据

    4、通过 adapter.notifyDataSetChanged()通知进行更新操作。

      效果图:

                       

  • 相关阅读:
    进程 线程 协程
    TCP的滑动窗口和网络拥塞控制
    Golang中函数结构体,将函数转换为接口
    go的调度 与 go 的GC
    未来程序员这个工种会如何进化与“35岁之殇”的思考
    golang 实现 LRU
    golang 单例模式实现
    内存泄露及内存溢出,解决方案
    Jvm调优参数
    HttpUtil
  • 原文地址:https://www.cnblogs.com/wdht/p/6146139.html
Copyright © 2020-2023  润新知