我有一个应用程序,它使用Web服务从SQL Server获取数据并将其导出到平板电脑中的SQLite数据库。问题是,该表有大约25,000条记录。当我将其限制为100条记录时,代码工作得很好。但是在导出所有数据时出现以下错误:
02-13 13:36:31.734: E/AndroidRuntime(12821): FATAL EXCEPTION: AsyncTask #1
02-13 13:36:31.734: E/AndroidRuntime(12821): java.lang.RuntimeException: An error occured while executing doInBackground()
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.Thread.run(Thread.java:856)
02-13 13:36:31.734: E/AndroidRuntime(12821): Caused by: java.lang.OutOfMemoryError
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.ThreadLocal$Values.initializeTable(ThreadLocal.java:244)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.ThreadLocal$Values.rehash(ThreadLocal.java:325)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.ThreadLocal$Values.cleanUp(ThreadLocal.java:254)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.ThreadLocal$Values.getAfterMiss(ThreadLocal.java:438)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.lang.ThreadLocal.get(ThreadLocal.java:65)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:359)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:992)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:799)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java:862)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:242)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
02-13 13:36:31.734: E/AndroidRuntime(12821): at com.example.shvalidation.DatabaseHandler.InsertBook(DatabaseHandler.java:75)
02-13 13:36:31.734: E/AndroidRuntime(12821): at com.example.shvalidation.MainMenuScreen$TestThread.doInBackground(MainMenuScreen.java:79)
02-13 13:36:31.734: E/AndroidRuntime(12821): at com.example.shvalidation.MainMenuScreen$TestThread.doInBackground(MainMenuScreen.java:1)
02-13 13:36:31.734: E/AndroidRuntime(12821): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-13 13:36:31.734: E/AndroidRuntime(12821): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-13 13:36:31.734: E/AndroidRuntime(12821): ... 4 more
02-13 13:36:32.804: E/WindowManager(12821): Activity com.example.shvalidation.MainMenuScreen has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{412636d8 V.E..... R......D 0,0-772,216} that was originally added here
02-13 13:36:32.804: E/WindowManager(12821): android.view.WindowLeaked: Activity com.example.shvalidation.MainMenuScreen has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{412636d8 V.E..... R......D 0,0-772,216} that was originally added here
02-13 13:36:32.804: E/WindowManager(12821): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
02-13 13:36:32.804: E/WindowManager(12821): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
02-13 13:36:32.804: E/WindowManager(12821): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.Dialog.show(Dialog.java:281)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ProgressDialog.show(ProgressDialog.java:116)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ProgressDialog.show(ProgressDialog.java:99)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ProgressDialog.show(ProgressDialog.java:94)
02-13 13:36:32.804: E/WindowManager(12821): at com.example.shvalidation.MainMenuScreen$TestThread.onPreExecute(MainMenuScreen.java:49)
02-13 13:36:32.804: E/WindowManager(12821): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
02-13 13:36:32.804: E/WindowManager(12821): at android.os.AsyncTask.execute(AsyncTask.java:534)
02-13 13:36:32.804: E/WindowManager(12821): at com.example.shvalidation.MainMenuScreen.onCreate(MainMenuScreen.java:30)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.Activity.performCreate(Activity.java:5104)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-13 13:36:32.804: E/WindowManager(12821): at android.os.Handler.dispatchMessage(Handler.java:99)
02-13 13:36:32.804: E/WindowManager(12821): at android.os.Looper.loop(Looper.java:137)
02-13 13:36:32.804: E/WindowManager(12821): at android.app.ActivityThread.main(ActivityThread.java:5039)
02-13 13:36:32.804: E/WindowManager(12821): at java.lang.reflect.Method.invokeNative(Native Method)
02-13 13:36:32.804: E/WindowManager(12821): at java.lang.reflect.Method.invoke(Method.java:511)
02-13 13:36:32.804: E/WindowManager(12821): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-13 13:36:32.804: E/WindowManager(12821): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-13 13:36:32.804: E/WindowManager(12821): at dalvik.system.NativeStart.main(Native Method)
我想知道是否有人知道我可以导出这些记录。是的,我知道向SQLite输出超过25,000条记录是荒谬的,但不幸的是,这是我被分配的项目。因此,我必须找到一种方法来实现它。
编辑:添加使用Web服务的代码并保存到SQLite。
package com.example.shvalidation;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainMenuScreen extends Activity {
//JSON Variables
JSONParser jsonParser = new JSONParser();
String pid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu_layout);
new TestThread().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu_layout, menu);
return true;
}
public void PlantToDome(View view) {
Intent intent = new Intent(this, SelectLocationScreen.class);
startActivity(intent);
}
//Código del Web Service
public class TestThread extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
protected void onPreExecute() {
dialog = ProgressDialog.show(MainMenuScreen.this, "Loading", "Loading data, please wait..");
}
protected Void doInBackground(Void...args0) {
int success;
Book book = new Book();
DatabaseHandler handler = new DatabaseHandler(MainMenuScreen.this);
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
"http://192.168.1.102:8080/WSBook.php", "GET", params);
// check your log for json response
// json success tag
success = json.getInt("success");
if (success == 1) {
// successfully received product details
JSONArray productObj = json.getJSONArray("record"); // JSON Array
// get first product object from JSON Array
// JSONObject product = productObj.getJSONObject(1);
for (int i = 0; i < productObj.length(); i++) {
JSONObject record = productObj.getJSONObject(i);
book.setAoiName(record.getString("aoi_name"));
book.setExptName(record.getString("expt_name"));
book.setEuID(record.getInt("eu_id"));
book.setX(record.getInt("x"));
book.setY(record.getInt("y"));
book.setZ(record.getInt("z"));
book.setRaplo(record.getString("raplo"));
// Book book = new Book(record.getString("aoi_name"), record.getString("expt_name"), record.getInt("eu_id"),
// record.getInt("x"), record.getInt("y"), record.getInt("z"), record.getString("raplo"));
handler.InsertBook(book);
}
}
} catch (Exception e) {
Log.e("error", e.toString());
}
return null;
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
}
}
编辑#2:我的JSON Parser类。
package com.example.shvalidation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET method
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
Log.e("Unsupported Encoding", Log.getStackTraceString(e));
} catch (ClientProtocolException e) {
Log.e("Client Protocol", Log.getStackTraceString(e));
} catch (IOException e) {
Log.e("IO Exception", Log.getStackTraceString(e));
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
Log.e("JSON Parser", json);
}
// return JSON String
return jObj;
}
}
答案 0 :(得分:2)
看起来你试图先将所有25,000行的数据拉入内存,然后将它们写入SQLite(这是猜测,因为你没有显示任何代码,但我敢打赌这是一个很好的猜测)。您必须将其限制为,例如,一次100行。也就是说,从Web服务中读取100行,然后将它们写入SQLite,然后再读取100行等等。您可以通过线程获得更好的功能,但这样可以让您走上正确的道路。
修改:感谢您添加代码。看起来罪魁祸首就是这条线:
JSONObject json = jsonParser.makeHttpRequest(
"http://192.168.1.102:8080/WSBook.php", "GET", params);
尝试从Web服务中读取整个表的文本并将其插入JSONObject,您的手机没有足够的内存来处理。
我看到两个解决方案: