我的应用程序依赖于Android独立类的核心模块来执行业务逻辑。这些对象需要可用于应用程序的所有部分,并且还需要在整个应用程序中保持其状态。
我一直在Application子类中实例化这些对象,并在我的活动和服务中使用它们。但是当Android决定杀死我的应用程序以释放内存时,这些业务逻辑对象也会被杀死并失去状态。
Android应用程序中有状态业务对象模型的最佳策略是什么?
答案 0 :(得分:1)
完美的解决方案是使用持久性存储。我所遵循的有点复杂但非常有用。 它分为三个部分:
以及以下步骤:
通过这种方式,您可以通过应用程序轻松获取所有数据
数据库:不打算详细说明。它可以是任何持久性存储,如db或preference。
API Helper :示例api帮助程序类。它可以是任何东西,取决于您的存储。
public class AppsApi {
private static AppsApi appInstance;
private Context mContext;
public static AppsApi getInstance(Context context) {
if (appInstance == null)
appInstance = new AppsApi(context);
return appInstance;
}
public AppsApi(Context context) {
this.mContext = context;
}
public static String PROJECTION[];
static {
String[] arrayOfString = new String[5];
arrayOfString[0] = AppsTable.COLUMN_ID;
arrayOfString[1] = AppsTable.COLUMN_APP_NAME;
arrayOfString[2] = AppsTable.COLUMN_APP_PACKAGE_NAME;
arrayOfString[3] = AppsTable.COLUMN_APP_ACTIVITY_NAME;
arrayOfString[4] = AppsTable.COLUMN_IS_FROM_DASHBOARD;
PROJECTION = arrayOfString;
}
public int insertApp(ContentValues app) {
Uri uri = mContext.getContentResolver().insert(
DashDroidContentProvider.CONTENT_URI_APP, app);
System.out.println("APP Added URI :: " + uri);
return Integer.parseInt(uri.getLastPathSegment());
}
public Cursor getAllApps() {
return mContext.getContentResolver().query(
DashDroidContentProvider.CONTENT_URI_APP, AppsApi.PROJECTION,
null, null, null);
}
public Cursor getAllApp(boolean isFromDashBoard) {
int is = isFromDashBoard ? 1 : 0;
return mContext.getContentResolver().query(
DashDroidContentProvider.CONTENT_URI_APP, AppsApi.PROJECTION,
AppsTable.COLUMN_IS_FROM_DASHBOARD + " LIKE ?",
new String[] { is + "" }, null);
}
public void deleteApp(int id) {
mContext.getContentResolver().delete(
DashDroidContentProvider.CONTENT_URI_APP,
AppsTable.COLUMN_ID + " = ?", new String[] { id + "" });
}
public void deleteApp(String packageName) {
mContext.getContentResolver().delete(
DashDroidContentProvider.CONTENT_URI_APP,
AppsTable.COLUMN_APP_PACKAGE_NAME + " LIKE ?",
new String[] { packageName + "" });
}
public void updateApp(ContentValues app, int id) {
int uri = mContext.getContentResolver().update(
DashDroidContentProvider.CONTENT_URI_APP, app, "_id=?",
new String[] { id + "" });
System.out.println("App Updated URI ::" + uri);
}
public void clear() {
mContext.getContentResolver().delete(
DashDroidContentProvider.CONTENT_URI_APP, null, null);
}
public int count() {
return ((Cursor) mContext.getContentResolver().query(
DashDroidContentProvider.CONTENT_URI_APP,
new String[] { AppsTable.COLUMN_ID }, null, null, null))
.getCount();
}
public Cursor filterApp(String selection, String[] selectionArgs) {
return mContext.getContentResolver().query(
DashDroidContentProvider.CONTENT_URI_APP, AppsApi.PROJECTION,
selection, selectionArgs, null);
}
public int insertBulkApps(ContentValues[] apps) {
int noOfRecordInserted = mContext.getContentResolver().bulkInsert(
DashDroidContentProvider.CONTENT_URI_APP, apps);
System.out.println("Inserted Record Count :: " + noOfRecordInserted);
return noOfRecordInserted;
}
}
数据助手:它是一个单实例类。通过应用程序为您提供数据。它很庞大但很简单。
public class AppsHelper {
public static final int TYPE_SAVE = 0;
public static final int TYPE_GET = 1;
public static final int TYPE_UPDATE = 2;
private AppsData[] appsDashBoard;
private AppsData[] appsMoreApps;
private AppsApi appsProvider;
private OnDataBaseUpdateListener mListener;
private static AppsHelper mHelper;
public AppsHelper(Context context) {
appsProvider = AppsApi.getInstance(context);
initData();
if (appsProvider.count() == 0) {
new saveDataTask().execute();
} else {
updateAppsFromDatabase();
}
}
public static AppsHelper getInstance(Context context) {
if (mHelper == null)
mHelper = new AppsHelper(context);
return mHelper;
}
private void initData() {
appsDashBoard = new AppsData[DashDroidConstants.NO_OF_DASH_BOARD_APPS];
appsMoreApps = new AppsData[DashDroidConstants.NO_OF_MORE_APPS];
for (int i = 0; i < appsDashBoard.length; i++) {
appsDashBoard[i] = new AppsData(i, "null", "null", "null");
}
for (int i = appsDashBoard.length; i < (appsMoreApps.length + appsDashBoard.length); i++) {
appsMoreApps[i - appsDashBoard.length] = new AppsData(i, "null",
"null", "null");
}
}
public void updateMoreApp(String appName, String activityName,
String appPackageName, int index) {
appsMoreApps[index].setData(appName, activityName, appPackageName);
new updateDataTask(false, index).execute();
}
public void updateMoreApp(String appName, String activityName,
String appPackageName, int index, OnDataBaseUpdateListener listener) {
appsMoreApps[index].setData(appName, activityName, appPackageName);
this.mListener = listener;
new updateDataTask(false, index).execute();
}
public void updateDashBoardApp(String appName, String activityName,
String appPackageName, int index) {
appsDashBoard[index].setData(appName, activityName, appPackageName);
new updateDataTask(true, index).execute();
}
public void updateDashBoardApp(String appName, String activityName,
String appPackageName, int index, OnDataBaseUpdateListener listener) {
appsDashBoard[index].setData(appName, activityName, appPackageName);
this.mListener = listener;
new updateDataTask(true, index).execute();
}
public void updateAppsFromDatabase() {
new getDataTask().execute();
}
public AppsData[] getDashBoardApps() {
return appsDashBoard;
}
public AppsData[] getMoreApps() {
return appsMoreApps;
}
private void updateAppInDatabase(boolean isDashBoardApp, int index) {
ContentValues cv = new ContentValues();
cv = new ContentValues();
if (isDashBoardApp) {
cv.put(AppsTable.COLUMN_APP_PACKAGE_NAME,
appsDashBoard[index].getPackageName());
cv.put(AppsTable.COLUMN_APP_ACTIVITY_NAME,
appsDashBoard[index].getActivityName());
cv.put(AppsTable.COLUMN_APP_NAME, appsDashBoard[index].getAppName());
} else {
cv.put(AppsTable.COLUMN_APP_PACKAGE_NAME,
appsMoreApps[index].getPackageName());
cv.put(AppsTable.COLUMN_APP_ACTIVITY_NAME,
appsMoreApps[index].getActivityName());
cv.put(AppsTable.COLUMN_APP_NAME, appsMoreApps[index].getAppName());
}
int dbIndex = isDashBoardApp ? index : index + appsDashBoard.length;
appsProvider.updateApp(cv, dbIndex);
}
private int saveDataInDatabase() {
ContentValues[] cv = new ContentValues[appsDashBoard.length
+ appsMoreApps.length];
for (int i = 0; i < appsDashBoard.length; i++) {
cv[i] = new ContentValues();
cv[i].put(AppsTable.COLUMN_ID, appsDashBoard[i].getId());
cv[i].put(AppsTable.COLUMN_APP_PACKAGE_NAME,
appsDashBoard[i].getPackageName());
cv[i].put(AppsTable.COLUMN_APP_ACTIVITY_NAME,
appsDashBoard[i].getActivityName());
cv[i].put(AppsTable.COLUMN_APP_NAME, appsDashBoard[i].getAppName());
cv[i].put(AppsTable.COLUMN_IS_FROM_DASHBOARD, "1");
}
for (int i = appsDashBoard.length; i < (appsMoreApps.length + appsDashBoard.length); i++) {
cv[i] = new ContentValues();
cv[i].put(AppsTable.COLUMN_ID, appsMoreApps[i
- appsDashBoard.length].getId());
cv[i].put(AppsTable.COLUMN_APP_PACKAGE_NAME, appsMoreApps[i
- appsDashBoard.length].getPackageName());
cv[i].put(AppsTable.COLUMN_APP_ACTIVITY_NAME, appsMoreApps[i
- appsDashBoard.length].getActivityName());
cv[i].put(AppsTable.COLUMN_APP_NAME, appsMoreApps[i
- appsDashBoard.length].getAppName());
cv[i].put(AppsTable.COLUMN_IS_FROM_DASHBOARD, "0");
}
return appsProvider.insertBulkApps(cv);
}
private void getDataFromDatabase() {
Cursor appCursor = appsProvider.getAllApps();
appCursor.moveToFirst();
for (int i = 0; i < appsDashBoard.length; i++) {
appsDashBoard[i]
.setData(
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_NAME)),
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_ACTIVITY_NAME)),
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_PACKAGE_NAME)));
appCursor.moveToNext();
}
for (int i = 0; i < appsMoreApps.length; i++) {
appsMoreApps[i]
.setData(
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_NAME)),
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_ACTIVITY_NAME)),
appCursor.getString(appCursor
.getColumnIndex(AppsTable.COLUMN_APP_PACKAGE_NAME)));
appCursor.moveToNext();
}
}
private class saveDataTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... params) {
return saveDataInDatabase();
}
@Override
protected void onPostExecute(Integer result) {
if (mListener != null)
mListener.onDataUpdate(TYPE_SAVE);
super.onPostExecute(result);
}
}
private class getDataTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
getDataFromDatabase();
return null;
}
@Override
protected void onPostExecute(Void result) {
if (mListener != null)
mListener.onDataUpdate(TYPE_GET);
super.onPostExecute(result);
}
}
private class updateDataTask extends AsyncTask<Void, Void, Void> {
boolean isFromDashBoard;
int index;
public updateDataTask(boolean isFromDashBoard, int index) {
this.isFromDashBoard = isFromDashBoard;
this.index = index;
}
@Override
protected Void doInBackground(Void... params) {
updateAppInDatabase(isFromDashBoard, index);
return null;
}
@Override
protected void onPostExecute(Void result) {
if (mListener != null)
mListener.onDataUpdate(TYPE_UPDATE);
super.onPostExecute(result);
}
}
public static class AppsData {
int id;
String appName;
String activityName;
String packageName;
public AppsData(int id, String appName, String activityName,
String packageName) {
this.id = id;
this.appName = appName;
this.activityName = activityName;
this.packageName = packageName;
}
public void setData(String appName, String activityName,
String packageName) {
this.appName = appName;
this.activityName = activityName;
this.packageName = packageName;
}
public int getId() {
return id;
}
public String getAppName() {
return appName;
}
public String getPackageName() {
return packageName;
}
public String getActivityName() {
return activityName;
}
}
public interface OnDataBaseUpdateListener {
public void onDataUpdate(int updateType);
}
}
它可以帮助您创建更结构化的代码和始终可用的数据,只需要调用AppsHelper.getInstance(context)
并激活!!! :)
答案 1 :(得分:0)
如果要在用户关闭应用程序时保存它们,则必须将它们保存在共享首选项或数据库中或手机内存中的文件中!
对于内部应用程序,您可以在从Serializable
或Parcelable
扩展的类中定义它们,并在活动/片段/等之间传递它们