編輯:Android開發實例
上一篇聊到網絡模塊的架構,我後來思考了下,覺得有可以優化的地方。
一、先提出我後來思考的問題:
在AppBaseActivity(對Activity類的擴展)中,用變量mAsyncRequests存儲當前activity所持有的所有網絡請求,仔細閱讀過上一篇源碼的朋友,一定知道有兩處中斷當前Activity所持有的網絡異步處理,分別是在activity暫停(回調方法onPause())和銷毀(回調方法onDestroy())的時候。上一篇的處理方式,代碼片段如下:
- 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 .
- }
- }
- }
- }
- }
仔細閱讀上面的代碼片段,會發現只是斷開了網絡請求返回,之後就從當前Activity所持有的網絡請求集合中移除了AsyncBaseRequest對象,經過實踐就會發現,這種處理方式明顯存在問題。中斷網絡異步請求時,會有以下幾種場景:
1、在異步線程中,當前正在發生著通過HTTP協議獲取服務器端返回的數據(InputStream),恰巧在這個時候調用請求中斷異步處理,上一篇的處理方式能處理。
2、在異步線程中,當前正發生著網絡請求的數據已返回,這時調用中斷處理,也就是說後面的數據解析和刷新UI的事就不處理了,上一篇的處理方式不能滿足需求。
3、在異步線程中,當前正發生著網絡請求返回的數據已解析完,這時調用中斷處理,也就是說後面讓主線程刷新UI的事就不處理了,上一篇的處理方式不能滿足需求。
4、在異步線程中,當前正在發生著。。。,這時調用中斷處理,後面的。。。就不用處理了。(可以控制顆粒度精細點,呵呵)
二、對上面提出的問題,我的解決方案只考慮三種情況,在Activity中調用中斷處理時,異步線程中的預處理方式。
1、在異步線程類(AsyncBaseRequest)中添加中斷標識,代碼如下:
- private boolean interrupted;
- public boolean isInterrupted() {
- return interrupted;
- }
- public void setInterrupted(boolean interrupted) {
- this.interrupted = interrupted;
- }
2、在異步線程類(AsyncBaseRequest)中的核心方法中添加預處理,代碼如下:
- @Override
- public void run() {
- try {
- if (interrupted) {
- System.err.println("訪問網絡前中斷業務處理線程(終止)");
- return;
- }
- mInStream = getRequestResult();
- if (mInStream != null) {
- if (interrupted) {
- System.err.println("解析數據前中斷業務處理線程(終止)");
- return;
- }
- String result = new String(readInputStream(mInStream));
- Object obj = parseHandler.parse(result);
- if (interrupted) {
- System.err.println("刷新UI前中斷業務處理線程(終止)");
- return;
- }
- requestCallback.onSuccess(obj);
- } else {
- System.out.println("get InputStream By HttpURLConnection return result is NULL.");
- requestCallback.onFail(Constant.NETWORK_REQUEST_RETUN_NULL); // 網絡請求返回NULL
- }
- } catch (IOException e) {
- requestCallback.onFail(Constant.NETWORK_REQUEST_IOEXCEPTION_CODE); // IO異常標識
- e.printStackTrace();
- } catch (JSONException e) {
- requestCallback.onFail(Constant.NETWORK_REQUEST_RESULT_PARSE_ERROR); // 網絡請求返回結果解析出錯
- e.printStackTrace();
- }
- }
3、在Activity(AppBaseActivity)中的處理,代碼如下:
- @Override
- protected void onPause() {
- /**
- * 在activity暫停的時候,同時設置終止標識,終止異步線程
- */
- cancelAllRequest();
- super.onPause();
- }
- private void cancelAllRequest() {
- if (mAsyncRequests != null && mAsyncRequests.size() > 0) {
- try {
- for (AsyncBaseRequest request : mAsyncRequests) {
- Thread thread = new Thread(request);
- if (thread.isAlive() || !Thread.interrupted()) {
- request.setInterrupted(true);
- }
- HttpURLConnection conn = request.getRequestConn();
- if (conn != null) {
- // conn.disconnect();
- System.err.println("onDestroy disconnect URL: " + conn.getURL());
- }
- mAsyncRequests.remove(request);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- @Override
- protected void onDestroy() {
- /**
- * 在activity銷毀的時候,同時設置終止標識,終止異步線程
- */
- cancelAllRequest();
- super.onDestroy();
- }
以上就是對上一篇網絡處理模塊中存在的問題,我的解決方式。大家有什麼更好的方式,可以交流下。互相借鑒,共同進步!
轉自:http://blog.csdn.net/android_ls/article/details/8740447
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放