android并发请求处理

以你之姓@ 2022-08-20 13:22 357阅读 0赞

最近在做android统计SDK,因为之前参与的网络开发项目都遇到一些相同的问题:

1.大量的并发请求造成堵塞,特别是遇上让人无语的3G网络,无限loading。。。

2.一般来说一个网络请求都会用使用到一个异步线程,大量的线程创建、运行、销毁又造成了系统资源的浪费

3.请求结束得到结果后,如果需要更新UI,一个不小心忘了返回UI线程,各种崩溃。。。

前些日子跟同事商量能不能做个请求队列去进行控制,于是趁着热度没消退说干就干,建了个模型,以备日后使用。

在这个模型中,有高中低三个优先级信道如下:高优先级—1,中优先级—3,低优先级—2

规则:

1.正常情况下各个优先级使用各自信道(线程)

2.高级信道满载、中、低级信道空置,则高级请求可使用低级信道

构思:

UI线程将期望的网络请求url和参数通过一个封装好的Runnable提交给Service处理(当然也可以交给一个Thread处理,本例使用Service),Service接收到请求,判断优先级,加入到相应线程池中排队。线程池启动线程发起网络请求,最后通过监听器将结果返回给Service,Service发送广播通知UI线程,UI线程更新相关界面,结束。

废话说完,上例子:

