Volley簡單學習使用五—— 源代碼分析三

一、Volley工作流程圖:


二、Network
? ? 在NetworkDispatcher中須要處理的網絡請求。由以下進行處理:
    NetworkResponse networkResponse = mNetwork.performRequest(request);
看一下mNetwork的定義:(定義在NetworkDispatcher中)

    /** The network interface for processing requests. */private final Network mNetwork;
NetworkDispatcher.mNetwork初始化發生在RequestQueue.start()中:

    NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,mCache, mDelivery);
而RequestQueue.mNetwork是在其構造函數中傳入的:

    public RequestQueue(Cache cache, Network network, int threadPoolSize,ResponseDelivery delivery) {mCache = cache;mNetwork = network;mDispatchers = new NetworkDispatcher[threadPoolSize];mDelivery = delivery;}
由前面分析知RequestQueue的構建是在Volley.newRequestQueue中實現的:

    //創建以stack為參數的Network對象Network network = new BasicNetwork(stack);//創建RequestQueue對象RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);queue.start();//繼續向下分析的入口

? ? 能夠看出mNetwork事實上是BasicNetwork對象。
? ? 則NetworkResponse中mNetwork實際上調用的是BasicNetwork.performRequest(),這是一個專門用來處理網絡請求的函數,其作用為調用HttpStack處理請求,并將結果轉換為可被ResponseDelivery處理的NetworkResponse
看一下其源代碼:
   @Overridepublic NetworkResponse performRequest(Request<?> request) throws VolleyError {long requestStart = SystemClock.elapsedRealtime();while (true) {HttpResponse httpResponse = null;byte[] responseContents = null;Map<String, String> responseHeaders = new HashMap<String, String>();try {/** 忽略網絡處理的細節*/// Gather headers.Map<String, String> headers = new HashMap<String, String>();addCacheHeaders(headers, request.getCacheEntry());/**運行網絡請求* 這里調用了HttpStack.performRequest。并得到一個HttpResponse返回結果*/httpResponse = mHttpStack.performRequest(request, headers);StatusLine statusLine = httpResponse.getStatusLine();int statusCode = statusLine.getStatusCode();responseHeaders = convertHeaders(httpResponse.getAllHeaders());/**新奇度驗證:* 304 Not Modified:client有緩沖的文件并發出了一個條件性的請求* (通常是提供If-Modified-Since頭表示客戶僅僅想比指定日期更新的文檔)。* server告訴客戶。原來緩沖的文檔還能夠繼續使用。*/if (statusCode == HttpStatus.SC_NOT_MODIFIED) {/** 解析成NetworkResponse,返回*/return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,request.getCacheEntry().data, responseHeaders, true);}// 推斷responses是否有實體信息,一些響應如204,并不包括content。所以須要驗證if (httpResponse.getEntity() != null) {//實體信息轉化成byte[]responseContents = entityToBytes(httpResponse.getEntity());} else {// 無實體信息情況responseContents = new byte[0];}// 超時情況處理.long requestLifetime = SystemClock.elapsedRealtime() - requestStart;logSlowRequests(requestLifetime, request, responseContents, statusLine);if (statusCode < 200 || statusCode > 299) {throw new IOException();}return new NetworkResponse(statusCode, responseContents, responseHeaders, false);} catch (SocketTimeoutException e) {attemptRetryOnException("socket", request, new TimeoutError());} catch (ConnectTimeoutException e) {attemptRetryOnException("connection", request, new TimeoutError());} catch (MalformedURLException e) {throw new RuntimeException("Bad URL " + request.getUrl(), e);} catch (IOException e) {...}}}

?總結一下Network.performRequest所做的工作:

1、由傳入的HttpStack對象運行網絡請求:mHttpStack.performRequest()

2、解析響應結果,將HttpResponse解析成NetworkResponse;

3、對返回結果進行新奇度驗證(304)

4、將response的實體信息轉化為byte數組

5、超時情況處理,假設發生超時,認證失敗等錯誤。進行重試操作(attemptRetryOnException)。直到成功、拋出異常(不滿足重試策略等)結束。


attemptRetryOnException()是依據重試策略進行請求重試操作:

    /*** Attempts to prepare the request for a retry. If there are no more attempts remaining in the* request's retry policy, a timeout exception is thrown.*/private static void attemptRetryOnException(String logPrefix, Request<?

> request, VolleyError exception) throws VolleyError { RetryPolicy retryPolicy = request.getRetryPolicy(); int oldTimeout = request.getTimeoutMs(); try { retryPolicy.retry(exception); } catch (VolleyError e) { request.addMarker( String.format("%s-timeout-giveup [timeout=%s]", logPrefix, oldTimeout)); throw e; } request.addMarker(String.format("%s-retry [timeout=%s]", logPrefix, oldTimeout)); }

三、HttpClientStack、HurlStack
? ? 據上面源代碼知。網絡請求處理的邏輯實際上是交由傳進來的參數HttpStack進行處理。

前面已經分析過。Android2.3之前使用?HttpClientStack,之后使用HurlStack。

1、先看兩者的父類HttpStack:
    public interface HttpStack {/*** Performs an HTTP request with the given parameters.* <p>A GET request is sent if request.getPostBody() == null. A POST request is sent otherwise,* and the Content-Type header is set to request.getPostBodyContentType().</p>* @param request the request to perform* @param 發起請求之前,加入額外的請求 Headers {@link Request#getHeaders()}*/public HttpResponse performRequest(Request<?

> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError; }

2、HttpClientStack(使用HttpClient來實現)

    @Overridepublic HttpResponse performRequest(Request<?

> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);//見附一 addHeaders(httpRequest, additionalHeaders); addHeaders(httpRequest, request.getHeaders()); onPrepareRequest(httpRequest);// Nothing.空函數,用于重寫;該函數在request被excute之前被調用 //一些網絡設置 HttpParams httpParams = httpRequest.getParams(); int timeoutMs = request.getTimeoutMs(); // TODO: Reevaluate this connection timeout based on more wide-scale // data collection and possibly different for wifi vs. 3G. HttpConnectionParams.setConnectionTimeout(httpParams, 5000); HttpConnectionParams.setSoTimeout(httpParams, timeoutMs); return mClient.execute(httpRequest); }

附一:createHttpRequest函數:

    /*** 依據傳進來的request來構造合適的HttpUriRequest*/static HttpUriRequest createHttpRequest(Request<?> request,Map<String, String> additionalHeaders) throws AuthFailureError {switch (request.getMethod()) {case Method.DEPRECATED_GET_OR_POST: {// This is the deprecated way that needs to be handled for backwards compatibility.// If the request's post body is null, then the assumption is that the request is// GET.  Otherwise, it is assumed that the request is a POST.byte[] postBody = request.getPostBody();if (postBody != null) {HttpPost postRequest = new HttpPost(request.getUrl());postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());HttpEntity entity;entity = new ByteArrayEntity(postBody);postRequest.setEntity(entity);return postRequest;} else {return new HttpGet(request.getUrl());}}/***********一般較多使用的是POST與GET。其等同于HttpClient的一般使用流程***************/case Method.GET:return new HttpGet(request.getUrl());case Method.DELETE:return new HttpDelete(request.getUrl());case Method.POST: {HttpPost postRequest = new HttpPost(request.getUrl());//這里就看到了前面實現Request時,重寫getBodyContentType()函數的意義postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());setEntityIfNonEmptyBody(postRequest, request);return postRequest;}case Method.PUT: {HttpPut putRequest = new HttpPut(request.getUrl());putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());setEntityIfNonEmptyBody(putRequest, request);return putRequest;}default:throw new IllegalStateException("Unknown request method.");}}
3、HurlStack(由HttpURLConnection來實現)
    @Overridepublic HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)throws IOException, AuthFailureError {String url = request.getUrl();HashMap<String, String> map = new HashMap<String, String>();map.putAll(request.getHeaders());map.putAll(additionalHeaders);//UrlRewriter見附一if (mUrlRewriter != null) {String rewritten = mUrlRewriter.rewriteUrl(url);if (rewritten == null) {thrownew IOException("URL blocked by rewriter: " + url);}url = rewritten;}/**************HttpURLConnection的一般使用流程*******************/URL parsedUrl = new URL(url);HttpURLConnection connection = openConnection(parsedUrl, request);for (String headerName : map.keySet()) {connection.addRequestProperty(headerName, map.get(headerName));}setConnectionParametersForRequest(connection, request);// Initialize HttpResponse with data from the HttpURLConnection.ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);int responseCode = connection.getResponseCode();if (responseCode == -1) {// -1 is returned by getResponseCode() if the response code could not be retrieved.// Signal to the caller that something was wrong with the connection.thrownew IOException("Could not retrieve response code from HttpUrlConnection.");}StatusLine responseStatus = new BasicStatusLine(protocolVersion,connection.getResponseCode(), connection.getResponseMessage());BasicHttpResponse response = new BasicHttpResponse(responseStatus);response.setEntity(entityFromConnection(connection));for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {if (header.getKey() != null) {Header h = new BasicHeader(header.getKey(), header.getValue().get(0));response.addHeader(h);}}return response;}
附一:UrlRewriter

    /** 對URLs在使用前進行重寫轉換*/public interface UrlRewriter {/*** Returns a URL to use instead of the provided one, or null to indicate* this URL should not be used at all.*/public String rewriteUrl(String originalUrl);}
參數mUrlRewriter通過HttpStack的構造函數傳入進來,故能夠自行進行定義:
    public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {mUrlRewriter = urlRewriter;mSslSocketFactory = sslSocketFactory;}

四、NetworkResponse
? ? 回到起點NetworkDispatcher(Thread)中的run()函數,當中:

????NetworkResponse?networkResponse?= mNetwork.performRequest(request);

以下繼續看NetworkResponse的源代碼:
NetworkResponse類非常easy,僅是用以在多個類中傳遞數據,其成員變量:
1)成員變量
int statusCode?Http 響應狀態碼

byte[] data?Body 數據
Map<String, String> headers?響應 Headers
boolean notModified?表示是否為 304 響應
long networkTimeMs?請求耗時

2)其主體僅僅為幾個構造函數:
    public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,boolean notModified) {this.statusCode = statusCode;this.data = data;this.headers = headers;this.notModified = notModified;}public NetworkResponse(byte[] data) {this(HttpStatus.SC_OK, data, Collections.<String, String>emptyMap(), false);}public NetworkResponse(byte[] data, Map<String, String> headers) {this(HttpStatus.SC_OK, data, headers, false);}
3)回想一下前面分析的設計NetworkResponse的類之間數據的傳遞關系:



這里的主體是依據NetworkDispatcher.run()函數進行分析的
0、函數中調用Network.performRequest();
? ? ?NetworkResponse networkResponse = mNetwork.performRequest(request);
? ? ?而Network.performRequest()是基于HttpStack實現的;
1、HttpClientStack與HurlStack(分別基于HttpClient與HttpURLConnection實現)中的public HttpResponse performRequest()函數返回HttpResponse?;
2、Network(實際為BasicNetwork)中performRequest()方法。使用1中的兩個HttpStack類。獲取到其返回值HttpResponse,然后將其解析成為NetworkResponse;
3、Request中 abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
? ? 將NetworkResponse解析成Response;
? ? 而該函數的調用是在NetworkDispatcher中的run()函數中調用的。 ? ? ? ? ? ? ? ?
4、在NetworkDispatcher.run()的最后一步:
? ? mDelivery.postResponse(request, response);
? ? 將response傳遞給了ResponseDelivery
后面繼續看Delivery的邏輯;
ResponseDelivery mDelivery的實際類型是ExecutorDelivery:
public RequestQueue(Cache cache, Network network, int threadPoolSize) {this(cache, network, threadPoolSize,new ExecutorDelivery(new Handler(Looper.getMainLooper())));
}
public ExecutorDelivery(final Handler handler) {// Make an Executor that just wraps the handler.mResponsePoster = new Executor() {@Overridepublic void execute(Runnable command) {handler.post(command);}};}
能夠看到非常easy,就是使用主線程的Looper構建一個Handler。以下全部的post操作都是調用這個Handler來運行Runnable;

比方:

@Override
public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {request.markDelivered();request.addMarker("post-response");mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
}
將傳遞來的Response轉化為ResponseDeliveryRunnable?,顯然這是一個Runnable;

private class ResponseDeliveryRunnable implements Runnable {private final Request mRequest;private final Response mResponse;private final Runnable mRunnable;public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {mRequest = request;mResponse = response;mRunnable = runnable;}@SuppressWarnings("unchecked")@Overridepublic void run() {// If this request has canceled, finish it and don't deliver.if (mRequest.isCanceled()) {mRequest.finish("canceled-at-delivery");return;}// Deliver a normal response or error, depending.if (mResponse.isSuccess()) {mRequest.deliverResponse(mResponse.result);} else {mRequest.deliverError(mResponse.error);}// If this is an intermediate response, add a marker, otherwise we're done// and the request can be finished.if (mResponse.intermediate) {mRequest.addMarker("intermediate-response");} else {mRequest.finish("done");}// If we have been provided a post-delivery runnable, run it.if (mRunnable != null) {mRunnable.run();}}}
在這個子線程中,轉而調用 Request來deliverResponse:

以StringRequest為例,來看這個函數:

@Override
protected void deliverResponse(String response) {if (mListener != null) {mListener.onResponse(response);}
}
這個Listener就是自己在定義Request的時候聲明的ResponseListener,能夠看到這個Listener工作在子線程中,所以假設要更新界面,注意使用Handler把消息傳遞主線程進行處理。


***************************************************** Volley圖片載入的實現 *******************************************************
Volley的圖片載入主要還是基于上面的原理來實現的。詳細例如以下:
ImageLoader的使用:
//創建ImageLoader
imageLoader = new ImageLoader(httpUtils.getRequestQueue(), imageCache);
public ImageLoader(RequestQueue queue, ImageCache imageCache) {mRequestQueue = queue;mCache = imageCache;}
這里面的ImageCache是自己定義的:
// 獲取最大內存緩存大小
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
MAX_CACHE_SIZE = maxMemory / 8; // 定義為應用最大緩存的1/8mImageLruCache = new LruCache<String, Bitmap>(MAX_CACHE_SIZE){@Overrideprotected int sizeOf(String url, Bitmap bitmap){return bitmap.getRowBytes() * bitmap.getHeight() / 1024;}};// 創建ImageCache
imageCache = new ImageLoader.ImageCache() {@Overridepublic void putBitmap(String url, Bitmap bitmap) {mImageLruCache.put(url, bitmap);}@Overridepublic Bitmap getBitmap(String url) {return mImageLruCache.get(url);}
};
使用LruCache來實現ImageCache接口,實現圖片的內存緩存:
public interface ImageCache {public Bitmap getBitmap(String url);public void putBitmap(String url, Bitmap bitmap);
}
載入圖片時的使用方法:

imageListener = ImageLoader.getImageListener(myImageView, default_pg, failed_pg);
imageLoader.get(imageUrl, imageListener);
來到ImageLoader#get:

public ImageContainer get(String requestUrl, final ImageListener listener) {return get(requestUrl, listener, 0, 0);}public ImageContainer get(String requestUrl, ImageListener imageListener,int maxWidth, int maxHeight) {return get(requestUrl, imageListener, maxWidth, maxHeight, ImageView.ScaleType.CENTER_INSIDE);}public ImageContainer get(String requestUrl, ImageListener imageListener,int maxWidth, int maxHeight, ImageView.ScaleType scaleType) {// 假設操作不是在主線程,則直接拋出異常throwIfNotOnMainThread();// 為圖片的URL創建一個特定的cacheKey,注意這個cache還和圖片的大小及scaleType相關final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType);// 這里會使用自己定義的LruCache去獲取一個Bitmap實例Bitmap cachedBitmap = mCache.getBitmap(cacheKey);// 假設緩存中已經存在。則直接返回if (cachedBitmap != null) {// Return the cached bitmap.ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null);imageListener.onResponse(container, true);return container;}// 假設緩存中不存在,則進行獲取ImageContainer imageContainer =new ImageContainer(null, requestUrl, cacheKey, imageListener);// 通知Observer這時能夠使用默認的圖片imageListener.onResponse(imageContainer, true);// 推斷是否已經有了一個同樣的請求在等待BatchedImageRequest request = mInFlightRequests.get(cacheKey);if (request != null) {// If it is, add this request to the list of listeners.request.addContainer(imageContainer);return imageContainer;}// 創建一個Request,反復之前的流程Request<Bitmap> newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, scaleType,cacheKey);mRequestQueue.add(newRequest);mInFlightRequests.put(cacheKey,new BatchedImageRequest(newRequest, imageContainer));return imageContainer;
}
處理邏輯大致和前面的addRequest同樣。首先推斷緩存中是否已經存在該url相應的bitmap。假設存在直接返回;假設不存在,先推斷是否已經有了一個同樣的請求在等待。假設是,把這個請求加入到監聽者鏈表中。假設不存在,則創建一個Request<Bitmap>,加入到RequestQueue中,從網絡中去獲取;從網絡中獲取的流程和前面分析的同樣。


先來看Request<Bitmap>:

protected Request<Bitmap> makeImageRequest(String requestUrl, int maxWidth, int maxHeight,ScaleType scaleType, final String cacheKey) {return new ImageRequest(requestUrl, new Listener<Bitmap>() {@Overridepublic void onResponse(Bitmap response) {onGetImageSuccess(cacheKey, response);}}, maxWidth, maxHeight, scaleType, Config.RGB_565, new ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {onGetImageError(cacheKey, error);}});
}
實際上返回一個ImageRequest類型。來看其請求成功的響應:即把獲得的圖片存儲到緩存中。

protected void onGetImageSuccess(String cacheKey, Bitmap response) {// 把獲取到的圖片存儲到緩存中mCache.putBitmap(cacheKey, response);// 能夠看到假設是多個同樣請求在等待,則能夠同一時候進行更新處理BatchedImageRequest request = mInFlightRequests.remove(cacheKey);if (request != null) {// Update the response bitmap.request.mResponseBitmap = response;// Send the batched responsebatchResponse(cacheKey, request);}
}
最后NetWork運行的結果會封裝成NetWorkResponse。通過ResponseDelivery進行轉發,這個類最后會調用Request中deliverResponse方法:

@Override
protected void deliverResponse(Bitmap response) {mListener.onResponse(response);
}
這個Listener就是最初定義的ImageListener:

public static ImageListener getImageListener(final ImageView view,final int defaultImageResId, final int errorImageResId) {return new ImageListener() {@Overridepublic void onErrorResponse(VolleyError error) {if (errorImageResId != 0) {view.setImageResource(errorImageResId);}}@Overridepublic void onResponse(ImageContainer response, boolean isImmediate) {if (response.getBitmap() != null) {view.setImageBitmap(response.getBitmap());} else if (defaultImageResId != 0) {view.setImageResource(defaultImageResId);}}};
}

能夠看到這里終于給View空間設置了圖片,以上就是Volley實現圖片載入的流程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258545.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258545.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258545.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html5 - history 歷史管理

參考文章&#xff1a; w3c : http://www.w3.org/html/ig/zh/wiki/HTML5/history 張鑫旭 : http://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/ zawa : http://zawa.iteye.com/blog/1271031  Demo : Demo 截圖&#xff…

源碼安裝libjpeg-turbo1.2.1,無root權限

首先說明我的系統是redhat linux64位。沒有root權限。我們想安裝libjpeg-turbo. 下面介紹具體的安裝步驟。 本來想安裝最新的版本&#xff0c;但是最后失敗了&#xff0c;無奈安裝成1.2.1. 1. 下載源碼&#xff1a; https://zh.osdn.net/projects/sfnet_libjpeg-turbo/download…

Android開發學習---使用Intelij idea 13.1 進行android 開發

Android開發學習---使用Intelij idea 13.1 進行android 開發 原文:Android開發學習---使用Intelij idea 13.1 進行android 開發1.為什么放棄eclipse?太卡!! 實在受不了eclipse的卡了,運行WEB項目還好,但android開發實在太慢,太慢!經常卡死,CPU經常被占滿! 看網上很多人都說比I…

python滑動條來設置閾值houghcircle_OpenCV Python,為什么Hough Circle Transform找不到所有圓圈?...

我搜索了很長時間可能出錯但我并不真正了解參數和預處理的影響我無法發布圖片,但是在一張非常清晰的歐元照片上,該程序識別出一些圈子,而不是其他一些圈子,甚至可以像其他人一樣清楚.這是我的代碼&#xff1a;‘$’import cv2import numpy as npfilename rC:\Users\roseline\D…

Logcat打印調試信息

Android Logcat調試中的V、D、I、W、E的分別代表什么&#xff1f; Log.v -- 黑色 -- verbose infoLog.d -- 藍色 -- debug infoLog.i -- 綠色 -- infoLog.w -- 橙色 -- warnLog.e -- 紅色 -- error info//Log.ASSERT -- 斷言 //Log.wtf() (1、Log.v 的調試顏色為黑色的&#xf…

opencv中的橢圓擬合

首先貼一個最簡單的程序&#xff1a;訪問&#xff1a;https://blog.csdn.net/guduruyu/article/details/70069426 //創建一個用于繪制圖像的空白圖 cv::Mat image cv::Mat::ones(480, 640, CV_8UC3); //設置藍色背景 image.setTo(cv::Scalar(100, 0, 0)); //輸入擬合…

unix c 11

多線程(thread) 操作系統支持多進程&#xff0c;進程內部使用多線程。 進程是 重量級的&#xff0c;擁有自己 獨立的內存空間。 線程是 輕量級的&#xff0c;不需要擁有自己 獨立的內存空間&#xff0c;線程的內存空間&#xff1a;1 共享進程的內存空間 2 每個線程擁有…

C# .net core 使用自定義的WebProxy

為什么80%的碼農都做不了架構師&#xff1f;>>> 因為.net core 的System.Net 中沒有提供WebProxy這個方法,所以可以根據需求實現一個. public class CoreWebProxy : IWebProxy{public readonly Uri Uri;private readonly bool bypass;public CoreWebProxy(Uri uri,…

2015年08月

2015年07月 - 2015年09月 ● 一般而言。。。 一般而言&#xff0c;牙周病輕者有口臭、牙齦紅腫疼痛、刷牙流血等癥狀&#xff0c;嚴重時會造成牙齦萎縮、牙齒敏感、牙齒搖動等情況。口腔沒有在飲食后30分鐘清潔就會逐漸轉化為酸性環境&#xff08;PH值約5.5&#xff09;&#x…

python類匯總_Python 類總結

Python可以繼承多個父類&#xff0c;多重繼承。類支持多個對象的產生&#xff0c;命名空間的繼承&#xff0c;運算符重載1)、類產生多個實例對象Python OOP模型中的兩種對象&#xff1a;類對象和實例對象。類對象提供默認的行為&#xff0c;是實例對象的工廠。實例對象是程序處…

matlab ,python,c++關于格式化輸出數字的表達

我們想要格式化輸出1,2,3&#xff0c;...為001,002,003 ... 那么在matlab,python,c該如何表達呢&#xff1f; matlab: >> filedirsprintf(%03i,10)filedir 010 or >> imagenamenum2str(10,%03d)imagename 010 python: index_str %03d % 10index_str Ou…

讀取Exchange的用戶未讀郵件數的幾種方法

【http://www.cnblogs.com/nbpowerboy/p/3539422.html】 可以使用ExchangeServiceBinding獲取郵件&#xff0c;他相當于outlook, 來獲取服務器的未接受的郵件. 至于 “該帳戶無權模擬所請求的用戶 ” ,是由于在exchange服務器上面沒有配置模擬賬戶. 需要在Exchange Management …

IOS第七天(2:UiTableView 加上數據分離)

****加上數據分離 #import "HMViewController.h" #import "HMStudent.h"interface HMViewController () <UITableViewDataSource> property (weak, nonatomic) IBOutlet UITableView *tableView;/** 數據列表 */ property (nonatomic, strong) NSArr…

觀點:Linux 上的殺毒軟件

剛剛進入二月&#xff0c;在360安全衛士 for Linux瞬間更名為360安全衛士國產系統專版。緊接著不久&#xff0c;Dr.Web 宣布發現一款可能源自 ChinaZ 的 Linux 系統的后門程序。加之又被朝內媒體炒作起來的 OpenSSL 基金會事宜&#xff0c;不由得思緒飄溢&#xff0c;再看看 Li…

使用opencv的LBF算法進行人臉關鍵點檢測

首先下載最新的opencv 和opencv_contrib, 然后按照在Windows下編譯擴展OpenCV 3.1.0 opencv_contrib的方法進行編譯&#xff0c;其中核心一點就是先編譯opencv&#xff0c;再在OPENCV_EXTRA_MODULES_PATH中加入opencv_contrib的modules的路徑。 編譯好了后就可以進行人臉關鍵…

scala case class 繼承_數字硬件系統設計之一:Scala快速入門(2)

原想簡單籠統介紹一下scala&#xff0c;后感覺這么做意思不大&#xff0c;網友看了和沒看一樣&#xff0c;還是應該稍微詳細具體一點&#xff0c;故而把系列編號由(上)(中)(下)&#xff0c;改為(上)(2)(3)(4)(5)....,(上)就是(1)吧&#xff0c;以下內容部分節選于我們即將出版的…

Ubuntu下安裝FTP服務及使用(VSFTPD詳細設置)(二)

vsftpd 作為一個主打安全的FTP服務器&#xff0c;有很多的選項設置。下面介紹了vsftpd的配置文件列表&#xff0c;而所有的配置都是基于vsftpd.conf這個配置文件 的。本文將提供完整的vsftpd.conf的中文說明。學習本文的內容將有助于你初步了解vsftpd的配置文件&#xff0c;但針…

crontab命令

前一天學習了 at 命令是針對僅運行一次的任務&#xff0c;循環運行的例行性計劃任務&#xff0c;linux系統則是由 cron (crond) 這個系統服務來控制的。Linux 系統上面原本就有非常多的計劃性工作&#xff0c;因此這個系統服務是默認啟動的。另外, 由于使用者自己也可以設置計劃…

調查顯示企業對 Linux 開發人才需求日漸增長

根據2014年Linux就業報告調查顯示&#xff0c;隨著Linux平臺增長&#xff0c;Linux平臺開發者就業需求較去年提升了7%&#xff0c;技術公司招聘Linux開發經歷的人才需求達到 77%&#xff0c;這是來自Dice和Linux基金會共同對就業市場對Linux人才的全景式調查&#xff0c;調查訪…

求圓和橢圓上任意角度的點的坐標

圓上任意角度的點的坐標 如上圖&#xff0c;給定圓心&#xff08;Cx,Cy&#xff09;,半徑為R&#xff0c; 求θ\thetaθ對應的點的坐標&#xff1f; 此處θ\thetaθ是相對于水平軸的角度。 顯然我們可以使用極坐標轉換來求&#xff1a; {pxCxRcos(θ)pyCyRsin(θ)\left\{\begi…