HttpURLConnection 传输数据和下载图片

Posted 非余之渔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()通知进行更新操作。

 

  效果图:

                   

以上是关于HttpURLConnection 传输数据和下载图片的主要内容,如果未能解决你的问题,请参考以下文章

网络传输---HttpURLConnection

JAVA通过HttpURLConnection 上传和下载文件

HttpURLConnection从链接下载数据存放本地临时文件,Java

HttpURLConnection从链接下载数据存放本地临时文件,Java

android中的HttpUrlConnection的使用之二

android中的HttpUrlConnection的使用之四