マップセクションが変更されるたびにサーバーでリクエストを実行する目的で、AsyncTask を拡張するプライベートクラスを持つ MyMapActivity があります (onMove() メソッド)。サーバーからの応答は、約 1 ~ 3 MB の JSON データ文字列です。そのため、OutOfMemory を回避するためにユーザーがマップを移動しているときに、サーバーへの複数の呼び出しを避ける必要があります。そのため、自分の AsyncTask が (onMove() の開始ごとに) キャンセルされているかどうかを確認しようとしています。しかし、これに関係なく、私はまだ持っています
01-19 20:45:05.660: エラー/MapActivity(2482): 接続ファクトリ クライアントを取得できませんでした 01-19 20:45:40.600: エラー/テザリング (96): アクティブな iface (usb0) が追加されたと報告され、無視されます 01-19 20:47:15.260: エラー/dalvikvm-heap(2482): 11908 バイトの割り当てでメモリが不足しています。 01-19 20:47:15.270: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 23091KB、ビットマップ サイズ = 101KB 01-19 20:47:15.410: エラー/dalvikvm-heap(2482): 7690 バイトの割り当てでメモリが不足しています。 01-19 20:47:15.420: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 23088KB、ビットマップ サイズ = 101KB 01-19 20:47:15.570: エラー/dalvikvm-heap(2482): 7656 バイトの割り当てでメモリが不足しています。 01-19 20:47:15.590: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 23090KB、ビットマップ サイズ = 101KB 01-19 20:47:15.730: エラー/dalvikvm-heap(2482): 9098 バイトの割り当てでメモリが不足しています。 01-19 20:47:15.740: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 23097KB、ビットマップ サイズ = 101KB 01-19 20:48:01.850: エラー/dalvikvm-heap(2482): 8176 バイトの割り当てでメモリが不足しています。 01-19 20:48:01.850: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 22767KB、ビットマップ サイズ = 101KB 01-19 20:48:01.970: エラー/dalvikvm-heap(2482): 12022 バイトの割り当てでメモリが不足しています。 01-19 20:48:01.980: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 22768KB、ビットマップ サイズ = 101KB 01-19 20:48:02.110: エラー/dalvikvm-heap(2482): 8936 バイトの割り当てでメモリが不足しています。 01-19 20:48:02.119: エラー/dalvikvm(2482): メモリ不足: ヒープ サイズ = 24519KB、割り当て済み = 22769KB、ビットマップ サイズ = 101KB 01-19 20:48:07.220: WARN/dalvikvm(2482): threadid=20: キャッチされない例外で終了するスレッド (グループ = 0x400259f8) 01-19 20:48:07.350: エラー/AndroidRuntime(2482): 致命的な例外: AsyncTask #9 01-19 20:48:07.350: エラー/AndroidRuntime(2482): java.lang.RuntimeException: doInBackground() の実行中にエラーが発生しました 01-19 20:48:07.350: エラー/AndroidRuntime(2482): android.os.AsyncTask$3.done(AsyncTask.java:200) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.FutureTask$Sync.innerSetException (FutureTask.java:273) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.FutureTask.setException (FutureTask.java:124) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:307) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.FutureTask.run で (FutureTask.java:137) 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1068) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): java.lang.Thread.run(Thread.java:1102) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): 原因: java.lang.OutOfMemoryError 01-19 20:48:07.350: エラー/AndroidRuntime(2482): java.lang.String.(String.java:468) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.lang.AbstractStringBuilder.toString (AbstractStringBuilder.java:659) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.lang.StringBuilder.toString (StringBuilder.java:664) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.stream.JsonReader.nextString (JsonReader.java:995) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.stream.JsonReader.nextValue (JsonReader.java:810) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.stream.JsonReader.objectValue (JsonReader.java:790) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.stream.JsonReader.quickPeek (JsonReader.java:385) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.stream.JsonReader.peek (JsonReader.java:348) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:322) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): com.google.gson.internal.bind.TypeAdapters$12.read(TypeAdapters.java:334) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read (ReflectiveTypeAdapterFactory.java:170) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read (TypeAdapterRuntimeTypeWrapper.java:38) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:71) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:86) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read (ReflectiveTypeAdapterFactory.java:170) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.Gson.fromJson (Gson.java:720) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): com.google.gson.Gson.fromJson (Gson.java:660) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): net.amagumo.realestate.MyMapActivity$MyTask.getHttpContent(MyMapActivity.java:444) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:393) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): net.amagumo.realestate.MyMapActivity$MyTask.doInBackground(MyMapActivity.java:1) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): android.os.AsyncTask$2.call(AsyncTask.java:185) で 01-19 20:48:07.350: エラー/AndroidRuntime (2482): java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:305) で 01-19 20:48:07.350: エラー/AndroidRuntime(2482): ... 4 つ以上 01-19 20:48:07.450: WARN/ActivityManager(96): 強制終了アクティビティ net.amagumo.realestate/.MyMapActivity 01-19 20:48:21.290: WARN/TimeThread(294): 時間の変換に失敗しました 01-19 20:48:42.899: WARN/TimeThread(294): 時間の変換に失敗しました
これが私の活動クラスです:
public class MyMapActivity extends MapActivity implements LocationListener, OnTouchListener, OnMoveListener, MyMapItemClickedListener, DefaultActivity {
MyMapView mv;
MapController mc;
LocationManager lm;
MyItemizedOverlay myOverlay;
DatabaseAdapter db;
AdvertResult advertResult;
String callerActivityString;
MyTask mytask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(Constants.DEBUG_TAG, "MAP - create");
setContentView(R.layout.map);
db = new DatabaseAdapter(getApplicationContext()).open();
mv = (MyMapView)this.findViewById(R.id.mapView);
mc = mv.getController();
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mv.setOnTouchListener(this);
mv.setmOnMoveListener(this);
mv.setSatellite(true);
Drawable marker=getResources().getDrawable(R.drawable.ic_maps_indicator_startpoint_list);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
myOverlay = new MyItemizedOverlay(marker);
myOverlay.setMyMapItemClickedListener(this);
mv.getOverlays().add(myOverlay);
advertResult = new AdvertResult();
mytask = new MyTask();
}
public void completeMap(){
Log.d(Constants.DEBUG_TAG_MAPS, "completing map - START");
for(AdvertSimple is : advertResult.getAdvertSimpleList()){
if(is.getAdress().getLat()!=null && is.getAdress().getLon()!=null){
GeoPoint gp = new GeoPoint(is.getAdress().getLat(), is.getAdress().getLon());
myOverlay.addItem(gp, "Advert", "snippet");
}
}
Log.d(Constants.DEBUG_TAG_MAPS, "completing map - END");
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
public void onLocationChanged(Location loc) {
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public boolean onTouch(View v, MotionEvent event) {
return false;
}
public void onMove(MapView mapView, GeoPoint center, boolean stopped) {
if(!mytask.isCancelled()){
Log.d(Constants.DEBUG_TAG_MAPS, "async task is cancelling - ATTEMPT");
mytask.cancel(true);
System.gc();
}
if(stopped){
Log.d(Constants.DEBUG_TAG_MAPS, "finished move/zoom action");
Integer latspan = mv.getLatitudeSpan();
Integer lonspan = mv.getLongitudeSpan();
Integer maxlat = center.getLatitudeE6() + (latspan/2);
Integer maxlon = center.getLongitudeE6() + (lonspan/2);
Integer minlat = center.getLatitudeE6() - (latspan/2);
Integer minlon = center.getLongitudeE6() - (lonspan/2);
mytask = new MyTask();
mytask.execute(this, null, new ResultComposite());
}
}
public MapRectangle getRectangle(){
GeoPoint center = mv.getMapCenter();
Integer latspan = mv.getLatitudeSpan();
Integer lonspan = mv.getLongitudeSpan();
Integer maxlat = center.getLatitudeE6() + (latspan/2);
Integer maxlon = center.getLongitudeE6() + (lonspan/2);
Integer minlat = center.getLatitudeE6() - (latspan/2);
Integer minlon = center.getLongitudeE6() - (lonspan/2);
return new MapRectangle(maxlat, maxlon, minlat, minlon);
}
@Override
public void completeAction(ResultComposite result) {
Log.d(Constants.DEBUG_TAG_MAPS, "async tasc is going to complete in caller activity - OK");
if(result!=null){
advertResult.setAdvertSimpleList(result.getAdvertSimpleList());
completeMap();
}
}
@Override
public RequestParams getRequestParams() {
RequestParams params = new RequestParams();
params.setDb(db);
params.setRectangle(getRectangle());
return params;
}
private class MyTask extends AsyncTask{
public MyMapActivity ma;
public HttpClient httpclient;
@Override
protected ResultComposite doInBackground(Object... params) {
Log.d(Constants.DEBUG_TAG_MAPS, "async tasc do in backgrounf - START");
ma = (MyMapActivity) params[0];
ResultComposite rc = new ResultComposite();
RequestParams rp = ma.getRequestParams();
MapRectangle rectangle = rp.getRectangle();
RequestJSONObject ro = new RequestJSONObject(rectangle.getMinlat(), rectangle.getMinlon(), rectangle.getMaxlat(), rectangle.getMaxlon());
Gson gson = new Gson();
String json = gson.toJson(ro);
ResponseJSONObject responseJSONObject = getHttpContent(json, Constants.HTTP_REQUEST_MAP);
AdvertSimpleJSON[] AdvertSimpleJSONarray = responseJSONObject.getAdvertySimple();
List simples = DataHelper.convertAdvertSimpleJSONArray2AdvertSimpleList(rp.getDb(), AdvertSimpleJSONarray);
rc.setAdvertSimpleList(simples);
return rc;
}
@Override
protected void onPostExecute(ResultComposite result) {
super.onPostExecute(result);
Log.d(Constants.DEBUG_TAG_MAPS, "async tasc is going to complete in caller activity - ATTEMPT");
ma.completeAction(result);
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.d(Constants.DEBUG_TAG_MAPS, "async task is cancelling - OK");
}
private ResponseJSONObject getHttpContent(String json, String requestType){
ResponseJSONObject responseJSONObject = null;
HttpPost post = new HttpPost(Constants.SERVER_MAP_URL);
try {
Log.d(Constants.DEBUG_TAG_MAPS, "try");
HttpEntity entity = new StringEntity(json);
post.setEntity(entity);
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 15000);
HttpConnectionParams.setSoTimeout(httpParameters, 150000);
httpclient = new DefaultHttpClient(httpParameters);
BasicHttpResponse response = (BasicHttpResponse ) httpclient.execute(post);
if(response.getStatusLine().getStatusCode() == 200){
Log.d(Constants.DEBUG_TAG, "response 200");
HttpEntity responseEntity = response.getEntity();
Gson g = new Gson();
BufferedReader reader = new BufferedReader ( new InputStreamReader ( responseEntity.getContent()) );
responseJSONObject = g.fromJson(reader, ResponseJSONObject.class);
reader.close();
System.gc();
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d(Constants.DEBUG_TAG_MAPS, "returning http results");
return responseJSONObject;
}
}
}
他に何をすべきですか?httpエンティティの消費を実行しようとしました。
AsynTask を処理するロジックは正しいですか?