我正在开发Android应用程序开发项目,我遇到了一个奇怪的情况,这似乎是由CursorLoader的构造函数引起的。 我的应用程序在调试模式下工作正常,但在没有调试的情况下运行时崩溃。 我该如何解决这个问题?
非常感谢提前
代码:
MainActivity.java
package com.tee.quietime;
import ...;
//All imports needed
public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {
public final static String EXTRA_MESSAGE = "com.tee.quietime.MESSAGE";
eventsListAdapter adapter;
protected static GregorianCalendar selectedDate;
protected static TextView selectedDateTxt;
protected static TextView emptyText;
protected static CalendarView mainCalendar;
protected static ListView selectedDateEventsList;
private static final TimeZone defaultTZ=TimeZone.getDefault();
private static final int INSTANCES_LOADER = 0;
private static final String ID_COLNAME = CalendarContract.Instances._ID;
private static final String BEGIN_COLNAME = CalendarContract.Instances.BEGIN;
private static final String END_COLNAME = CalendarContract.Instances.END;
private static final String END_DAY_COLNAME = CalendarContract.Instances.END_DAY;
private static final String END_MINUTE_COLNAME = CalendarContract.Instances.END_MINUTE;
private static final String EVENT_ID_COLNAME = CalendarContract.Instances.EVENT_ID;
private static final String START_DAY_COLNAME = CalendarContract.Instances.START_DAY;
private static final String START_MINUTE_COLNAME = CalendarContract.Instances.START_MINUTE;
private static final String ALL_DAY_COLNAME = CalendarContract.Instances.ALL_DAY;
private static final String DURATION_COLNAME = CalendarContract.Instances.DURATION;
private static final String LOCATION_COLNAME = CalendarContract.Instances.EVENT_LOCATION;
private static final String TITLE_COLNAME = CalendarContract.Instances.TITLE;
private static final String TIMEZONE_COLNAME = CalendarContract.Instances.EVENT_TIMEZONE;
private static final String END_TIMEZONE_COLNAME = CalendarContract.Instances.EVENT_END_TIMEZONE;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting Selected Date for today and updating Text
selectedDate = (GregorianCalendar) Calendar.getInstance();
selectedDateTxt = (TextView)findViewById(R.id.selectedDate);
this.updateSelectedDateTxt();
selectedDateEventsList = (ListView)findViewById(R.id.EventList);
emptyText = (TextView)findViewById(R.id.noEventsTxt);
selectedDateEventsList.setEmptyView(emptyText);
getLoaderManager().initLoader(INSTANCES_LOADER, null, this);
mainCalendar = (CalendarView)findViewById(R.id.mainCalendar);
//Previous Date onClickListener
ImageButton previousDate = (ImageButton) findViewById(R.id.previousDate);
previousDate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
updateSelectedDateList();
}
});
//Next Date onClickListener
ImageButton nextDate = (ImageButton) findViewById(R.id.nextDate);
nextDate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
updateSelectedDateList();
}
});
//Go to Today onClickListener
ImageButton goToToday = (ImageButton) findViewById(R.id.goToToday);
goToToday.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
updateSelectedDateList();
}
});
//Changing date on calendar listener
mainCalendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month,
int dayOfMonth) {
...
updateSelectedDateList();
}
});
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id){
case INSTANCES_LOADER:{
Uri baseUri=Instances.CONTENT_URI;
final String[] INSTANCE_PROJECTION= new String[] {Instances._ID,
Instances.BEGIN,
Instances.END,
Instances.END_DAY,
Instances.END_MINUTE,
Instances.EVENT_ID,
Instances.START_DAY,
Instances.START_MINUTE,
Instances.ALL_DAY,
Instances.DURATION,
Instances.EVENT_LOCATION,
Instances.TITLE,
Instances.EVENT_TIMEZONE,
Instances.EVENT_END_TIMEZONE,
};
String selection = "((" + Instances.VISIBLE + " = ? ) AND (" + Instances.END + " < ? ) AND (" + Instances.BEGIN + " >= ? ))";
String[] selectionArgs = new String[]{"1",String.valueOf(selectedDate.getTimeInMillis()+86400000),String.valueOf(selectedDate.getTimeInMillis())};
////////// CRASHES HERE !! ///////////
return new CursorLoader(this,baseUri,INSTANCE_PROJECTION, selection, selectionArgs, Instances.BEGIN);
}
default:return null;
}
}
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
switch(cursorLoader.getId()){
case INSTANCES_LOADER :{
int i=0,size=0;
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()) size++;
String[][] values= new String[size][5];
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
values[i][0]=cursor.getString(cursor.getColumnIndex(TITLE_COLNAME));
values[i][1]=cursor.getString(cursor.getColumnIndex(LOCATION_COLNAME));
values[i][2]=String.valueOf(Long.parseLong(cursor.getString(cursor.getColumnIndex(BEGIN_COLNAME)))+defaultTZ.getRawOffset());
values[i][3]=String.valueOf(Long.parseLong(cursor.getString(cursor.getColumnIndex(END_COLNAME)))+defaultTZ.getRawOffset());
values[i][4]=cursor.getString(cursor.getColumnIndex(ALL_DAY_COLNAME));
i++;
}
adapter = new eventsListAdapter(this,values);
selectedDateEventsList.setAdapter(adapter);
}
}
}
public void onLoaderReset(Loader<Cursor> cursorLoader) {
cursorLoader=null;
}
protected void updateSelectedDateTxt(){
...
}
protected void updateSelectedDateCalendar(){
...
}
protected void updateSelectedDateList(){
getLoaderManager().restartLoader(INSTANCES_LOADER, null, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
...
}
eventsListAdapter(自定义适配器)
package com.tee.quietime;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class eventsListAdapter extends ArrayAdapter<String[]> {
private final Context context;
private final String[][] values;
public eventsListAdapter(Context context, String[][] values) {
super(context, R.layout.eventrowlayout, values);
this.context = context;
this.values = values;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.eventrowlayout, parent, false);
TextView title = (TextView) rowView.findViewById(R.id.firstLine);
TextView subTitle = (TextView) rowView.findViewById(R.id.secondLine);
String titleOnly= values[position][0];
if (values[position][1]!=null && !values[position][1].isEmpty()){
String titleWithLocation =titleOnly + " at "+values[position][1];
title.setText(titleWithLocation);
}
else
title.setText(titleOnly);
long millisST=Long.parseLong(values[position][2]);
long millisEND=Long.parseLong(values[position][3]);
String strST=String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millisST)%24,
TimeUnit.MILLISECONDS.toMinutes(millisST) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisST)));
String strEND=String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millisEND)%24,
TimeUnit.MILLISECONDS.toMinutes(millisEND) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisEND)));
String subTxt="Starts "+strST+" - "+strEND;
String subTxtAllDay="All day event";
if(values[position][4].compareTo("1")!=0)
subTitle.setText(subTxt);
else
subTitle.setText(subTxtAllDay);
return rowView;
}
}
logcat的
12-02 00:08:12.265: D/OpenGLRenderer(30687): Enabling debug mode 0
12-02 00:08:12.475: D/dalvikvm(30687): threadid=11: still suspended after undo (sc=1 dc=1)
12-02 00:08:17.355: W/dalvikvm(30687): threadid=11: thread exiting with uncaught exception (group=0x4162aba8)
12-02 00:08:17.365: E/AndroidRuntime(30687): FATAL EXCEPTION: AsyncTask #1
12-02 00:08:17.365: E/AndroidRuntime(30687): Process: com.tee.quietime, PID: 30687
12-02 00:08:17.365: E/AndroidRuntime(30687): java.lang.RuntimeException: An error occured while executing doInBackground()
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.os.AsyncTask$3.done(AsyncTask.java:300)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.lang.Thread.run(Thread.java:841)
12-02 00:08:17.365: E/AndroidRuntime(30687): Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.android.calendar/instances/when
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.ContentResolver.query(ContentResolver.java:461)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.CursorLoader.loadInBackground(CursorLoader.java:65)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57)
12-02 00:08:17.365: E/AndroidRuntime(30687): at android.os.AsyncTask$2.call(AsyncTask.java:288)
12-02 00:08:17.365: E/AndroidRuntime(30687): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
12-02 00:08:17.365: E/AndroidRuntime(30687): ... 3 more