首先是封装好的Runnable

  1. public class HttpConnRunnable implements Runnable, Parcelable {
  2. public static final int HIGH_LEVEL = 0;
  3. public static final int NORMAL_LEVEL = 1;
  4. public static final int LOW_LEVEL = 2;
  5. private int mPriority = NORMAL_LEVEL;//优先级,默认为普通
  6. private String mUrl = “”;
  7. private HttpConnListener mListener;//监听器
  8. public HttpConnRunnable() {
  9. super();
  10. }
  11. public HttpConnRunnable(int priority) {
  12. super();
  13. mPriority = priority;
  14. }
  15. @Override
  16. public void run() {
  17. Log.i(Thread.currentThread().getName(), “——Start to connect:” + mUrl + “, priority:” + mPriority + “——-“);
  18. try {
  19. Thread.sleep(10000);
  20. //TODO:进行网络请求相关操作,并通过listener返回结果
  21. mListener.onSucceed(“Connected to “ + mUrl + “ succeed!”);
  22. }
  23. catch (InterruptedException e) {
  24. e.printStackTrace();
  25. }
  26. Log.i(Thread.currentThread().getName(), “——Finish to connect:” + mUrl + “, priority:” + mPriority + “——-“);
  27. }
  28. public int getPriority() {
  29. return mPriority;
  30. }
  31. public void setPriority(int priority) {
  32. mPriority = priority;
  33. }
  34. public String getURL() {
  35. return mUrl;
  36. }
  37. public void setURL(String url) {
  38. mUrl = url;
  39. }
  40. public void setHttpConnListener(HttpConnListener listener) {
  41. mListener = listener;
  42. }
  43. //序列化,为了传递给Service,如果是使用Thread处理本例,则无需序列化
  44. public static final Parcelable.Creator CREATOR = new Creator() {
  45. @Override
  46. public HttpConnRunnable createFromParcel(Parcel source) {
  47. HttpConnRunnable data = null;
  48. Bundle bundle = source.readBundle();
  49. if(bundle != null) {
  50. data = new HttpConnRunnable(bundle.getInt(“PRIORITY”));
  51. data.mUrl = bundle.getString(“URL”);
  52. }
  53. return data;
  54. }
  55. @Override
  56. public HttpConnRunnable[] newArray(int size) {
  57. return new HttpConnRunnable[size];
  58. }
  59. };
  60. @Override
  61. public int describeContents() {
  62. return 0;
  63. }
  64. @Override
  65. public void writeToParcel(Parcel dest, int flags) {
  66. Bundle bundle = new Bundle();
  67. bundle.putInt(“PRIORITY”, mPriority);
  68. bundle.putString(“URL”, mUrl);
  69. dest.writeBundle(bundle);
  70. }
  71. }
  1. Service的处理:
  1. public class HttpConnService extends Service implements HttpConnListener {
  2. public static final String HTTP_POOL_PARAM_KEYWORD = “HttpPoolParam”; //网络参数传递的关键字
  3. private final int HIGH_POOL_SIZE = 1;
  4. private final int NORMAL_POOL_SIZE = 3;
  5. private final int LOW_POOL_SIZE = 2;
  6. // 可重用固定线程数的线程池
  7. private ThreadPoolExecutor mHighPool;
  8. private ThreadPoolExecutor mNormalPool;
  9. private ThreadPoolExecutor mLowPool;
  10. @Override
  11. public void onCreate() {
  12. //初始化所有
  13. mHighPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(HIGH_POOL_SIZE);
  14. mNormalPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(NORMAL_POOL_SIZE);
  15. mLowPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(LOW_POOL_SIZE);
  16. super.onCreate();
  17. }
  18. @Override
  19. public int onStartCommand(Intent intent, int flags, int startId) {
  20. //接受到来自UI线程的请求
  21. //取出Runnable,并加入到相应队列
  22. Bundle bundle = intent.getExtras();
  23. HttpConnRunnable httpConnRunnable = bundle.getParcelable(HTTP_POOL_PARAM_KEYWORD);
  24. if (httpConnRunnable != null) {
  25. httpConnRunnable.setHttpConnListener(HttpConnService.this);
  26. int level = httpConnRunnable.getPriority();
  27. switch (level) {
  28. case HttpConnRunnable.HIGH_LEVEL:
  29. //如果高级池满而低级池未满交由低级池处理
  30. //如果高级池满而普通池未满交由普通池处理
  31. //如果高级池未满则交给高级池处理,否则,交由高级池排队等候
  32. if (mHighPool.getActiveCount() == HIGH_POOL_SIZE && mLowPool.getActiveCount() < LOW_POOL_SIZE) {
  33. mLowPool.execute(httpConnRunnable);
  34. }
  35. else if (mHighPool.getActiveCount() == HIGH_POOL_SIZE && mNormalPool.getActiveCount() < NORMAL_POOL_SIZE) {
  36. mNormalPool.execute(httpConnRunnable);
  37. }
  38. else {
  39. mHighPool.execute(httpConnRunnable);
  40. }
  41. break;
  42. case HttpConnRunnable.NORMAL_LEVEL:
  43. //如果普通池满而低级池未满交由低级池处理
  44. //如果普通池未满则交给普通池处理,否则,交由普通池排队等候
  45. if (mNormalPool.getActiveCount() == NORMAL_POOL_SIZE && mLowPool.getActiveCount() < LOW_POOL_SIZE) {
  46. mLowPool.execute(httpConnRunnable);
  47. }
  48. else {
  49. mNormalPool.execute(httpConnRunnable);
  50. }
  51. break;
  52. case HttpConnRunnable.LOW_LEVEL:
  53. mLowPool.execute(httpConnRunnable);
  54. break;
  55. }
  56. }
  57. return super.onStartCommand(intent, flags, startId);
  58. }
  59. @Override
  60. public void onDestroy() {
  61. mHighPool.shutdownNow();
  62. mNormalPool.shutdownNow();
  63. mLowPool.shutdownNow();
  64. mNormalPool = null;
  65. mLowPool = null;
  66. super.onDestroy();
  67. }
  68. @Override
  69. public IBinder onBind(Intent intent) {
  70. return null;
  71. }
  72. @Override
  73. public void onSucceed(String result) {
  74. Intent intent = new Intent();
  75. intent.setAction(“com.ezstudio.connpool.HttpConnReceiver”);
  76. // 要发送的内容
  77. intent.putExtra(“RESULT”, result);
  78. // 发送 一个无序广播
  79. sendBroadcast(intent);
  80. }
  81. @Override
  82. public void onFailed() {
  83. // TODO Auto-generated method stub
  84. }
  85. }
  1. Receiver的处理比较简单:
  1. public class HttpConnReceiver extends BroadcastReceiver {
  2. private HttpConnListener mListener;
  3. public void setHttpConnListener (HttpConnListener listener) {
  4. mListener = listener;
  5. }
  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. String action = intent.getAction();
  9. if (action.equals(“com.ezstudio.connpool.HttpConnReceiver”)) {
  10. String result = intent.getStringExtra(“RESULT”);
  11. mListener.onSucceed(result);
  12. }
  13. }
  14. }

发表评论

表情:
评论列表 (有 0 条评论,357人围观)

还没有评论,来说两句吧...

相关阅读

    相关 android并发请求处理

    最近在做android统计SDK,因为之前参与的网络开发项目都遇到一些相同的问题: 1.大量的并发请求造成堵塞,特别是遇上让人无语的3G网络,无限loading。。。 2.