私は長時間実行されるアプリケーションを開発しています。私のアプリケーションはDefaultHttpClient
(私も試してみましたAndroidHttpClient
) を定期的に使用しています。わかりませんが、しばらく作業した後、どういうわけかhttpClient.execute
眠ります。文字通りスリープ状態になり、ウェイクアップ (ロック解除または PC への接続) すると、デバイスhttpClient
はすぐに動作し続けます (タイムアウトを設定した場合は例外をスローするか、実行の応答を返すだけです)。同様のケースと非作業を検索して試しました。wake と wifilocks については、実行前に wifi lock と wake lock を取得し、応答が得られたら解放するだけです。何も機能しません。私にはわかりません。
私が使用しているデバイスは、Galaxy S3(v4.0+) と Ace(v2.3.6) です。
前もって感謝します。
これはスタックする MyTask であり、行でスタックし、response = new MyClient(ctx).client.execute(post);
httpsMyClient
と証明書を処理するためのラッパーです。
public abstract class GenericTask extends AsyncTask<Object, Object, Document> {
public final static String TAG = "GenericTask";
private WakeLock wakeLock;
private WifiLock wifiLock;
protected HttpPost post;
public String taskId;
public Context ctx;
Object parameter;
public GenericTask(Context ctx, Object parameter) {
this.parameter = parameter;
this.ctx = ctx;
post = null;
initLock(ctx);
lock();
}
private void lock() {
try {
wakeLock.acquire();
wifiLock.acquire();
Log.d(TAG,"LockAcquired");
} catch (Exception e) {
Log.e("WlanSilencer", "Error getting Lock: " + e.getMessage());
}
}
private void unlock() {
Log.e(TAG,"unlock");
if (wakeLock.isHeld())
wakeLock.release();
if (wifiLock.isHeld())
wifiLock.release();
Log.d(TAG,"LockReleased");
}
private void initLock(Context context) {
wifiLock = ((WifiManager) context
.getSystemService(Context.WIFI_SERVICE)).createWifiLock(
WifiManager.WIFI_MODE_FULL_HIGH_PERF, "GenericTaskWifiLock");
wakeLock = ((PowerManager) context
.getSystemService(Context.POWER_SERVICE)).newWakeLock(
PowerManager.FULL_WAKE_LOCK, "GenericTaskWakeLock");
Log.d(TAG,"LockInitiated");
}
public boolean cancelTask(boolean bln) {
if(post!=null)
post.abort();
return super.cancel(bln);
}
public void execute(){
if(Build.VERSION.SDK_INT >= 11){
startNew();
}else{
startOld();
}
}
private void startOld() {
super.execute();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void startNew(){
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR );
}
@Override
protected void onPostExecute(Document doc) {
unlock();
if(doc==null){
Log.e("GenericTask: " +getClass(),"onPostExecute doc=null");
}
Log.e(TAG,"onPostExecute");
TaskManager.getInstance().returnFromTaskSuccess(doc, getClass(), taskId, parameter);
}
@Override
protected Document doInBackground(Object... params) {
Log.e(TAG,"doInBackground");
try {
return call();
} catch (InvalidKeyException e) {
OtherUtils.printStackTrace(e);
} catch (NoSuchPaddingException e) {
OtherUtils.printStackTrace(e);
} catch (InvalidAlgorithmParameterException e) {
OtherUtils.printStackTrace(e);
} catch (IllegalStateException e) {
OtherUtils.printStackTrace(e);
} catch (NoSuchAlgorithmException e) {
OtherUtils.printStackTrace(e);
} catch (IOException e) {
OtherUtils.printStackTrace(e);
} catch (TransformerException e) {
OtherUtils.printStackTrace(e);
} catch (ParserConfigurationException e) {
OtherUtils.printStackTrace(e);
}
return null;
}
protected abstract String getUrl();
protected abstract Document getRequest();
public int initialSleep() {
return 0;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
protected Document call() throws IOException, TransformerException, ParserConfigurationException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalStateException, NoSuchAlgorithmException{
Document doc = getRequest();
String url = getUrl();
Document responseXml = null;
try {
post = HttpUtils.postXml(doc, url, null);
HttpResponse response;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 16000);
HttpConnectionParams.setSoTimeout(httpParams, 20000);
post.setParams(httpParams);
response = new MyClient(ctx).client.execute(post);
HttpEntity resEntity = response.getEntity();
responseXml = XmlUtils.entityToXml(resEntity, null);
resEntity.consumeContent();
return responseXml;
} catch (TransformerException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
}
Httpユーティリティ:
public class HttpUtils {
public static HttpPost postXml(Document doc, String url, WrapperAsByteArrayOutputStream baos) throws IOException, TransformerConfigurationException, TransformerException
{
StringWriter xmlAsWriter = new StringWriter();
StreamResult result = new StreamResult(xmlAsWriter);
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), result);
HttpPost post = new HttpPost(url);
InputStreamEntity req;
if ( baos == null ) {
req = new InputStreamEntity(new ByteArrayInputStream(xmlAsWriter.toString().getBytes()), -1);
}
else {
req = new InputStreamEntity(new WrappedInputStream(new ByteArrayInputStream(xmlAsWriter.toString().getBytes()), baos), -1);
}
req.setChunked(true);
post.setEntity(req);
return post;
}
私の顧客:
public class MyClient extends DefaultHttpClient { public HttpClient クライアント;
public MyClient(Context ccc) {
super();
KeyStore localTrustStore = null;
try {
localTrustStore = KeyStore.getInstance("BKS");
} catch (KeyStoreException e) {
e.printStackTrace();
}
InputStream in = ccc.getResources().openRawResource(
R.raw.localcert);
try {
localTrustStore.load(in, "local_trust_password".toCharArray());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
SSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = new SSLSocketFactory(localTrustStore);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
HttpParams params = new BasicHttpParams();
ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
schemeRegistry);
this.client = new DefaultHttpClient(cm, params);
}
AlarmReciever の onrecieve
public void onReceive(Context context, Intent intent) {
try {
TaskManager.getInstance().sendBatteryStatus();
}
} catch (Exception e) {
Toast.makeText(
context,
"There was an error somewhere, but we still received an alarm",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
returnfromtask の成功は、単純にスレッド セーフの id をチェックし、doc を処理し、以下のように新しいアラームを設定します。
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
Intent intent = new Intent(ctx, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(ctx, 2131225, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
sendBatteryStatus は、送信する情報を収集し、それを GenericTask を拡張するタスクに渡し、正常に実行されますnew MyAsyncTask(..bla bla).execute();