• Android基础4(get、post乱码解决、Asynchttpclient的GET_POST访问网络、上传文件、多线程下载、多线程下载的Android移植、XUtils实现多线程下载)


    1.post方式提交数据的中文乱码解决(重点)

    解决中文乱码的方法:

     保证客户端和服务器端使用的字符集编码一致。

     Android应用程序默认使用的字符集是UTF-8;

      //Tomcat默认的字符集编码是iso-8859-1,默认是iso-8859-1进行转码  

     String username = request.getParameter("username");   

    String password = request.getParameter("password");             

    String  newUsername = new String(username.getBytes("iso-8859-1"),"UTF-8");   

    String  newPassword = new String(password.getBytes("iso-8859-1"),"UTF-8");   

    System.out.println(newUsername);   

    System.out.println(newPassword);   

      if("中国".equals(newUsername) && "发展".equals(newPassword)){  

     //Tomcat默认的字符集编码是iso-8859-1,默认是iso-8859-1进行转码,当它发现使用iso-8859-1不能编码中文的时候,   //会使用操作系统使用的本地码表(字符集编码)进行编码   

     response.getOutputStream().write("登陆成功".getBytes("UTF-8"));  

     }else

    {    response.getOutputStream().write("登陆失败".getBytes("UTF-8"));  

    }

    2.get提交数据乱码的解决:

     保证客户端和服务器端使用的字符集编码一致.  Android应用程序默认使用的字符集是UTF-8.  

    3.使用HttpClient向服务器端提交数据

      HttpClient是apache下的子项目,轻量级的浏览器。

     使用步骤:  

    1、创建一个浏览器:  

    2、输入网址:  

    3、按回车,执行请求:

    * 使用GET方式提交数据:

      代码:

      //1、创建一个浏览器:    

    HttpClient client = new DefaultHttpClient();

      //2、输入网址:    

    HttpGet http = new HttpGet(path);

      //3、按回车,执行请求:   

     //服务器返回的所有数据都封装到了response里   

     HttpResponse response = client.execute(http);    

    //得到响应码(状态码)    

    int code = response.getStatusLine().getStatusCode();    

    if (200 == code) {    

    // 获得服务器端的响应数据    

    InputStream is = response.getEntity().getContent();       

    String result = StreamTools.readStream(is);    

    Message msg = Message.obtain();    

    msg.obj = result;    

    handler.sendMessage(msg);   

    }         

    * 使用POST方式发送提交数据:        

    代码:   

    package com.qaa.qqlogin;     

    import java.io.InputStream;   

    import java.net.URLEncoder;   

    import java.util.ArrayList;   

    import java.util.List;      

    import org.apache.http.HttpResponse;   

    import org.apache.http.client.HttpClient;   

    import org.apache.http.client.entity.UrlEncodedFormEntity;   

    import org.apache.http.client.methods.HttpPost;   

    import org.apache.http.impl.client.DefaultHttpClient;   

    import org.apache.http.message.BasicNameValuePair;      

    import android.app.Activity;   

    import android.os.Bundle;   

    import android.os.Handler;   

    import android.os.Message;   

    import android.text.TextUtils;   

    import android.view.View;   

    import android.widget.EditText;   

    import android.widget.Toast;      

    public class MainActivity extends Activity {    

     private EditText et_qq;   

    private EditText et_pwd;      

    private Handler handler = new Handler(){        

    public void handleMessage(Message msg) {     

    String result = (String) msg.obj;          

    Toast.makeText(MainActivity.this, result, 0).show();   

     };   

    };     

     @Override   

    protected void onCreate(Bundle savedInstanceState) {    

    super.onCreate(savedInstanceState);    

    setContentView(R.layout.activity_main);        

    et_qq = (EditText) findViewById(R.id.et_qq);    

    et_pwd = (EditText) findViewById(R.id.et_pwd);   

    }       

     public void login(View view){    

    final String qq = et_qq.getText().toString().trim();    

    final String pwd = et_pwd.getText().toString().trim();        

    if(TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)){     

    Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

    return;    

    }else

    {     

    final String path = "http://192.168.20.91:8080/web/servlet/LoginServlet";     

    new Thread() {      

    public void run() {       

    try {        

    String data = "username="+URLEncoder.encode(qq,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");                        

    //      1、创建一个浏览器:       

     HttpClient client = new DefaultHttpClient();   

    //      2、输入网址:        

    HttpPost http = new HttpPost(path);      

      //封装提交的参数        

    BasicNameValuePair value1 = new BasicNameValuePair("username",qq) ;       

     BasicNameValuePair value2 = new BasicNameValuePair("password",pwd) ;                

    List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();        

    parameters.add(value1);       

     parameters.add(value2);        

    //把提交的数据封装到form实体对象中        

    //默认是iso-8859-1进行url编码,需要显示的指定字符集编码        

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"UTF-8");               

     //设置提交的数据实体        

    http.setEntity(entity);   

    //      3、按回车,执行请求:        

    HttpResponse response = client.execute(http);               

     //得到响应码        

    int code = response.getStatusLine().getStatusCode();       

     if (200 == code) {        

     // 获得服务器端的响应数据        

     InputStream is = response.getEntity().getContent();         

    String result = StreamTools.readStream(is);                  

    Message msg = Message.obtain();         

    msg.obj = result;         

    handler.sendMessage(msg);        

    }       

    } catch (Exception e) {        

    e.printStackTrace();       

    }     

     };    

     }.start();    

    }  

     }

     }

    5.使用开源项目Asynchttpclient的GET_POST访问网络

    * 使用GET方式提交数据:

    代码:

     package com.qaa.qqlogin;

     import java.io.InputStream;  

    import java.net.HttpURLConnection;  

    import java.net.URL;  

    import java.net.URLEncoder;    

    import org.apache.http.Header;    

    import com.loopj.android.http.AsyncHttpClient;  

    import com.loopj.android.http.AsyncHttpResponseHandler;    

    import android.app.Activity;  

    import android.os.Bundle;  

    import android.os.Handler;  

    import android.os.Message;  

    import android.text.TextUtils;  

    import android.view.View;  

    import android.widget.EditText;  

    import android.widget.Toast;    

    public class MainActivity extends Activity {     

    private EditText et_qq;   

    private EditText et_pwd;     

    @Override   

    protected void onCreate(Bundle savedInstanceState)

    {    

    super.onCreate(savedInstanceState);    

    setContentView(R.layout.activity_main);      

    et_qq = (EditText) findViewById(R.id.et_qq);    

    et_pwd = (EditText) findViewById(R.id.et_pwd);   

    }     

    public void login(View view)

    {    

    final String qq = et_qq.getText().toString().trim();    

    final String pwd = et_pwd.getText().toString().trim();      

    if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd))

    {     

    Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

    return;    }

    else

    {          

    String path = "http://192.168.20.91:8080/web/servlet/LoginServlet?username="       + qq + "&password="+pwd;         

     //1、创建一个浏览器对象     

    AsyncHttpClient client = new AsyncHttpClient();     

    //2、发送一个GET请求     

    client.get(path, new AsyncHttpResponseHandler() {           

     /** * 请求处理成功后调用这个方法     

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等) */      

    @Override      

    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

    Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      }

         /**      

    * 请求处理失败后调用这个方法      

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

    * Throwable 异常对象       */      

    @Override      

    public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

            error.printStackTrace();              

    Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

    }     

    });    

    }   

    }    

    }

    * 使用POST方式提交数据:

    代码:

     package com.qaa.qqlogin;

     import java.io.InputStream;  

    import java.net.HttpURLConnection;  

    import java.net.URL;  

    import java.net.URLEncoder;    

    import org.apache.http.Header;    

    import com.loopj.android.http.AsyncHttpClient;  

    import com.loopj.android.http.AsyncHttpResponseHandler;  

    import com.loopj.android.http.RequestParams;    

    import android.app.Activity;  

    import android.os.Bundle;  

    import android.os.Handler;  

    import android.os.Message;  

    import android.text.TextUtils;  

    import android.view.View;  

    import android.widget.EditText;  

    import android.widget.Toast;    

    public class MainActivity extends Activity

    {     

    private EditText et_qq;   

    private EditText et_pwd;     

    @Override   

    protected void onCreate(Bundle savedInstanceState)

    {    

    super.onCreate(savedInstanceState);    

    setContentView(R.layout.activity_main);        

    et_qq = (EditText) findViewById(R.id.et_qq);    

    et_pwd = (EditText) findViewById(R.id.et_pwd);   

    }

      public void login(View view)

    {    

    final String qq = et_qq.getText().toString().trim();    

    final String pwd = et_pwd.getText().toString().trim();        

    if(TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)){     

    Toast.makeText(this, "qq号码或者密码不能为空", 0).show();     

    return;    

    }else

    {     

    String path = "http://192.168.20.91:8080/web/servlet/LoginServlet";

     AsyncHttpClient client = new AsyncHttpClient();     

    //封装要提交的数据     

    RequestParams params = new RequestParams();     

    params.put("username", qq);     

    params.put("password", pwd);         

     //执行post请求     

    //path 请求的url    

     //params 封装要提交的数据     

    //responseHandler 响应的处理器     

    client.post(path, params, new AsyncHttpResponseHandler()

    {      

    /**      

    * 请求处理成功后调用这个方法      

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等)       */      

    @Override      

    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

    Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      

    }      

    /**      

    * 请求处理失败后调用这个方法      

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

    * Throwable 异常对象       */      

    @Override      

    public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {       

    error.printStackTrace();       

    Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

    }     

    });    

    }   

    }   

    }

    ##6上传文件(重点)

    代码:       

    String path = "http://192.168.20.91:8080/web/servlet/UploadServlet";          

    AsyncHttpClient client = new AsyncHttpClient();     

    //封装要提交的数据     

    RequestParams params = new RequestParams();          

    //上传文件     

    File file = new File(fildir);     

    params.put("file", file);          

    //执行post请求     

    //path 请求的url     

    //params 封装要提交的数据     

    //responseHandler 响应的处理器     

    client.post(path, params, new AsyncHttpResponseHandler() {      

    /**      

    * 请求处理成功后调用这个方法      

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等)       */      

    @Override      

    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {       

    Toast.makeText(MainActivity.this, new String(responseBody), 0).show();      

    }      

    /**      

    * 请求处理失败后调用这个方法      

    * statusCode 响应码 200 404 503      

    * headers 响应头信息      

    * responseBody 服务器返回的响应数据(如:登陆成功、失败等)      

    * Throwable 异常对象       */      

    @Override      

    public void onFailure(int statusCode, Header[] headers,byte[] responseBody, Throwable error) {              

    error.printStackTrace();       

    Toast.makeText(MainActivity.this, "请求处理失败", 0).show();      

    }     

    });  

    7.多线程下载的原理

    多线程下载文件的步骤:

     1、在客户端本地创建一个与服务器端一样大小的空白文件:  

    (1)创建空白文件:RandomAccessFile setlength();  

    (2)获取空白文件大小:content-length;    

    2、确定每个子线程下载数据块大小:     

    blocksize=length/threadCount:10/3=3     

    确定每个子线程下载数据的起始位置和结束位置:  

    第0个线程:开始位置 0*3=0 结束位置:(0+1)*3-1  

    第1个线程:开始位置 1*3=3 结束位置:(1+1)*3-1  ...  

    第n个线程:开始位置 n*blocksize  结束位置:(n+1)*blocksize-1  n是线程的id  最后一个子线程下载的结束位置:length-1

     3、创建子线程,下载对应数据块:

     4、确定每个子线程什么下载完毕,标识整个文件都下载完成:使用变量来标识;    

    ##8.多线程下载的Android移植

    代码:

    MainActivity.java:

    package com.qaa.multithreaddownloader;    

    import java.io.RandomAccessFile;  

    import java.net.HttpURLConnection;  

    import java.net.URL;        

    import android.app.Activity;  

    import android.os.Bundle;  

    import android.os.Environment;  

    import android.text.TextUtils;  

    import android.view.View;  

    import android.widget.EditText;  

    import android.widget.Toast;    

    public class MainActivity extends Activity {

     private EditText et_path;

     private EditText et_threadCount;    

    private static int threadCount = 3;

     @Override  

    protected void onCreate(Bundle savedInstanceState)

    {   super.onCreate(savedInstanceState);  

     setContentView(R.layout.activity_main);     

     et_path = (EditText) findViewById(R.id.et_path);  

     et_threadCount = (EditText) findViewById(R.id.et_threadCount);

     }  

     public void download(View view){      

    final String path = et_path.getText().toString().trim();  

     String tcStr = et_threadCount.getText().toString().trim();   

    if(TextUtils.isEmpty(path)){    

    Toast.makeText(this, "请输入下载文件的网络路径", 0).show();    

    return;   }

    else{   

     if(!TextUtils.isEmpty(tcStr))

    {     threadCount = Integer.parseInt(tcStr);   

     }    

    new Thread(){     

    public void run() {      

    // 1、在客户端本地创建一个与服务器端一样大小的空白文件:     

     try {              

    URL url = new URL(path);      

     HttpURLConnection conn = (HttpURLConnection) url.openConnection();      

     conn.setRequestMethod("GET");      

     conn.setConnectTimeout(3000);      

     int code = conn.getResponseCode();       

    if (200 == code) {        

    int length = conn.getContentLength();        

    RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe", "rw");        

    raf.setLength(length);        

    // 2、确定每个子线程下载数据块大小:        

    int blockSize = length / threadCount;        

    for (int threadId = 0; threadId < threadCount; threadId++) {         

    // blocksize=length/threadCount:10/3=3         

    // 确定每个子线程下载数据的起始位置和结束位置:        

     // 第0个线程:开始位置 0*3=0 结束位置:(0+1)*3-1        

     // 第1个线程:开始位置 1*3=3 结束位置:(1+1)*3-1         

    // ...         // 第n个线程:开始位置 n*blocksize 结束位置:(n+1)*blocksize-1         // n是线程的id        

     // 最后一个子线程下载的结束位置:length-1        

     int startIndex = threadId * blockSize;        

     int endIndex = (threadId + 1) * blockSize - 1;       

      if (threadId == (threadCount - 1)) {         

     endIndex = length - 1;         }         

    // 3、创建子线程,下载对应数据块:         

    new ChildThreadDownLoader(threadId,startIndex,endIndex,path).start();       

     }      

     }    

      } catch (Exception e) {

          e.printStackTrace();    

      }

        };    

    }.start();   

    }   

     }

    ChildThreadDownLoader.java:

     package com.qaa.multithreaddownloader;    

    import java.io.IOException;  

    import java.io.InputStream;  

    import java.io.RandomAccessFile;  

    import java.net.HttpURLConnection;  

    import java.net.MalformedURLException;  

    import java.net.ProtocolException;  

    import java.net.URL;    

    import android.os.Environment;    

    public class ChildThreadDownLoader extends Thread{    

    private int threadId;  

    private int startIndex;  

    private int endIndex;  

    private String path;  

    private  static int runningThreadCount = 3;    

    public ChildThreadDownLoader(int threadId, int startIndex, int endIndex,    String path) {   

    super();   

    this.threadId = threadId;  

     this.startIndex = startIndex;   

    this.endIndex = endIndex;   

    this.path = path;  }    

    @Override  

    public void run() {   

    try {    

    URL url = new URL(path);    

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();    

    conn.setRequestMethod("GET");    

    conn.setConnectTimeout(3000);    

    //告诉服务器子线程请求的数据范围    

    conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);   

     //请求部分数据成功返回的响应码是206    

    int code = conn.getResponseCode();    

    if(206 == code){     

    InputStream is = conn.getInputStream();     

    RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe","rwd");     

    raf.seek(startIndex);    System.out.println("线程"+threadId+"正在下载...................");     

    byte[] buffer = new byte[1024*1024];     

    int len = 0;     

    while((len = is.read(buffer)) != -1){      

    raf.write(buffer, 0, len);     

    }     

    is.close();    

     raf.close();        

     }        

    System.out.println("线程"+threadId+"下载完毕...................");   

     // 4、确定每个子线程什么下载完毕,标识整个文件都下载完成:使用变量来标识;    

    synchronized (ChildThreadDownLoader.class)

    {     runningThreadCount --;    

     if(runningThreadCount == 0){      

    System.out.println("文件下载完成..............");    

     }   

     }          

     }

    catch (Exception e)

    {    e.printStackTrace();  

     }  

    }

     }

    10.开源项目XUtils实现多线程下载(重点)

    代码:

     package com.qaa.multithreaddownloader;

     import java.io.File;  

    import java.io.RandomAccessFile;  

    import java.net.HttpURLConnection;  

    import java.net.URL;  

     import com.lidroid.xutils.HttpUtils;  

    import com.lidroid.xutils.exception.HttpException;  

    import com.lidroid.xutils.http.ResponseInfo;  

    import com.lidroid.xutils.http.callback.RequestCallBack;        

    import android.app.Activity;  

    import android.os.Bundle;  

    import android.os.Environment;  

    import android.text.TextUtils;  

    import android.view.View;  

    import android.widget.EditText;  

    import android.widget.Toast;    

    public class MainActivity extends Activity {

     private EditText et_path;

     private EditText et_threadCount;    

    private static int threadCount = 3;

     @Override  

    protected void onCreate(Bundle savedInstanceState) {   

    super.onCreate(savedInstanceState);   

    setContentView(R.layout.activity_main);      

    et_path = (EditText) findViewById(R.id.et_path);   

    et_threadCount = (EditText) findViewById(R.id.et_threadCount);  

    }    

    public void download(View view){      

    String path = et_path.getText().toString().trim();   

    String tcStr = et_threadCount.getText().toString().trim();   

    if(TextUtils.isEmpty(path))

    {    

    Toast.makeText(this, "请输入下载文件的网络路径", 0).show();    

    return;   }

    else{    

    if(!TextUtils.isEmpty(tcStr))

    {     threadCount = Integer.parseInt(tcStr);    

    }        

    HttpUtils http = new HttpUtils();    

    http.download(path, Environment.getExternalStorageDirectory()+"/temp.exe",  new RequestCallBack<File>()

    {

              @Override          

    public void onStart()

    {              

    Toast.makeText(MainActivity.this, "开始下载...", 0).show();          

    }

              @Override          

    public void onLoading(long total, long current, boolean isUploading)

    {      System.out.println(current+"/"+total+"-------------------------------");                    

    }

           

        @Override     

    public void onFailure(HttpException arg0, String arg1) {      

    Toast.makeText(MainActivity.this, "下载失败...", 0).show();     }

        @Override     

    public void onSuccess(ResponseInfo<File> arg0) {      Toast.makeText(MainActivity.this, "下载完成,文件保存在"+arg0.result.getPath(), 0).show();     

    }  

     });  

     }   

     }

     }

  • 相关阅读:
    颜色渐变
    DELPHI 反射机制
    网络的收藏资料
    WM_Paint 消息详解
    解决EmbeddedWB弹出页面错误框的问题
    刁蛮公主第二集(纳米盘)
    第五章 用用户控件创建自定义控件
    RTX51 tiny系统要注意的问题:(关于时间片)
    第四章 高级控件编程
    CSDN新频道visual studio技术频道
  • 原文地址:https://www.cnblogs.com/kingqinwang/p/5112532.html
Copyright © 2020-2023  润新知