Android仿人人客户端(v5.7.1)——网络模块处理的架构

来源:互联网 发布:知到智慧树形势与政策 编辑:程序博客网 时间:2024/06/05 17:41

Android仿人人客户端(v5.7.1)——网络模块处理的架构

分类: 仿人人Android客户端(v5.7.1) 7407人阅读 评论(27) 收藏 举报
网络处理ANDROID仿人人网络模块架构类图

转载请标明出处:http://blog.csdn.net/android_ls/article/details/8732427
 声明:仿人人项目,所用所有图片资源都来源于官方人人android客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。
       上一篇聊到了通过WebView组件加载人人的访问授权页面,接下来就是当用户输入人人访问账号和密码,点击“登录”按钮,成功后人人的服务器端会返回AccessToken的值。初次使用,我们本地是没有存储session Key的,我们需要通过AccessToken去服务器端请求数据,获得session Key、sessionSecret和用户的userId。存储当前获得的sessionKey, sessionSecret以备后用。这里就需要用到网络这块的知识,这一篇就来说下仿人人的网络模块是如何架构的,先来看下网络处理模块的类图:

  一、网络请求基类(AsyncBaseRequest),是一个实现Runnable接口的线程类。

  初始化时的参数列表:

[java] view plaincopy
  1. public AsyncBaseRequest(String url, Map<String, String> parameter, ParseCallback handler, ResultCallback requestCallback) {}  

 参数列表解释: 

        第一个参数:网络请求URL;

        第二个参数:网络请求的参数;

        第三个参数:网络请求返回数据的解析器;

       第四个参数:网络请求返回的结果回调接口;
  网络请求具体实现抽象方法:

[java] view plaincopy
  1. protected abstract InputStream getRequestResult() throws IOException;  

  线程核心run()方法里面的实现:

[java] view plaincopy
  1. @Override  
  2. public void run() {  
  3.     try {  
  4.         mInStream = getRequestResult();  
  5.         if (mInStream != null) {  
  6.             String result = new String(readInputStream(mInStream));  
  7.             Object obj = parseHandler.parse(result);  
  8.             requestCallback.onSuccess(flag, obj);  
  9.         } else {  
  10.             System.out.println("get InputStream By HttpURLConnection return result is NULL.");  
  11.         }  
  12.     } catch (IOException e) {  
  13.         requestCallback.onFail(flag, Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO异常标识  
  14.         e.printStackTrace();  
  15.     }  
  16. }  

二、通过HTTP协议发送GET请求的具体实现

[java] view plaincopy
  1. package com.everyone.android.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.net.HttpURLConnection;  
  6. import java.net.URL;  
  7. import java.net.URLEncoder;  
  8. import java.util.Map;  
  9.   
  10. import org.apache.http.protocol.HTTP;  
  11.   
  12. import com.everyone.android.callback.ParseCallback;  
  13. import com.everyone.android.callback.ResultCallback;  
  14.   
  15. /** 
  16.  * 功能描述:通过HTTP协议发送GET请求 
  17.  * @author android_ls 
  18.  * 
  19.  */  
  20. public class AsyncHttpGet extends AsyncBaseRequest {  
  21.   
  22.     /** 
  23.      *  
  24.      */  
  25.     private static final long serialVersionUID = 2L;  
  26.   
  27.     public AsyncHttpGet(String url, Map<String, String> parameter,  
  28.             ParseCallback handler, ResultCallback requestCallback) throws IOException {  
  29.         super(url, parameter, handler, requestCallback);  
  30.     }  
  31.   
  32.     @Override  
  33.     protected InputStream getRequestResult() throws IOException {  
  34.         StringBuilder sb = new StringBuilder(requestUrl);  
  35.         sb.append('?');  
  36.         for(Map.Entry<String, String> entry : parameter.entrySet()){  
  37.             sb.append(entry.getKey()).append('=')  
  38.                 .append(URLEncoder.encode(entry.getValue(), HTTP.UTF_8)).append('&');  
  39.         }  
  40.         sb.deleteCharAt(sb.length()-1);  
  41.           
  42.         URL url = new URL(sb.toString());  
  43.         mHttpURLConn = (HttpURLConnection)url.openConnection();  
  44.         mHttpURLConn.setConnectTimeout(connectTimeout);  
  45.         mHttpURLConn.setRequestMethod("GET");  
  46.         if(mHttpURLConn.getResponseCode()== HttpURLConnection.HTTP_OK){  
  47.             return mHttpURLConn.getInputStream();  
  48.         }  
  49.         return null;  
  50.     }  
  51.       
  52. }  

三、通过HTTP协议发送POST请求的具体实现

[java] view plaincopy
  1. package com.everyone.android.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.OutputStream;  
  6. import java.net.HttpURLConnection;  
  7. import java.net.URL;  
  8. import java.net.URLEncoder;  
  9. import java.util.Map;  
  10.   
  11. import org.apache.http.protocol.HTTP;  
  12.   
  13. import com.everyone.android.callback.ParseCallback;  
  14. import com.everyone.android.callback.ResultCallback;  
  15.   
  16. /** 
  17.  * 功能描述:通过HTTP协议发送POST请求 
  18.  * @author android_ls 
  19.  * 
  20.  */  
  21. public class AsyncHttpPost extends AsyncBaseRequest {  
  22.   
  23.     /** 
  24.      *  
  25.      */  
  26.     private static final long serialVersionUID = 3L;  
  27.   
  28.     public AsyncHttpPost(String url, Map<String, String> parameter,  
  29.             ParseCallback handler, ResultCallback requestCallback) {  
  30.         super(url, parameter, handler, requestCallback);  
  31.     }  
  32.   
  33.     @Override  
  34.     protected InputStream getRequestResult() throws IOException {  
  35.         StringBuilder sb = new StringBuilder();  
  36.         if(parameter!=null && !parameter.isEmpty()){  
  37.             for(Map.Entry<String, String> entry : parameter.entrySet()){  
  38.                 sb.append(entry.getKey()).append('=')  
  39.                     .append(URLEncoder.encode(entry.getValue(), HTTP.UTF_8)).append('&');  
  40.             }  
  41.             sb.deleteCharAt(sb.length()-1);  
  42.         }  
  43.           
  44.         // 得到实体的二进制数据  
  45.         byte[] entitydata = sb.toString().getBytes();  
  46.         URL url = new URL(requestUrl);  
  47.         mHttpURLConn = (HttpURLConnection)url.openConnection();  
  48.         mHttpURLConn.setRequestMethod("POST");  
  49.         mHttpURLConn.setConnectTimeout(5 * 1000);  
  50.         // 如果通过post提交数据,必须设置允许对外输出数据  
  51.         mHttpURLConn.setDoOutput(true);  
  52.         mHttpURLConn.setRequestProperty("Content-Type""application/x-www-form-urlencoded");  
  53.         mHttpURLConn.setRequestProperty("Content-Length", String.valueOf(entitydata.length));  
  54.         OutputStream outStream = mHttpURLConn.getOutputStream();  
  55.         outStream.write(entitydata);  
  56.         outStream.flush();  
  57.         outStream.close();  
  58.         if(mHttpURLConn.getResponseCode()== HttpURLConnection.HTTP_OK){  
  59.             return mHttpURLConn.getInputStream();  
  60.         }  
  61.         return null;  
  62.     }  
  63.   
  64. }  

四、线程池类

[java] view plaincopy
  1. package com.everyone.android.net;  
  2.   
  3. import java.util.concurrent.AbstractExecutorService;  
  4. import java.util.concurrent.ArrayBlockingQueue;  
  5. import java.util.concurrent.ThreadPoolExecutor;  
  6. import java.util.concurrent.TimeUnit;  
  7.   
  8. import android.util.Log;  
  9.   
  10. /** 
  11.  * 功能描述:网络请求线程池类 
  12.  * @author android_ls 
  13.  */  
  14. public class DefaultThreadPool {  
  15.     /** 
  16.      * 用于保存等待执行的任务的阻塞队列。(有序的先进先出阻塞队列) 
  17.      */  
  18.     private static ArrayBlockingQueue<Runnable> mBlockingQueue = new ArrayBlockingQueue<Runnable>(15true);  
  19.   
  20.     /** 
  21.      * 线程池 
  22.      */  
  23.     private static AbstractExecutorService mThreadPoolExecutor  
  24.                                                         = new ThreadPoolExecutor(5710, TimeUnit.SECONDS, mBlockingQueue,   
  25.                                                                 new ThreadPoolExecutor.DiscardOldestPolicy());  
  26.   
  27.     private static DefaultThreadPool instance = null;  
  28.   
  29.     public static DefaultThreadPool getInstance() {  
  30.         if (instance == null) {  
  31.             instance = new DefaultThreadPool();  
  32.         }  
  33.         return instance;  
  34.     }  
  35.   
  36.     /** 
  37.      * 执行任务 
  38.      * @param r 
  39.      */  
  40.     public void execute(Runnable r) {  
  41.         mThreadPoolExecutor.execute(r);  
  42.     }  
  43.   
  44.     /** 
  45.      * 关闭,并等待任务执行完成,不接受新任务 
  46.      */  
  47.     public static void shutdown() {  
  48.         if (mThreadPoolExecutor != null) {  
  49.             mThreadPoolExecutor.shutdown();  
  50.             Log.i(DefaultThreadPool.class.getName(), "DefaultThreadPool shutdown");  
  51.         }  
  52.     }  
  53.   
  54.     /** 
  55.      * 关闭,立即关闭,并挂起所有正在执行的线程,不接受新任务 
  56.      */  
  57.     public static void shutdownRightnow() {  
  58.         if (mThreadPoolExecutor != null) {  
  59.             mThreadPoolExecutor.shutdownNow();  
  60.             try {  
  61.                 // 设置超时极短,强制关闭所有任务  
  62.                 mThreadPoolExecutor.awaitTermination(1, TimeUnit.MICROSECONDS);  
  63.             } catch (InterruptedException e) {  
  64.                 e.printStackTrace();  
  65.             }  
  66.   
  67.             Log.i(DefaultThreadPool.class.getName(), "DefaultThreadPool shutdownRightnow");  
  68.         }  
  69.     }  
  70.   
  71. }  

五、网络请求返回的数据解析接口

[java] view plaincopy
  1. package com.everyone.android.callback;  
  2.   
  3. /** 
  4.  * 功能描述:网络请求返回的数据解析接口 
  5.  * @author android_ls 
  6.  * 
  7.  */  
  8. public interface ParseCallback {  
  9.     /** 
  10.      * 对网络请求返回的数据进行解析 
  11.      * @param str 要解析的字符串,JSON格式或XML 
  12.      * @return 解析的结果 
  13.      */  
  14.     public Object parse(String str);  
  15. }  

六、网络请求返回的结果回调接口

[java] view plaincopy
  1. package com.everyone.android.callback;  
  2.   
  3. /** 
  4.  * 功能描述:网络请求返回的结果回调接口 
  5.  * @author android_ls 
  6.  * 
  7.  */  
  8. public interface ResultCallback {  
  9.     public void onSuccess(Object obj);  
  10.   
  11.     public void onFail(int errorCode);  
  12.   
  13. }  

七、应用中界面(Activity)的基类

[java] view plaincopy
  1. package com.everyone.android;  
  2.   
  3. import java.net.HttpURLConnection;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.widget.Toast;  
  11.   
  12. import com.everyone.android.net.AsyncBaseRequest;  
  13. import com.everyone.android.net.DefaultThreadPool;  
  14.   
  15. /** 
  16.  * 功能描述:应用中界面(Activity)的基类 
  17.  * 对原有的Activity类进行扩展 
  18.  * @author android_ls 
  19.  */  
  20. public abstract class AppBaseActivity extends Activity {  
  21.   
  22.     /** 
  23.      * 当前activity所持有的所有网络请求 
  24.      */  
  25.     protected List<AsyncBaseRequest> mAsyncRequests;  
  26.   
  27.     protected Handler mHandler;  
  28.   
  29.     protected DefaultThreadPool mDefaultThreadPool;  
  30.   
  31.     @Override  
  32.     protected void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(getLayoutId());  
  35.   
  36.         ((EveryoneApplication) this.getApplication()).addActivity(this);  
  37.   
  38.         mHandler = new Handler();  
  39.         mAsyncRequests = new ArrayList<AsyncBaseRequest>();  
  40.         mDefaultThreadPool = DefaultThreadPool.getInstance();  
  41.   
  42.         // 初始化组件  
  43.         setupView();  
  44.         // 初始化数据  
  45.         initializedData();  
  46.     }  
  47.   
  48.     /** 
  49.      * 布局文件ID 
  50.      * @return 
  51.      */  
  52.     protected abstract int getLayoutId();  
  53.   
  54.     /** 
  55.      * 初始化组件 
  56.      */  
  57.     protected abstract void setupView();  
  58.   
  59.     /** 
  60.      * 初始化数据 
  61.      */  
  62.     protected abstract void initializedData();  
  63.   
  64.     @Override  
  65.     protected void onPause() {  
  66.         /** 
  67.          * 在activity销毁的时候同时设置停止请求,停止线程请求回调 
  68.          */  
  69.         cancelRequest();  
  70.         super.onPause();  
  71.     }  
  72.   
  73.     private void cancelRequest() {  
  74.         if (mAsyncRequests != null && mAsyncRequests.size() > 0) {  
  75.             for (AsyncBaseRequest request : mAsyncRequests) {  
  76.                 HttpURLConnection conn = request.getRequestConn();  
  77.                 if (conn != null) {  
  78.                     try {  
  79.                         conn.disconnect();  
  80.                         System.out.println("onDestroy disconnect URL: " + conn.getURL());  
  81.                         mAsyncRequests.remove(request);  
  82.                     } catch (UnsupportedOperationException e) {  
  83.                         //do nothing .  
  84.                     }  
  85.                 }  
  86.             }  
  87.         }  
  88.     }  
  89.   
  90.     /** 
  91.      * 显示Toast形式的提示信息 
  92.      * @param message 
  93.      */  
  94.     protected void show(String message) {  
  95.         Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();  
  96.     }  
  97.   
  98.     @Override  
  99.     protected void onDestroy() {  
  100.         /** 
  101.          * 在activity销毁的时候同时设置停止请求,停止线程请求回调 
  102.          */  
  103.         cancelRequest();  
  104.         super.onDestroy();  
  105.     }  
  106. }  

