最近在做android客户端的统计sdk,为了保证数据统计的准确行,需要把一些基本信息,和无网络情况下用户的操作保存到SqlLite本地数据库中,等待有网了的时候进行传;

基本解决思路,离线操作的数据请求URL和请求参数进行封装,封装到对象中,转化为json存储到SQlLite数据库中;定时任务检测网络情况,如果有网,则把数据库中数据取出,进行网络上传;

    取出数据库中请求,就需要处理大量网络请求,同时发送请求的情况,一般来说一个网络请求都会用使用到一个异步线程,大量的线程创建、运行、销毁又造成了系统资源的浪费,而且同时同时new出多个子线程也会造成客户端卡死现象;于是考虑到能不能做个请求队列去进行控制

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


更多相关文章

  1. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  2. Android(安卓)ANR分析
  3. 线程方法Android:异步调用详解
  4. 金九银十中,看看这31道Android面试题
  5. Android(安卓)Handler 作用以及使用
  6. Android每周一轮子:OkHttp(1)
  7. 移动端启动速度
  8. Android(安卓)AsyncTask !!!!
  9. Android常见40道原理性面试,去面试之前必须要了解的知识点

随机推荐

  1. Android(安卓)Studio android APP混淆打
  2. 用 Python脚本生成 Android(安卓)SALT 盐
  3. Android(安卓)利用程序实现GPS的打开或关
  4. Android中调用webservice小结
  5. android使用aidl实现进程间通信的实例
  6. Android(安卓)动画
  7. Android中目的地Intent的使用
  8. greendao3.2.0使用方法(超详细)
  9. Android(安卓)clickable 属性问题
  10. 2019-08-20 Android(安卓)线性布局介绍-L