Android网络开发 请求队列
来源:互联网 发布:算法与数据结构 书籍 编辑:程序博客网 时间:2024/05/29 00:32
Android网络开发 请求队列
文章出处:Android那些事儿的博客
因为之前参与的网络开发项目都遇到一些相同的问题:
1.大量的并发请求造成堵塞,特别是遇上让人无语的3G网络,无限loading。。。
2.一般来说一个网络请求都会用使用到一个异步线程,大量的线程创建、运行、销毁又造成了系统资源的浪费
3.请求结束得到结果后,如果需要更新UI,一个不小心忘了返回UI线程,各种崩溃。。。
前些日子跟同事商量能不能做个请求队列去进行控制,于是趁着热度没消退说干就干,建了个模型,以备日后使用。
在这个模型中,有高中低三个优先级信道如下:高优先级–1,中优先级–3,低优先级–2
规则:
1.正常情况下各个优先级使用各自信道(线程)
2.高级信道满载、中、低级信道空置,则高级请求可使用低级信道
构思:
UI线程将期望的网络请求url和参数通过一个封装好的Runnable提交给Service处理(当然也可以交给一个Thread处理,本例使用Service),Service接收到请求,判断优先级,加入到相应线程池中排队。线程池启动线程发起网络请求,最后通过监听器将结果返回给Service,Service发送广播通知UI线程,UI线程更新相关界面,结束。
废话说完,上例子:
首先是封装好的Runnable
public class HttpConnRunnable implements Runnable, Parcelable {
public static final int HIGH_LEVEL = 0; public static final int NORMAL_LEVEL = 1; public static final int LOW_LEVEL = 2; private int mPriority = NORMAL_LEVEL;//优先级,默认为普通 private String mUrl = ""; private HttpConnListener mListener;//监听器 public HttpConnRunnable() { super(); } public HttpConnRunnable(int priority) { super(); mPriority = priority; } @Override public void run() { Log.i(Thread.currentThread().getName(), "----Start to connect:" + mUrl + ", priority:" + mPriority + "-----"); try { Thread.sleep(10000); //TODO:进行网络请求相关操作,并通过listener返回结果 mListener.onSucceed("Connected to " + mUrl + " succeed!"); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(Thread.currentThread().getName(), "----Finish to connect:" + mUrl + ", priority:" + mPriority + "-----"); } public int getPriority() { return mPriority; } public void setPriority(int priority) { mPriority = priority; } public String getURL() { return mUrl; } public void setURL(String url) { mUrl = url; } public void setHttpConnListener(HttpConnListener listener) { mListener = listener; } //序列化,为了传递给Service,如果是使用Thread处理本例,则无需序列化 public static final Parcelable.Creator<HttpConnRunnable> CREATOR = new Creator<HttpConnRunnable>() { @Override public HttpConnRunnable createFromParcel(Parcel source) { HttpConnRunnable data = null; Bundle bundle = source.readBundle(); if(bundle != null) { data = new HttpConnRunnable(bundle.getInt("PRIORITY")); data.mUrl = bundle.getString("URL"); } return data; } @Override public HttpConnRunnable[] newArray(int size) { return new HttpConnRunnable[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { Bundle bundle = new Bundle(); bundle.putInt("PRIORITY", mPriority); bundle.putString("URL", mUrl); dest.writeBundle(bundle); }
}
Service的处理:
public class HttpConnService extends Service implements HttpConnListener {
public static final String HTTP_POOL_PARAM_KEYWORD = “HttpPoolParam”; //网络参数传递的关键字
private final int HIGH_POOL_SIZE = 1; private final int NORMAL_POOL_SIZE = 3; private final int LOW_POOL_SIZE = 2; // 可重用固定线程数的线程池 private ThreadPoolExecutor mHighPool; private ThreadPoolExecutor mNormalPool; private ThreadPoolExecutor mLowPool; @Override public void onCreate() { //初始化所有 mHighPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(HIGH_POOL_SIZE); mNormalPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(NORMAL_POOL_SIZE); mLowPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(LOW_POOL_SIZE); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //接受到来自UI线程的请求 //取出Runnable,并加入到相应队列 Bundle bundle = intent.getExtras(); HttpConnRunnable httpConnRunnable = bundle.getParcelable(HTTP_POOL_PARAM_KEYWORD); if (httpConnRunnable != null) { httpConnRunnable.setHttpConnListener(HttpConnService.this); int level = httpConnRunnable.getPriority(); switch (level) { case HttpConnRunnable.HIGH_LEVEL: //如果高级池满而低级池未满交由低级池处理 //如果高级池满而普通池未满交由普通池处理 //如果高级池未满则交给高级池处理,否则,交由高级池排队等候 if (mHighPool.getActiveCount() == HIGH_POOL_SIZE && mLowPool.getActiveCount() < LOW_POOL_SIZE) { mLowPool.execute(httpConnRunnable); } else if (mHighPool.getActiveCount() == HIGH_POOL_SIZE && mNormalPool.getActiveCount() < NORMAL_POOL_SIZE) { mNormalPool.execute(httpConnRunnable); } else { mHighPool.execute(httpConnRunnable); } break; case HttpConnRunnable.NORMAL_LEVEL: //如果普通池满而低级池未满交由低级池处理 //如果普通池未满则交给普通池处理,否则,交由普通池排队等候 if (mNormalPool.getActiveCount() == NORMAL_POOL_SIZE && mLowPool.getActiveCount() < LOW_POOL_SIZE) { mLowPool.execute(httpConnRunnable); } else { mNormalPool.execute(httpConnRunnable); } break; case HttpConnRunnable.LOW_LEVEL: mLowPool.execute(httpConnRunnable); break; } } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { mHighPool.shutdownNow(); mNormalPool.shutdownNow(); mLowPool.shutdownNow(); mNormalPool = null; mLowPool = null; super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onSucceed(String result) { Intent intent = new Intent(); intent.setAction("com.ezstudio.connpool.HttpConnReceiver"); // 要发送的内容 intent.putExtra("RESULT", result); // 发送 一个无序广播 sendBroadcast(intent); } @Override public void onFailed() { // TODO Auto-generated method stub }
}
Receiver的处理比较简单:
public class HttpConnReceiver extends BroadcastReceiver {
private HttpConnListener mListener;
public void setHttpConnListener (HttpConnListener listener) { mListener = listener; } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals("com.ezstudio.connpool.HttpConnReceiver")) { String result = intent.getStringExtra("RESULT"); mListener.onSucceed(result); } }
}
可能很多同学都看过这么文章,不过由于没有源码可能还是云里雾里,由于我也是个小菜鸟的关系就本着学习的心态对照原博客,可新浪微博发送微博的效果自己实现了队列请求的效果,便记录下来,以便日后拿来用。也将源码分享给大家
源码
此源码是as工程,不会在eclipse导入as工程的同学可以new eclipse工程,拷一下代码和布局文件。。。
菜鸟转载,不喜勿喷
- Android网络开发 请求队列
- android开发网络请求
- Android开发请求网络方式
- Android开发 多线程网络请求
- Android开发之网络请求
- 网络请求队列
- iOS网络开发中的同步、异步和请求队列
- iOS网络开发中的同步、异步和请求队列
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- android开发之网络请求框架比较
- Android开发请求网络方式详解
- Android开发请求网络方式详解
- 使用session pool来优化mongodb的性能
- Android Studio 利用Gradle来混淆代码
- mysql简单查询语句的执行顺序
- 背包九讲
- 第十周 项目一-建立二叉树算法库
- Android网络开发 请求队列
- 我出去找工作,应该要多少合适
- Qt Pro
- 第十周项目--建立二叉树算法库
- Android Material Style 学习资料
- 将原先的matchsets中的产品替换为它的分词结果
- Android中的service
- NGINX原理分析 之 SLAB分配机制
- JDBC基础学习笔记_01JDBC基础简介