我有一个 android 应用程序,我在其中使用光标和列表视图。我在运行 android 版本为 2.1 时开发了这个应用程序。我决定不使用 StartmanagingCursor() 和 stopmanagingcursor() 因为当我从一个活动转移到另一个活动时它们的行为不稳定。事实上,我创建了一个静态函数,它调用每个生命周期事件来管理活动游标。下面是这个函数的完整代码。
public static void onBegin(Object extraMethodName, Activity activity,
Utils.lifeStatus lastStatus, Utils.lifeStatus currentStatus) {
Method method;
Utils.currentActivity = activity.getLocalClassName() + "_"
+ Integer.toString(activity.getTaskId());
if (!Utils.lifecycleCheck(lastStatus, currentStatus)) {
DBAdapter.open(activity);
if (extraMethodName != null) {
try {
method = activity.getClass().getSuperclass()
.getDeclaredMethod (extraMethodName.toString());
method.setAccessible(true);
method.invoke(activity);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void onEnd(Object extraMethodName, Activity activity,
Utils.lifeStatus lastStatus, Utils.lifeStatus currentStatus) {
Method method;
Log.i("Utils.currentActivity", Utils.currentActivity);
Log.i("ActivityClosing",
activity.getLocalClassName() + "_"
+ Integer.toString(activity.getTaskId()));
if (Utils.lifecycleCheck(lastStatus, currentStatus)) {
if (Utils.currentActivity.equals(activity.getLocalClassName() + "_"
+ Integer.toString(activity.getTaskId()))) {
if (extraMethodName != null) {
try {
method = activity.getClass().getSuperclass()
.getDeclaredMethod(extraMethodName.toString());
method.setAccessible(true);
method.invoke(activity);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
DBAdapter.close();
}
}
}
public static boolean lifecycleCheck(Utils.lifeStatus lastStatus,
Utils.lifeStatus newStatus) {
boolean result = false;
if (lastStatus != null) {
switch (lastStatus) {
case PAUSE:
case DESTROY:
case STOP:
result = false;
break;
case RESUME:
case START:
case RESTART:
case ONACTIVITYRESULT:
result = true;
break;
default:
result = false;
}
} else {
result = false;
}
return result;
}
其中extramethod是onBegin函数中每个activity的初始化函数和onEnd函数中的关闭游标函数。
在我决定创建一个基本 Activity 之前,这些函数一直很完美,其中我有一个光标和一个适配器,所有其他活动都从 base 继承。此活动还管理生命周期。(下面是完整的代码)。在那次更改之后,我在 android v4.0 中部署了我的应用程序,我的客户报告我说它在随机情况下崩溃。复制错误对我来说非常困难,但我可以看到,当应用程序崩溃时,我会将奇怪的重复数据从客户端带到服务器。
package baseActivities;
public class BaseListActivity extends ListActivity {
protected BaseCursorAdapter _cAdapter;
protected BaseGridCursorAdapter _gridAdapter;
protected BaseImageCursorAdapter _imageAdapter;
protected String TAG = "BaseActivity";
private static Utils.lifeStatus _lastStatus = Utils.lifeStatus.DESTROY;
public Cursor _cursor;
public enum filterTypes{
query,category,subcategory,promitheutis
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context cnt=this.getApplicationContext();
Thread.UncaughtExceptionHandler mUEHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
Intent i = new Intent(cnt, MainActivity.class);
i.putExtra("ERROR", 1);
AlarmManager alm = (AlarmManager) cnt
.getSystemService(Context.ALARM_SERVICE);
alm.set(AlarmManager.RTC, System
.currentTimeMillis() + 1000,
PendingIntent.getActivity(
cnt,
0,
i, 0));
Process.killProcess(Process.myPid());
}
};
// Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
}
protected void setupForm() throws Exception {
}
public void search(HashMap<filterTypes,Object> FilterParams)
{
}
public void openRowDetails(int position,String quantity)
{
}
public void back_click(View v) throws Exception {
finish();
}
@Override
protected void onStart() {
super.onStart();
Utils.onBegin("setupForm", this, _lastStatus, Utils.lifeStatus.START);
_lastStatus = Utils.lifeStatus.START;
Log.i(TAG, "onStart()");
}
@Override
protected void onRestart() {
super.onRestart();
Utils.onBegin("setupForm", this, _lastStatus, Utils.lifeStatus.RESTART);
_lastStatus = Utils.lifeStatus.RESTART;
Log.i(TAG, "onRestart()");
}
@Override
protected void onResume() {
super.onResume();
Utils.onBegin("setupForm", this, _lastStatus, Utils.lifeStatus.RESUME);
String settedLanguage = Utils.getLanguage();
Utils.SetLaguage(settedLanguage == null ? Settings.LANGUAGE
: settedLanguage, this.getBaseContext());
_lastStatus = Utils.lifeStatus.RESUME;
Log.i(TAG, "onResume()");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Saving activity state
Log.i(TAG, "onSaveInstanceState()");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onRestoreInstanceState()");
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be
// "paused").
Utils.onEnd("prepareToCloseDB", this, _lastStatus,
Utils.lifeStatus.PAUSE);
Log.i(TAG, "onPause()");
_lastStatus = Utils.lifeStatus.PAUSE;
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
setListAdapter(null);
Utils.onEnd("prepareToCloseDB", this, _lastStatus,
Utils.lifeStatus.STOP);
Log.i(TAG, "onStop()");
_lastStatus = Utils.lifeStatus.STOP;
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
setListAdapter(null);
Utils.onEnd("prepareToCloseDB", this, _lastStatus,
Utils.lifeStatus.DESTROY);
Log.i(TAG, "onDestroy()");
_lastStatus = Utils.lifeStatus.DESTROY;
}
@SuppressWarnings("unused")
protected void prepareToCloseDB() {
TextView emptyTextView = ((TextView)findViewById(android.R.id.empty));
if(emptyTextView!=null)
{
emptyTextView.setText(this.getResources().getString(R.string.parakalw_perimenete));
}
if (_cursor != null) {
if (!_cursor.isClosed()) {
_cursor.close();
}
}
}
}
以下是我从我的应用程序中收集的日志之一。
-----------------EXCEPTION START--------------------
26/01/2013 15:05:58
-----------------STAACKTRACE--------------------
Don't have database lock!
Class:android.database.sqlite.SQLiteDatabase | File:SQLiteDatabase.java | Method:verifyLockOwner | Line:2090
Class:android.database.sqlite.SQLiteDatabase | File:SQLiteDatabase.java | Method:endTransaction | Line:690
Class:myapp.myapp.FindMeetingActivity | File:FindMeetingActivity.java | Method:deleteMeeting | Line:235
Class:myapp.myapp.FindMeetingActivity | File:FindMeetingActivity.java | Method:onContextItemSelected | Line:142
Class:android.app.Activity | File:Activity.java | Method:onMenuItemSelected | Line:2538
Class:com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback | File:PhoneWindow.java | Method:onMenuItemSelected | Line:3521
Class:com.android.internal.view.menu.MenuBuilder | File:MenuBuilder.java | Method:dispatchMenuItemSelected | Line:735
Class:com.android.internal.view.menu.MenuItemImpl | File:MenuItemImpl.java | Method:invoke | Line:149
Class:com.android.internal.view.menu.MenuBuilder | File:MenuBuilder.java | Method:performItemAction | Line:874
Class:com.android.internal.view.menu.MenuDialogHelper | File:MenuDialogHelper.java | Method:onClick | Line:167
Class:com.android.internal.app.AlertController$AlertParams$3 | File:AlertController.java | Method:onItemClick | Line:924
Class:android.widget.AdapterView | File:AdapterView.java | Method:performItemClick | Line:292
Class:android.widget.AbsListView | File:AbsListView.java | Method:performItemClick | Line:1058
Class:android.widget.AbsListView$PerformClick | File:AbsListView.java | Method:run | Line:2514
Class:android.widget.AbsListView$1 | File:AbsListView.java | Method:run | Line:3168
Class:android.os.Handler | File:Handler.java | Method:handleCallback | Line:605
Class:android.os.Handler | File:Handler.java | Method:dispatchMessage | Line:92
Class:android.os.Looper | File:Looper.java | Method:loop | Line:137
Class:android.app.ActivityThread | File:ActivityThread.java | Method:main | Line:4444
Class:java.lang.reflect.Method | File:Method.java | Method:invokeNative | Line:-2
Class:java.lang.reflect.Method | File:Method.java | Method:invoke | Line:511
Class:com.android.internal.os.ZygoteInit$MethodAndArgsCaller | File:ZygoteInit.java | Method:run | Line:787
Class:com.android.internal.os.ZygoteInit | File:ZygoteInit.java | Method:main | Line:554
Class:dalvik.system.NativeStart | File:NativeStart.java | Method:main | Line:-2
---------------EXCEPION END----------------------
你能帮我理解为什么会这样吗?它是由我的基本活动问题引起的,还是由 android v4.0 的更改引起的。?
感谢我们的帮助!