八、测试(继承自AppBaseActivity的子类),方法的调用

[java] view plaincopy
  1. String url = "http://www.baidu.com/";  
  2.               
  3.             Map<String, String> parameter = new HashMap<String, String>();  
  4.             parameter.put("name""android_ls");  
  5.             parameter.put("age""23");  
  6.               
  7.             AsyncBaseRequest asyncBaseRequest = new AsyncHttpPost(url, parameter, new ParseCallback(){  
  8.   
  9.                 @Override  
  10.                 public Object parse(String str) {  
  11.                     // TODO Auto-generated method stub  
  12.                     return null;  
  13.                 }  
  14.                   
  15.             },  
  16.             new ResultCallback(){  
  17.   
  18.                 @Override  
  19.                 public void onSuccess(int flag, Object obj) {  
  20.                     // TODO Auto-generated method stub  
  21.                       
  22.                 }  
  23.   
  24.                 @Override  
  25.                 public void onFail(int flag, int errorCode) {  
  26.                     // TODO Auto-generated method stub  
  27.                       
  28.                 }  
  29.                   
  30.             });  
  31.             mDefaultThreadPool.execute(asyncBaseRequest);  
  32.             mAsyncRequests.add(asyncBaseRequest);  

AsyncBaseRequest的完整代码

[java] view plaincopy
  1. package com.everyone.android.net;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.Serializable;  
  7. import java.net.HttpURLConnection;  
  8. import java.util.Map;  
  9.   
  10. import com.everyone.android.callback.ParseCallback;  
  11. import com.everyone.android.callback.ResultCallback;  
  12. import com.everyone.android.utils.Constant;  
  13. /** 
  14.  * 功能描述:通过HTTP协议发送网络请求线程类 
  15.  * @author android_ls 
  16.  * 
  17.  */  
  18. public abstract class AsyncBaseRequest implements Runnable, Serializable {  
  19.     /** 
  20.      *  
  21.      */  
  22.     private static final long serialVersionUID = 1L;  
  23.   
  24.     /** 
  25.      * 网络连接超时,默认值为5秒 
  26.      */  
  27.     protected int connectTimeout = 5 * 1000;  
  28.       
  29.     /** 
  30.      * 网络数据读取超时,默认值为5秒 
  31.      */  
  32.     protected int readTimeout = 5 * 1000;  
  33.   
  34.     protected void setConnectTimeout(int connectTimeout) {  
  35.         this.connectTimeout = connectTimeout;  
  36.     }  
  37.   
  38.     protected void setReadTimeout(int readTimeout) {  
  39.         this.readTimeout = readTimeout;  
  40.     }  
  41.   
  42.     protected String requestUrl;  
  43.     protected Map<String, String> parameter;  
  44.     private ParseCallback parseHandler;  
  45.     private ResultCallback requestCallback;  
  46.   
  47.     protected HttpURLConnection mHttpURLConn;  
  48.     protected InputStream mInStream;  
  49.   
  50.     public AsyncBaseRequest(String url, Map<String, String> parameter,  
  51.             ParseCallback handler, ResultCallback requestCallback) {  
  52.         this.parseHandler = handler;  
  53.         this.requestUrl = url;  
  54.         this.parameter = parameter;  
  55.         this.requestCallback = requestCallback;  
  56.     }  
  57.   
  58.     /** 
  59.      * 发送网络请求 
  60.      *  
  61.      * @return 网络请求返回的InputStream数据流 
  62.      * @throws IOException 
  63.      */  
  64.     protected abstract InputStream getRequestResult() throws IOException;  
  65.   
  66.     @Override  
  67.     public void run() {  
  68.         try {  
  69.             mInStream = getRequestResult();  
  70.             if (mInStream != null) {  
  71.                 String result = new String(readInputStream(mInStream));  
  72.                 Object obj = parseHandler.parse(result);  
  73.                 requestCallback.onSuccess(obj);  
  74.             } else {  
  75.                 System.out.println("get InputStream By HttpURLConnection return result is NULL.");  
  76.             }  
  77.         } catch (IOException e) {  
  78.             requestCallback.onFail(Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO异常标识  
  79.             e.printStackTrace();  
  80.         }  
  81.     }  
  82.   
  83.     /** 
  84.      * 从输入流读取数据 
  85.      *  
  86.      * @param inStream 
  87.      * @return 
  88.      * @throws IOException 
  89.      * @throws Exception 
  90.      */  
  91.     protected byte[] readInputStream(InputStream inStream) throws IOException {  
  92.         ByteArrayOutputStream outSteam = new ByteArrayOutputStream();  
  93.         byte[] buffer = new byte[1024];  
  94.         int len = 0;  
  95.         while ((len = inStream.read(buffer)) != -1) {  
  96.             outSteam.write(buffer, 0, len);  
  97.         }  
  98.         outSteam.close();  
  99.         inStream.close();  
  100.         return outSteam.toByteArray();  
  101.     }  
  102.   
  103.     public HttpURLConnection getRequestConn() {  
  104.         return mHttpURLConn;  
  105.     }  
  106.   
  107. }  

好了就到这里吧,后面的待续。。。

吐槽下:在CSDN上写文章,写完后你若想删除掉之前写的一部分内容,就得一行一行删,不能选中某个区域,之后一次性删除,真郁闷。我记得之前不是这样的,现在为什么会这样呢?我刚才删除写错的文字和代码就用了我五分钟左右,真的想说粗话了,但想了下,算了。我是一个文明的人,呵呵。

 这一篇网络模块处理有些地方有待优化,优化处理部分请阅读下篇Android仿人人客户端(v5.7.1)——网络模块优化

0 0