在我的 Android-App 中,我想加载一个大的 JSON 文件,解析它,检查该值是否已经在我的 SQLite-DB 中并插入/更新它。我的 ListView 稍后会由 CursorLoader 更新,这应该可以解决。
但是获取和插入/更新本身总是崩溃并且没有值被存储。我很确定我的代码效率有点低(例如,每个项目检查一个查询)但这是唯一的原因吗?
JSON 是否太大(约 23MB)?
JSONHelper.java
还是应该扩展其他类AsyncTask
?
我应该返回什么字符串doBackground()
?
这是我的代码:
MyActivity.java
:
// ...
protected void onCreate(Bundle bundle) {
// ...
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
new JSONHelper(view.getContext()).execute(ActionType.GET_PLACES);
}
});
// ...
JSONHelper.java
:
public class JSONHelper extends AsyncTask<my.package.JSONHelper.ActionType,
Void, String> {
// enum to define action type
public enum ActionType {
GET_CATEGORIES, GET_PLACES
}
// a lot of private static final Strings
private ActionType actionType;
private Context context;
// Creating JSON Parser instance
private JSONParser jParser;
private JSONObject json;
// constructor
public JSONHelper(Context context) {
this.context = context;
}
@Override
protected String doInBackground(ActionType... params) {
actionType = params[0];
executeAction();
}
private void executeAction() {
// which JSON-Type needs to be handled
switch (actionType) {
case GET_CATEGORIES:
// Creating JSON Parser instance
jParser = new JSONParser();
// getting JSON string from URL
json = jParser.getJSONFromUrl(URL_GET_CATEGORIES);
try {
// Getting Array of categories
JSONArray categories = json.getJSONArray(TAG01);
// looping through all categories
for(int i = 0; i < categories.length(); i++){
JSONObject c = categories.getJSONObject(i);
// Storing each json item in variable
String categoryId = c.getString(TAG02);
String categoryName = c.getString(TAG03);
// ...
ContentValues values = new ContentValues();
values.put(COLUMN_ID, categoryId);
values.put(COLUMN_NAME, categoryName);
// ...
// check if it exists in DB
Cursor cursor = context.getContentResolver()
.query(MyContentProvider
.CATEGORIES_URI,
new String[] {COLUMN_ID},
COLUMN_ID + "=?", new String[] {categoryId}, null);
// if it already exists => update
if (cursor.moveToFirst()) {
String idTmp = cursor.getString(cursor
.getColumnIndexOrThrow(COLUMN_CMID));
context.getContentResolver().update(MyContentProvider
.CATEGORIES__URI, values,
COLUMN_ID + "=?", new String[] {idTmp});
// close the cursor
cursor.close();
}
// else insert as new row
else {
context.getContentResolver().insert(MyContentProvider
.CATEGORIES_URI, values);
// close the cursor
cursor.close();
}
}
}
catch (JSONException e) {
e.printStackTrace();
}
break;
case GET_PLACES:
// ...
}
}
}
既不JSONParser.java
也不MyContentProvider.java
扩展AsyncTask
。他们应该吗?
提前非常感谢!
编辑:
我忘记了 Logcat,抱歉,这里是:
08-22 16:38:20.958: E/dalvikvm-heap(14337): Out of memory on a 21404366-byte allocation.
...
08-22 16:38:21.018: W/dalvikvm(14337): threadid=13: thread exiting with uncaught exception (group=0x410ba438)
08-22 16:38:21.068: E/AndroidRuntime(14337): FATAL EXCEPTION: AsyncTask #2
08-22 16:38:21.068: E/AndroidRuntime(14337): java.lang.RuntimeException: An error occured while executing doInBackground()
08-22 16:38:21.068: E/AndroidRuntime(14337): at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-22 16:38:21.068: E/AndroidRuntime(14337): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.lang.Thread.run(Thread.java:856)
08-22 16:38:21.068: E/AndroidRuntime(14337): Caused by: java.lang.OutOfMemoryError
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:124)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.lang.StringBuilder.append(StringBuilder.java:271)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.io.BufferedReader.readLine(BufferedReader.java:417)
08-22 16:38:21.068: E/AndroidRuntime(14337): at my.package.JSONParser.getJSONFromUrl(JSONParser.java:56)
08-22 16:38:21.068: E/AndroidRuntime(14337): at my.package.JSONHelper.executeAction(JSONHelper.java:203)
08-22 16:38:21.068: E/AndroidRuntime(14337): at my.package.JSONHelper.doInBackground(JSONHelper.java:103)
08-22 16:38:21.068: E/AndroidRuntime(14337): at my.package.JSONHelper.doInBackground(JSONHelper.java:1)
08-22 16:38:21.068: E/AndroidRuntime(14337): at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-22 16:38:21.068: E/AndroidRuntime(14337): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-22 16:38:21.068: E/AndroidRuntime(14337): ... 5 more