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()通知進行更新操作。

 

  效果圖:

                   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM