编辑:将GetData任务的onPostExecute()方法更改为仅调用cursor.requery()后,它似乎正在工作。
我正在构建一个Android活动,使用kSoap库从Web服务中提取数据。数据存储在sqlite数据库中,并使用listactivity中的自定义CursorAdapter显示。该代码用于更新数据库,它正在按照我想要的方式显示数据库中的数据。
但是,我希望活动检查onCreate中的数据库是否过时,如果它是旧的,请更新数据库,然后设置适配器。为此,我设置了一个AsyncTask,它在后台线程中更新数据库,并在onPostExecute中设置CursorAdapter。如果我尝试使用我的自定义CursorAdapter,则会有例外。但是,如果我使用标准的BasicCursorAdapter(任何游标的列作为数据),它可以正常工作。再次 - 当我没有更新数据库时,自定义CursorAdapter似乎工作正常。
我一直在试图找出可能导致此异常的原因,但我的想法已经用完了。写入数据库然后从中读取可能有问题吗?
以下是活动:
public class MyList extends ListActivity {
private MyDBAdapter db;
private Cursor cursor;
private MyWebService wsData;
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_list);
context = this;
wsData = new MyWebService();
db = new MyDBAdapter(this);
db.open();
//EDIT: I get the cursor and sets the adapter in onCreate instead of in the GetDataTask
cursor = db.getAll();
startManagingCursor(cursor);
ListAdapter adapter = new MyListAdapter(context,
R.layout.my_list_row,
cursor,
new String[] { cursor.getColumnName(1) },
new int[] { R.id.myListRow_id });
setListAdapter(adapter);
//If (dbIsOutdated()) {
new GetDataTask().execute();
//} else {
//setAdapter();
//}
}
@Override
protected void onDestroy() {
super.onDestroy();
db.close();
}
这是任务:
private class GetDataTask extends AsyncTask<Void, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(context);
protected void onPreExecute() {
this.dialog.setMessage("Downloading data...");
this.dialog.show();
}
protected Boolean doInBackground(Void...voids) {
//First get a soapobject with all the leagues
SoapObject unparsed = wsData.getAll();
//Clear all old data in the database
db.clearTables();
//Iterate through the soapobject and fill the database
for (int i=0;i<unparsed.getPropertyCount();i++) {
if (unparsed.getProperty(i) instanceof SoapObject) {
String id = ((SoapObject)unparsed.getProperty(i)).getProperty("Id").toString();
String name = ((SoapObject)unparsed.getProperty(i)).getProperty("Name").toString();
db.insert(id, name);
}
}
return true;
}
protected void onPostExecute(Boolean unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
//this updates the list
cursor.requery();
/* --- This part is not necessary it seems, and might be what
--- causes the memory overloading
cursor = db.getAll();
startManagingCursor(cursor);
ListAdapter adapter = new MyListAdapter(context,
R.layout.my_list_row,
cursor,
new String[] { cursor.getColumnName(1) },
new int[] { R.id.myListRow_id });
setListAdapter(adapter);
*/
}
}
MyWebService是一个处理对WebService的调用的类,getAll()方法返回一个包含SoapObjects的SoapObject及相关数据。
我还有一个方法(setAdapter()),它以与onPostExecute()完全相同的方式设置适配器,并且没有任何问题。
我的适配器:
public class MyListAdapter extends SimpleCursorAdapter {
private Cursor mCursor;
private Context mContext;
public MyListAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.mCursor = c;
this.mContext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row==null){
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.my_list_row, parent, false);
}
this.mCursor.moveToPosition(position);
TextView id=(TextView)row.findViewById(R.id.leagueListRow_id);
TextView name=(TextView)row.findViewById(R.id.leagueListRow_name);
String lId = this.mCursor.getString(1);
String lName = this.mCursor.getString(2);
id.setText(lId);
name.setText(lName);
return row;
}
}
我不确定如何阅读日志,但我认为theese是关键线:
[snip]
02-10 19:18:10.446: DEBUG/dalvikvm(223): GC freed 20592 objects / 1063064 bytes in 546ms
02-10 19:18:17.256: INFO/ARMAssembler(59): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x2fa530:0x2fa6f8] in 10766582 ns
02-10 19:18:17.377: ERROR/dalvikvm-heap(223): 256-byte external allocation too large for this process.
02-10 19:18:17.396: ERROR/(223): VM won't let us allocate 256 bytes
02-10 19:18:17.407: DEBUG/skia(223): --- decoder->decode returned false
02-10 19:18:17.419: DEBUG/AndroidRuntime(223): Shutting down VM
02-10 19:18:17.419: WARN/dalvikvm(223): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
02-10 19:18:17.427: ERROR/AndroidRuntime(223): Uncaught handler: thread main exiting due to uncaught exception
02-10 19:18:17.489: ERROR/AndroidRuntime(223): android.view.InflateException: Binary XML file line #20: Error inflating class <unknown>
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.createView(LayoutInflater.java:513)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.rInflate(LayoutInflater.java:621)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at se.gobrugda.bbmanagerdroid.ListLeaguesNew$LeagueListAdapter.getView(ListLeaguesNew.java:224)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.AbsListView.obtainView(AbsListView.java:1274)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.ListView.measureHeightOfChildren(ListView.java:1147)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.ListView.onMeasure(ListView.java:1060)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.View.measure(View.java:7964)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:888)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.LinearLayout.measureVertical(LinearLayout.java:350)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.View.measure(View.java:7964)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.View.measure(View.java:7964)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.LinearLayout.measureVertical(LinearLayout.java:464)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.View.measure(View.java:7964)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3023)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.View.measure(View.java:7964)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.ViewRoot.performTraversals(ViewRoot.java:763)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.os.Handler.dispatchMessage(Handler.java:99)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.os.Looper.loop(Looper.java:123)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.app.ActivityThread.main(ActivityThread.java:4363)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at java.lang.reflect.Method.invokeNative(Native Method)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at java.lang.reflect.Method.invoke(Method.java:521)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at dalvik.system.NativeStart.main(Native Method)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): Caused by: java.lang.reflect.InvocationTargetException
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.ImageView.<init>(ImageView.java:105)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at java.lang.reflect.Constructor.constructNative(Native Method)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.view.LayoutInflater.createView(LayoutInflater.java:500)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): ... 35 more
02-10 19:18:17.489: ERROR/AndroidRuntime(223): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:447)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.content.res.Resources.loadDrawable(Resources.java:1705)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): at android.widget.ImageView.<init>(ImageView.java:115)
02-10 19:18:17.489: ERROR/AndroidRuntime(223): ... 39 more
02-10 19:18:17.556: INFO/Process(59): Sending signal. PID: 223 SIG: 3
02-10 19:18:17.556: INFO/dalvikvm(223): threadid=7: reacting to signal 3
02-10 19:18:17.636: INFO/dalvikvm(223): Wrote stack trace to '/data/anr/traces.txt