Android仿人人客户端(v5.7.1)——网络模块处理的架构
来源:互联网 发布:知到智慧树形势与政策 编辑:程序博客网 时间:2024/06/05 17:41
Android仿人人客户端(v5.7.1)——网络模块处理的架构
转载请标明出处:http://blog.csdn.net/android_ls/article/details/8732427
声明:仿人人项目,所用所有图片资源都来源于官方人人android客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。
上一篇聊到了通过WebView组件加载人人的访问授权页面,接下来就是当用户输入人人访问账号和密码,点击“登录”按钮,成功后人人的服务器端会返回AccessToken的值。初次使用,我们本地是没有存储session Key的,我们需要通过AccessToken去服务器端请求数据,获得session Key、sessionSecret和用户的userId。存储当前获得的sessionKey, sessionSecret以备后用。这里就需要用到网络这块的知识,这一篇就来说下仿人人的网络模块是如何架构的,先来看下网络处理模块的类图:
一、网络请求基类(AsyncBaseRequest),是一个实现Runnable接口的线程类。
初始化时的参数列表:
- public AsyncBaseRequest(String url, Map<String, String> parameter, ParseCallback handler, ResultCallback requestCallback) {}
参数列表解释:
第一个参数:网络请求URL;
第二个参数:网络请求的参数;
第三个参数:网络请求返回数据的解析器;
第四个参数:网络请求返回的结果回调接口;
网络请求具体实现抽象方法:
- protected abstract InputStream getRequestResult() throws IOException;
线程核心run()方法里面的实现:
- @Override
- public void run() {
- try {
- mInStream = getRequestResult();
- if (mInStream != null) {
- String result = new String(readInputStream(mInStream));
- Object obj = parseHandler.parse(result);
- requestCallback.onSuccess(flag, obj);
- } else {
- System.out.println("get InputStream By HttpURLConnection return result is NULL.");
- }
- } catch (IOException e) {
- requestCallback.onFail(flag, Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO异常标识
- e.printStackTrace();
- }
- }
二、通过HTTP协议发送GET请求的具体实现
- package com.everyone.android.net;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- import java.util.Map;
- import org.apache.http.protocol.HTTP;
- import com.everyone.android.callback.ParseCallback;
- import com.everyone.android.callback.ResultCallback;
- /**
- * 功能描述:通过HTTP协议发送GET请求
- * @author android_ls
- *
- */
- public class AsyncHttpGet extends AsyncBaseRequest {
- /**
- *
- */
- private static final long serialVersionUID = 2L;
- public AsyncHttpGet(String url, Map<String, String> parameter,
- ParseCallback handler, ResultCallback requestCallback) throws IOException {
- super(url, parameter, handler, requestCallback);
- }
- @Override
- protected InputStream getRequestResult() throws IOException {
- StringBuilder sb = new StringBuilder(requestUrl);
- sb.append('?');
- for(Map.Entry<String, String> entry : parameter.entrySet()){
- sb.append(entry.getKey()).append('=')
- .append(URLEncoder.encode(entry.getValue(), HTTP.UTF_8)).append('&');
- }
- sb.deleteCharAt(sb.length()-1);
- URL url = new URL(sb.toString());
- mHttpURLConn = (HttpURLConnection)url.openConnection();
- mHttpURLConn.setConnectTimeout(connectTimeout);
- mHttpURLConn.setRequestMethod("GET");
- if(mHttpURLConn.getResponseCode()== HttpURLConnection.HTTP_OK){
- return mHttpURLConn.getInputStream();
- }
- return null;
- }
- }
三、通过HTTP协议发送POST请求的具体实现
- package com.everyone.android.net;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- import java.util.Map;
- import org.apache.http.protocol.HTTP;
- import com.everyone.android.callback.ParseCallback;
- import com.everyone.android.callback.ResultCallback;
- /**
- * 功能描述:通过HTTP协议发送POST请求
- * @author android_ls
- *
- */
- public class AsyncHttpPost extends AsyncBaseRequest {
- /**
- *
- */
- private static final long serialVersionUID = 3L;
- public AsyncHttpPost(String url, Map<String, String> parameter,
- ParseCallback handler, ResultCallback requestCallback) {
- super(url, parameter, handler, requestCallback);
- }
- @Override
- protected InputStream getRequestResult() throws IOException {
- StringBuilder sb = new StringBuilder();
- if(parameter!=null && !parameter.isEmpty()){
- for(Map.Entry<String, String> entry : parameter.entrySet()){
- sb.append(entry.getKey()).append('=')
- .append(URLEncoder.encode(entry.getValue(), HTTP.UTF_8)).append('&');
- }
- sb.deleteCharAt(sb.length()-1);
- }
- // 得到实体的二进制数据
- byte[] entitydata = sb.toString().getBytes();
- URL url = new URL(requestUrl);
- mHttpURLConn = (HttpURLConnection)url.openConnection();
- mHttpURLConn.setRequestMethod("POST");
- mHttpURLConn.setConnectTimeout(5 * 1000);
- // 如果通过post提交数据,必须设置允许对外输出数据
- mHttpURLConn.setDoOutput(true);
- mHttpURLConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- mHttpURLConn.setRequestProperty("Content-Length", String.valueOf(entitydata.length));
- OutputStream outStream = mHttpURLConn.getOutputStream();
- outStream.write(entitydata);
- outStream.flush();
- outStream.close();
- if(mHttpURLConn.getResponseCode()== HttpURLConnection.HTTP_OK){
- return mHttpURLConn.getInputStream();
- }
- return null;
- }
- }
四、线程池类
- package com.everyone.android.net;
- import java.util.concurrent.AbstractExecutorService;
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.ThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
- import android.util.Log;
- /**
- * 功能描述:网络请求线程池类
- * @author android_ls
- */
- public class DefaultThreadPool {
- /**
- * 用于保存等待执行的任务的阻塞队列。(有序的先进先出阻塞队列)
- */
- private static ArrayBlockingQueue<Runnable> mBlockingQueue = new ArrayBlockingQueue<Runnable>(15, true);
- /**
- * 线程池
- */
- private static AbstractExecutorService mThreadPoolExecutor
- = new ThreadPoolExecutor(5, 7, 10, TimeUnit.SECONDS, mBlockingQueue,
- new ThreadPoolExecutor.DiscardOldestPolicy());
- private static DefaultThreadPool instance = null;
- public static DefaultThreadPool getInstance() {
- if (instance == null) {
- instance = new DefaultThreadPool();
- }
- return instance;
- }
- /**
- * 执行任务
- * @param r
- */
- public void execute(Runnable r) {
- mThreadPoolExecutor.execute(r);
- }
- /**
- * 关闭,并等待任务执行完成,不接受新任务
- */
- public static void shutdown() {
- if (mThreadPoolExecutor != null) {
- mThreadPoolExecutor.shutdown();
- Log.i(DefaultThreadPool.class.getName(), "DefaultThreadPool shutdown");
- }
- }
- /**
- * 关闭,立即关闭,并挂起所有正在执行的线程,不接受新任务
- */
- public static void shutdownRightnow() {
- if (mThreadPoolExecutor != null) {
- mThreadPoolExecutor.shutdownNow();
- try {
- // 设置超时极短,强制关闭所有任务
- mThreadPoolExecutor.awaitTermination(1, TimeUnit.MICROSECONDS);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Log.i(DefaultThreadPool.class.getName(), "DefaultThreadPool shutdownRightnow");
- }
- }
- }
五、网络请求返回的数据解析接口
- package com.everyone.android.callback;
- /**
- * 功能描述:网络请求返回的数据解析接口
- * @author android_ls
- *
- */
- public interface ParseCallback {
- /**
- * 对网络请求返回的数据进行解析
- * @param str 要解析的字符串,JSON格式或XML
- * @return 解析的结果
- */
- public Object parse(String str);
- }
六、网络请求返回的结果回调接口
- package com.everyone.android.callback;
- /**
- * 功能描述:网络请求返回的结果回调接口
- * @author android_ls
- *
- */
- public interface ResultCallback {
- public void onSuccess(Object obj);
- public void onFail(int errorCode);
- }
七、应用中界面(Activity)的基类
- package com.everyone.android;
- import java.net.HttpURLConnection;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.widget.Toast;
- import com.everyone.android.net.AsyncBaseRequest;
- import com.everyone.android.net.DefaultThreadPool;
- /**
- * 功能描述:应用中界面(Activity)的基类
- * 对原有的Activity类进行扩展
- * @author android_ls
- */
- public abstract class AppBaseActivity extends Activity {
- /**
- * 当前activity所持有的所有网络请求
- */
- protected List<AsyncBaseRequest> mAsyncRequests;
- protected Handler mHandler;
- protected DefaultThreadPool mDefaultThreadPool;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(getLayoutId());
- ((EveryoneApplication) this.getApplication()).addActivity(this);
- mHandler = new Handler();
- mAsyncRequests = new ArrayList<AsyncBaseRequest>();
- mDefaultThreadPool = DefaultThreadPool.getInstance();
- // 初始化组件
- setupView();
- // 初始化数据
- initializedData();
- }
- /**
- * 布局文件ID
- * @return
- */
- protected abstract int getLayoutId();
- /**
- * 初始化组件
- */
- protected abstract void setupView();
- /**
- * 初始化数据
- */
- protected abstract void initializedData();
- @Override
- protected void onPause() {
- /**
- * 在activity销毁的时候同时设置停止请求,停止线程请求回调
- */
- cancelRequest();
- super.onPause();
- }
- private void cancelRequest() {
- if (mAsyncRequests != null && mAsyncRequests.size() > 0) {
- for (AsyncBaseRequest request : mAsyncRequests) {
- HttpURLConnection conn = request.getRequestConn();
- if (conn != null) {
- try {
- conn.disconnect();
- System.out.println("onDestroy disconnect URL: " + conn.getURL());
- mAsyncRequests.remove(request);
- } catch (UnsupportedOperationException e) {
- //do nothing .
- }
- }
- }
- }
- }
- /**
- * 显示Toast形式的提示信息
- * @param message
- */
- protected void show(String message) {
- Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
- }
- @Override
- protected void onDestroy() {
- /**
- * 在activity销毁的时候同时设置停止请求,停止线程请求回调
- */
- cancelRequest();
- super.onDestroy();
- }
- }
八、测试(继承自AppBaseActivity的子类),方法的调用
- String url = "http://www.baidu.com/";
- Map<String, String> parameter = new HashMap<String, String>();
- parameter.put("name", "android_ls");
- parameter.put("age", "23");
- AsyncBaseRequest asyncBaseRequest = new AsyncHttpPost(url, parameter, new ParseCallback(){
- @Override
- public Object parse(String str) {
- // TODO Auto-generated method stub
- return null;
- }
- },
- new ResultCallback(){
- @Override
- public void onSuccess(int flag, Object obj) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onFail(int flag, int errorCode) {
- // TODO Auto-generated method stub
- }
- });
- mDefaultThreadPool.execute(asyncBaseRequest);
- mAsyncRequests.add(asyncBaseRequest);
AsyncBaseRequest的完整代码
- package com.everyone.android.net;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.Serializable;
- import java.net.HttpURLConnection;
- import java.util.Map;
- import com.everyone.android.callback.ParseCallback;
- import com.everyone.android.callback.ResultCallback;
- import com.everyone.android.utils.Constant;
- /**
- * 功能描述:通过HTTP协议发送网络请求线程类
- * @author android_ls
- *
- */
- public abstract class AsyncBaseRequest implements Runnable, Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- /**
- * 网络连接超时,默认值为5秒
- */
- protected int connectTimeout = 5 * 1000;
- /**
- * 网络数据读取超时,默认值为5秒
- */
- protected int readTimeout = 5 * 1000;
- protected void setConnectTimeout(int connectTimeout) {
- this.connectTimeout = connectTimeout;
- }
- protected void setReadTimeout(int readTimeout) {
- this.readTimeout = readTimeout;
- }
- protected String requestUrl;
- protected Map<String, String> parameter;
- private ParseCallback parseHandler;
- private ResultCallback requestCallback;
- protected HttpURLConnection mHttpURLConn;
- protected InputStream mInStream;
- public AsyncBaseRequest(String url, Map<String, String> parameter,
- ParseCallback handler, ResultCallback requestCallback) {
- this.parseHandler = handler;
- this.requestUrl = url;
- this.parameter = parameter;
- this.requestCallback = requestCallback;
- }
- /**
- * 发送网络请求
- *
- * @return 网络请求返回的InputStream数据流
- * @throws IOException
- */
- protected abstract InputStream getRequestResult() throws IOException;
- @Override
- public void run() {
- try {
- mInStream = getRequestResult();
- if (mInStream != null) {
- String result = new String(readInputStream(mInStream));
- Object obj = parseHandler.parse(result);
- requestCallback.onSuccess(obj);
- } else {
- System.out.println("get InputStream By HttpURLConnection return result is NULL.");
- }
- } catch (IOException e) {
- requestCallback.onFail(Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO异常标识
- e.printStackTrace();
- }
- }
- /**
- * 从输入流读取数据
- *
- * @param inStream
- * @return
- * @throws IOException
- * @throws Exception
- */
- protected byte[] readInputStream(InputStream inStream) throws IOException {
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = inStream.read(buffer)) != -1) {
- outSteam.write(buffer, 0, len);
- }
- outSteam.close();
- inStream.close();
- return outSteam.toByteArray();
- }
- public HttpURLConnection getRequestConn() {
- return mHttpURLConn;
- }
- }
好了就到这里吧,后面的待续。。。
吐槽下:在CSDN上写文章,写完后你若想删除掉之前写的一部分内容,就得一行一行删,不能选中某个区域,之后一次性删除,真郁闷。我记得之前不是这样的,现在为什么会这样呢?我刚才删除写错的文字和代码就用了我五分钟左右,真的想说粗话了,但想了下,算了。我是一个文明的人,呵呵。
这一篇网络模块处理有些地方有待优化,优化处理部分请阅读下篇Android仿人人客户端(v5.7.1)——网络模块优化
- Android仿人人客户端(v5.7.1)——网络模块处理的架构
- Android仿人人客户端(v5.7.1)——网络模块处理的架构
- Android仿人人客户端(v5.7.1)——网络模块优化
- Android仿人人客户端(v5.7.1)——网络模块时序图
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(流程图或活动图)
- Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)
- Android仿人人客户端(v5.7.1)——欢迎和导引界面的类图
- Android仿人人客户端(v5.7.1)——欢迎和导引界面的编码实现
- Android仿人人客户端(v5.7.1)——消息中心视图的实现
- Android仿人人客户端(v5.7.1)——人人授权访问界面
- Android仿人人客户端(v5.7.1)——主流程(活动)图
- Android仿人人客户端(v5.7.1)——个人主页(一)
- Android仿人人客户端(v5.7.1)——个人主页(二)
- Android仿人人客户端(v5.7.1)——个人主页(三)
- Android仿人人客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图
- Android仿人人客户端(v5.7.1)——新鲜事之状态
- Android仿人人客户端(v5.7.1)——新鲜事之分享照片
- Android仿人人客户端(v5.7.1)——新鲜事之完整篇
- unity地形Terrain浅谈
- 再谈我是怎么招聘程序员的
- 拓扑排序——判断有向图是否存在回路
- 那点所谓的分布式——memcache
- Tair
- Android仿人人客户端(v5.7.1)——网络模块处理的架构
- PV 并发量的计算
- 多线程第三篇:关键段(临界区)
- 理解Android系统的进程间通信原理(一)----RPC中的代理模式
- 在Lu脚本中绘制普通XY图(折线图)
- 对Java语言入门初学者的一些建议
- 从多个文件中搜索指定单词功能实现
- Navigation Drawer
- getComputedStyle与currentStyle