android超時處理
『壹』 如何修改Android超時休眠時間
方法一、調整代碼:
Settings.System.putInt(getContentResolver(),android.provider.Settings.System.SCREEN_OFF_TIMEOUT,-1);
許可權:<uses-permission android:name="android.permission.WRITE_SETTINGS" />
方法二、調整資料庫:
android的這些設置都是存放在sql資料庫里的,也就是說可以直接通過修改資料庫來不讓android睡眠。
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
具體sql:
UPDATE system SET value = '-1' WHERE name = 'screen_off_timeout' ;
『貳』 android token 超時,非同步回調怎麼實現會比較優雅
PhoneGap的js回調有幾種實現方式。其中一種是ajax。
我們先來看一下js端相關代碼:
// file: lib/android/plugin/android/callback.js
define("cordova/plugin/android/callback", function(require, exports, mole) {
var port = null,
token = null,
xmlhttp;
function startXhr() {
// cordova/exec depends on this mole, so we can't require cordova/exec on the mole level.
var exec = require('cordova/exec'),
xmlhttp = new XMLHttpRequest();
// Callback function when XMLHttpRequest is ready
xmlhttp.onreadystatechange=function(){
if (!xmlhttp) {
return;
}
if (xmlhttp.readyState === 4){
// If callback has javaScript statement to execute
if (xmlhttp.status === 200) {
// Need to url decode the response
var msg = decodeURIComponent(xmlhttp.responseText);
setTimeout(startXhr, 1);
exec.processMessages(msg);
}
// If callback ping (used to keep XHR request from timing out)
else if (xmlhttp.status === 404) {
setTimeout(startXhr, 10);
}
// 0 == Page is unloading.
// 400 == Bad request.
// 403 == invalid token.
// 503 == server stopped.
else {
console.log("JSCallback Error: Request failed with status " + xmlhttp.status);
exec.setNativeToJsBridgeMode(exec.nativeToJsModes.POLLING);
}
}
};
if (port === null) {
port = prompt("getPort", "gap_callbackServer:");
}
if (token === null) {
token = prompt("getToken", "gap_callbackServer:");
}
xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true);
xmlhttp.send();
}
mole.exports = {
start: function() {
startXhr();
},
stop: function() {
if (xmlhttp) {
var tmp = xmlhttp;
xmlhttp = null;
tmp.abort();
}
},
isAvailable: function() {
return ("true" != prompt("usePolling", "gap_callbackServer:"));
}
};
});
主要的處理是startXhr函數。它向java的server端發起了ajax請求,在onreadystatechange這個回調函數中等待server端返回結果。如果server端返回的結果正確,則再通過setTimeout(startXhr, 1)函數,1豪秒後再重新向server端發起ajax請求。如果從server返回的結果狀態是404,則每隔10豪秒,重新向server端發起ajax請求。
接下來看看server端是如何處理的。server端的處理代碼是CallbackServer.java中的run()方法中。
先看server端的源碼:
它通過serverSocket來模擬http的server端。其中,jsMessageQueue中是從java端發送的js消息,serverSocket在接收到客戶端(js端)的請求後,會將jsMessageQueue中的js代碼發送到客戶端(js端)。
/**
* Start running the server.
* This is called automatically when the server thread is started.
*/
public void run() {
// Start server
try {
this.active = true;
String request;
waitSocket = new ServerSocket(0);
this.port = waitSocket.getLocalPort();
//Log.d(LOG_TAG, "CallbackServer -- using port " +this.port);
this.token = java.util.UUID.randomUUID().toString();
//Log.d(LOG_TAG, "CallbackServer -- using token "+this.token);
while (this.active) {
//Log.d(LOG_TAG, "CallbackServer: Waiting for data on socket");
Socket connection = waitSocket.accept();
BufferedReader xhrReader = new BufferedReader(new InputStreamReader(connection.getInputStream()), 40);
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
request = xhrReader.readLine();
String response = "";
//Log.d(LOG_TAG, "CallbackServerRequest="+request);
if (this.active && (request != null)) {
if (request.contains("GET")) {
// Get requested file
String[] requestParts = request.split(" ");
// Must have security token
if ((requestParts.length == 3) && (requestParts[1].substring(1).equals(this.token))) {
//Log.d(LOG_TAG, "CallbackServer -- Processing GET request");
String payload = null;
// Wait until there is some data to send, or send empty data every 10 sec
// to prevent XHR timeout on the client
while (this.active) {
if (jsMessageQueue != null) {
payload = jsMessageQueue.popAndEncode();
if (payload != null) {
break;
}
}
synchronized (this) {
try {
this.wait(10000); // prevent timeout from happening
//Log.d(LOG_TAG, "CallbackServer>>> break <<<");
break;
} catch (Exception e) {
}
}
}
// If server is still running
if (this.active) {
// If no data, then send 404 back to client before it times out
if (payload == null) {
//Log.d(LOG_TAG, "CallbackServer -- sending data 0");
response = "HTTP/1.1 404 NO DATA\r\n\r\n "; // need to send content otherwise some Android devices fail, so send space
}
else {
//Log.d(LOG_TAG, "CallbackServer -- sending item");
response = "HTTP/1.1 200 OK\r\n\r\n";
response += encode(payload, "UTF-8");
}
}
else {
response = "HTTP/1.1 503 Service Unavailable\r\n\r\n ";
}
}
else {
response = "HTTP/1.1 403 Forbidden\r\n\r\n ";
}
}
else {
response = "HTTP/1.1 400 Bad Request\r\n\r\n ";
}
//Log.d(LOG_TAG, "CallbackServer: response="+response);
//Log.d(LOG_TAG, "CallbackServer: closing output");
output.writeBytes(response);
output.flush();
}
output.close();
xhrReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
this.active = false;
//Log.d(LOG_TAG, "CallbackServer.startServer() - EXIT");
}
『叄』 android okhttp超時怎麼辦
OkHttp是一個在開發可汗學院AndroidAPP過程中非常重要的依賴庫。它的默認的配置為我們提供了非常重要實用功能,下面一些步驟我們可以讓Okhttp提供功能使用靈活和內省能力。1.啟用文件系統上的響應緩存默認情況下,Okhttp不支持響應緩存,包括HTTPCache-Control頭允許緩存響應。因此,客戶端通過一次又一次的請求相同的資源浪費時間和帶寬。而不是簡單地讀取初始響應後緩存的副本。要在文件系統中啟用響應緩存,需要配置com.squareup.okhttp.Cache實例,並把它傳遞給你的OkHttpClient實例的setCache方法。你必須初始化緩存與存放目錄的文件,並以位元組為單位的最大值。響應返回數據可以寫入給定目錄文件,如果一個響應的緩存超過了給定的大小。我們可以採取LRUpolicy。我們可以在stackoverflow查看JesseWilson的回復。我們可以通過context.getCacheDir()在子目錄中緩存我們的響應://Basedirectoryrecommendedby/q/4441849/400717.final@NullableFilebaseDir=context.getCacheDir();if(baseDir!=null){finalFilecacheDir=newFile(baseDir,"HttpResponseCache");okHttpClient.setCache(newCache(cacheDir,HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));}//Basedirectoryrecommendedby/q/4441849/400717.final@NullableFilebaseDir=context.getCacheDir();if(baseDir!=null){finalFilecacheDir=newFile(baseDir,"HttpResponseCache");okHttpClient.setCache(newCache(cacheDir,HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));}在可汗學院的程序中我們指定HTTP_RESPONSE_DISK_CACHE_MAX_SIZEas10*1024*1024,or10MB的大小2.集成StethoStetho是Facebook的一個可愛的庫,可以使用Chrome瀏覽器的Chrome開發人員工具功能來檢查你的Android應用程序。Stetho除了允許你檢查你的應用程序的SQLite資料庫,還可以查看View的層次結構。允許你檢查由OkHttp發起的每個請求和響應:這種自省機制是確保伺服器返回允許資源緩存的HTTP頭是非常有用的,以及驗證沒有請求時,保證緩存的資源存在。要想使用Stetho,只需添加一個StethoInterceptor實例的網路攔截器列表:okHttpClient.networkInterceptors().add(newStethoInterceptor());okHttpClient.networkInterceptors().add(newStethoInterceptor());然後,運行應用程序,打開瀏覽器後,輸入chrome://inspect。然後你就會看到應用程序的設備和標識符的列表。然後滑鼠右鍵選擇inspect打開開發者工具,然後打開新的tab,開始監控OkHttp請求。3.使用Picasso和Retrofit你可能使用過Picasso來載入網路圖片,或者使用Retrofit來簡化發出請求和解碼響應。這些第三方庫將隱式地創建自己的OkHttpClient供內部使用,如果你不明確指定一個。Picassoversion2.5.2的OkHttpDownloader類:(){OkHttpClientclient=newOkHttpClient();client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);returnclient;}(){OkHttpClientclient=newOkHttpClient();client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);returnclient;}Retrofit也有類似的工廠方法來創建自己的OkHttpClient。圖片一般在應用程序中需要載入的比較大的資源。盡管Picasso自己維護它的LRU機制來緩存圖片,在內存中嚴格執行。如果客戶端嘗試使用Picasso來載入圖片。Picasso會找不到其在內存中緩存圖像,然後將委託載入該圖片到它的內部OkHttpClient實例。並且默認情況下該實例將始終從伺服器載入圖片資源。作為defaultOkHttpClient的方法不能與上面提到的文件系統中的響應緩存配置結合起來。指定你自己的OkHttpClient實例允許返回數據從文件系統緩存響應,圖片不會從伺服器載入。這是非常重要的在程序第一次啟動以後。這個時候Picasso的內存緩存是冷的。所以它會頻繁的委託OkHttpClient實例去載入圖片。這就需要構建配置了您Picasso的OkHttpClient實例,如果你在你的代碼中使用Picasso.with(context).load()Picasso.with(context).load()載入圖片,你是用的是Picasso的單例模式。這是通過with方法懶漢模式地實例化並配置自己的OkHttpClient。因此,我們必須使我們自己的Picasso實例在單例之前通過wiht方法調用。實現這個,可以簡單的將OkHttpClient實例封裝在OkHttpDownloader中,然後傳遞給Picasso.Builder實例的downloader方法。finalPicassopicasso=newPicasso.Builder(context).downloader(newOkHttpDownloader(okHttpClient)).build();//,butreplacethesingleton//instancejustincase.Picasso.setSingletonInstance(picasso);finalPicassopicasso=newPicasso.Builder(context).downloader(newOkHttpDownloader(okHttpClient)).build();//,butreplacethesingleton//instancejustincase.Picasso.setSingletonInstance(picasso);在Retrofit中要使用OkHttpClient實例,需要改造1.9.x的一個RestAdapter,需要將OkHttpClient封裝OkClient的實例中。然後把它傳遞給RestAdapter.Builder實例的setClient方法。restAdapterBuilder.setClient(newOkClient(httpClient));restAdapterBuilder.setClient(newOkClient(httpClient));在Retrofit2.0中只需要簡單的將OkHttpClient傳遞給Retrofit.Builder實例的client方法。在可汗學院的APP中我們通過Dagger依賴注入來確保我們只有一個OkHttpClient的實例。這種方法同樣也適用於Picasso和Retrofit我們提供了一個為OkHttpClient實例提供單例模式的註解示例:@Provides@(finalContextcontext,){finalOkHttpClientokHttpClient=newOkHttpClient();configureClient(okHttpClient,);returnokHttpClient;}@Provides@(finalContextcontext,){finalOkHttpClientokHttpClient=newOkHttpClient();configureClient(okHttpClient,);returnokHttpClient;}OkHttpClient將會通過Dagger的註解創建一個實例提供給我們的Picasso和Retrofit。4.指定一個用戶代理攔截器日誌文件和分析為我們提供了有用的信息,當客戶在每個請求提供詳細的User-Agentheader值的時候。默認情況下,Okhttp包含User-Agent值只有在特定的Okhttp版本中。為了指定我們自己的useragent。首先創建攔截器的替換值,我們可以看stackoverflow的建議。{privatestaticfinalStringUSER_AGENT_HEADER_NAME="User-Agent";;publicUserAgentInterceptor(StringuserAgentHeaderValue){this.userAgentHeaderValue=Preconditions.checkNotNull(userAgentHeaderValue);}@(Chainchain)throwsIOException{finalRequestoriginalRequest=chain.request();=originalRequest.newBuilder().removeHeader(USER_AGENT_HEADER_NAME).addHeader(USER_AGENT_HEADER_NAME,userAgentHeaderValue).build();returnchain.proceed(requestWithUserAgent);}}{privatestaticfinalStringUSER_AGENT_HEADER_NAME="User-Agent";;publicUserAgentInterceptor(StringuserAgentHeaderValue){this.userAgentHeaderValue=Preconditions.checkNotNull(userAgentHeaderValue);}@(Chainchain)throwsIOException{finalRequestoriginalRequest=chain.request();=originalRequest.newBuilder().removeHeader(USER_AGENT_HEADER_NAME).addHeader(USER_AGENT_HEADER_NAME,userAgentHeaderValue).build();returnchain.proceed(requestWithUserAgent);}}為了創建User-Agentheader值人然後傳遞給UserAgentInterceptor的構造器,使用你得到的任何信息。我們可以使用:android的系統信息可以清晰的傳遞出這是一台android設備Build.MODEL或者「製造商提供的用戶可見最終可見的名稱」Build.BRAND或者「消費者可見的品牌與產品/硬體相關信息」Build.VERSION.SDK_INT或者「消費者可見的Android提供的SDK版本號」BuildConfig.APPLICATION_IDBuildConfig.VERSION_NAMEBuildConfig.VERSION_CODE最後三個值由的applicationID,VERSIONCODE和VERSIONNAME的值在我們的Gradlebuild腳本中了解信息可以查看versioningyourapplications和請注意,如果您的應用程序使用的是WebView,您可以配置使用相同的User-Agentheader值,你可以通過下面方法創建UserAgentInterceptor:WebSettingssettings=webView.getSettings();settings.setUserAgentString(userAgentHeaderValue);WebSettingssettings=webView.getSettings();settings.setUserAgentString(userAgentHeaderValue);5.指定合理的超時2.5.0版本之前,OkHttp請求默認為永不超時。2.5.0版本開始如果建立連接請求超時,如果從連接讀取下一個位元組或寫入的下一個位元組到連接,花費超過10秒,就終止。這樣做需要更新到2.5.0版本我們就不需要在我們的代碼中修改bug。原因很簡單是我因為我們第一次使用的時候使用了錯誤的路徑。要覆蓋這些默認值,可以分別調用setConnectTimeout,setReadTimeout或setWriteTimeout。需要注意的是Picasso和Retrofit為OkHttpClient實例指定不同的超時值時,默認情況下,Picasso指定:連接超過15秒.讀取超過20秒寫入超過20秒而Retrofit指定:連接超過15秒.讀取超過20秒沒有寫入超時通過配置Picasso和Retrofit自己的OkHttpClient實例你可以確保所有的請求超時是一致的
『肆』 android中如何獲取超時時長的異常
android獲取超時時長的異常方式如下:設置超時機制
client.getParams().setIntParameter(
HttpConnectionParams.SO_TIMEOUT, TIME_OUT_DELAY); // 超時設置
client.getParams().setIntParameter(
HttpConnectionParams.CONNECTION_TIMEOUT, TIME_OUT_DELAY);// 連接超時
這里設置了兩種超時,第一種是請求超時,第二種時連接超時。
當向伺服器發出請求後,請求和伺服器建立socket連接,但是很長時間內都沒有建立socket連接,這就時第一種請求超時,這種情況主要發生在請求了
一個不存在的伺服器。超時之後,會拋出InterruptedIOException異常。
Timeout for blocking operations. The argument value is specified in
milliseconds. An InterruptedIOException is thrown if this timeout
expires.
『伍』 android如何設置連接超時啊
您好,我是這樣設置的,代碼如下:
public static InputStream getHttpByApache(String urlStr) throws Exception {
HttpGet httpGet = new HttpGet(urlStr);
HttpClient httpClient = new DefaultHttpClient();
// 設置連接超時、讀取超時
HttpParams basicHttpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(basicHttpParams, 3 * 1000);
HttpConnectionParams.setSoTimeout(basicHttpParams, 3 * 1000);
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
return httpResponse.getEntity().getContent();
}
return null;
}
『陸』 如何處理Android-Async-Http連接超時的問題
一般網路超時後,可以嘗試重新連接,或者給出錯誤提示。
Android-Async-Http第三方的網路請求框架,內部已經默認實現了,二次請求網路,就是在網路錯誤後再請求一次伺服器。所以可以直接給出錯誤提示,讓用戶檢查網路。