android并发网络请求的处理

来源:互联网 发布:java获取所有interface 编辑:程序博客网 时间:2024/06/06 17:22

      最近在做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 0
原创粉丝点击