GVKun编程网logo

在Android中使用ORMLite持久保存Collection类(android持久化存储方式)

15

本文将为您提供关于在Android中使用ORMLite持久保存Collection类的详细介绍,我们还将为您解释android持久化存储方式的相关知识,同时,我们还将为您提供关于AndroidAndE

本文将为您提供关于在Android中使用ORMLite持久保存Collection类的详细介绍,我们还将为您解释android持久化存储方式的相关知识,同时,我们还将为您提供关于Android AndEngine:正确处理Collission Detection、Android Collection Widget 的基本示例、Android ORMLite ForeignCollection关联外部集合、android – Robolectric:使用ormlite进行测试的实用信息。

本文目录一览:

在Android中使用ORMLite持久保存Collection类(android持久化存储方式)

在Android中使用ORMLite持久保存Collection类(android持久化存储方式)

我有两个如下的类设置。当我需要注释什么东西作为外国收藏时,我什么时候不需要,我感到困惑。这听起来也很愚蠢,但是ORMLite文档中没有任何地方说明是否允许非外部集合。如果我有一个自动int装箱到Integer的清单,该怎么办?我可以使用@DatabaseField上面的标准来坚持Collection吗?根据,外国馆藏ORMLite还必须具有向后引用才能正常工作(给父母的引用,具有一对多的关系)。对于下面的示例,我假设您应该将注解myBList作为外部集合并进行myA异化,但是您将如何处理myStringList呢?

我在这里看到了示例代码,但没有回答我的问题:http :
//ormlite.com/docs/examples

public class A {    private Set<B> myBList = new HashSet<B>();    private List<String> myStringList = new ArrayList<String>();    private long id;        public A(){}    public Set<B> getMyBList() {        return myBList;    }    public void setMyBList(Set<B> myBList) {        this.myBList = myBList;    }    public List<String> getMyStringList() {        return myStringList;    }    public void setMyStringList(List<String> myStringList) {        this.myStringList = myStringList;    }    public void setId(long id){        this.id = id;    }    public long getId(){        return id;    }}public class B {    private int myInt;    private String myString;    private A myA;    private long id;    public B(){}    public A getMyA(){         return myA;    }    public A setMyA(A a){        myA = a;    }    public int getMyInt() {        return myInt;    }    public void setMyInt(int myInt) {        this.myInt = myInt;    }    public String getMyString() {        return myString;    }    public void setMyString(String myString) {        this.myString = myString;    }    public void setId(long id){        this.id = id;    }    public long getId(){        return id;    }}

答案1

小编典典

@罗伯特是正确的。当hibernate持久化一个集合(甚至一个数组)时,它会使用带有外部ID的隐藏的多余表(换句话说,就是隐藏的外部集合)来实现。ORMLite尝试遵守KISS原则,因此您是否“手工”定义了国外藏品。

我添加了有关存储集合的更多详细信息。

http://ormlite.com/docs/foreign-
collection


这意味着您不能持久化Integer类型,因为没有外部标识符。另外,您的代码可以定义外部集合Collection<Order>ForeignCollection<Order>。任一个都会设置为ForeignCollection。ORMLite不支持列表或其他集合类型。

Android AndEngine:正确处理Collission Detection

Android AndEngine:正确处理Collission Detection

我正在研究一个涉及ff的简单AndEngine游戏.精灵

a.)坦克
b.)士兵
c.)炸弹

我在这里有一个类似的问题:Android AndEngine: Simple sprite collision

游戏的样子:

但是,在解决最初的问题时,又出现了另一个问题:

当炸弹(飞机当前所在的地方并垂直下降,直到它到达目标或地板,通过鼠标点击)击中目标,说一名士兵,士兵精灵必须分离并留下血液飞溅精灵1秒,以及炸弹爆炸精灵.但是,游戏力关闭会产生indexOutOfBoundError.据我所知,这可能是炸弹与其目标之间精灵数量的差异,导致出现数组错误,但logCat根本没有帮助.

09-22 11:13:37.585: E/AndroidRuntime(735): FATAL EXCEPTION: UpdateThread
09-22 11:13:37.585: E/AndroidRuntime(735): java.lang.indexoutofboundsexception: Invalid  index 5,size is 5
09-22 11:13:37.585: E/AndroidRuntime(735):  at java.util.ArrayList.throwindexoutofboundsexception(ArrayList.java:251)
09-22 11:13:37.585: E/AndroidRuntime(735):  at java.util.ArrayList.get(ArrayList.java:304)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onUpdateScene(Engine.java:591)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onUpdate(Engine.java:586)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)

如此处所示,logCat没有在我的代码上给出错误,但是在AndEngine本身上,并且很可能不是这样.

我的新代码在onCreateScene Update Handler中运行(根据上面链接的上一个问题的帮助):

protected void checkSoldierCollision() {
    // Todo Auto-generated method stub

    int numBombs = bombGroup.getChildCount();
    int numTroops = troopsGroup.getChildCount();
    final ArrayList<Sprite> tobedetached = new ArrayList<Sprite>();
    for (int i = 0; i < numBombs; i++) {
        Sprite s = (Sprite) bombGroup.getChildByIndex(i);
        for (int j = 0; j < numTroops; j++) {
            Sprite s2 = (Sprite) troopsGroup.getChildByIndex(j);

            if (s.collidesWith(s2)) {

                /*Sprite splat = createSplat();
                splat.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splat);*/

                Sprite splode = createExplosion();
                splode.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splode);

                // WARNING: cannot detach from the list
                 //while looping through the list
                tobedetached.add(s);
                tobedetached.add(s2);

            }
        }
    }
    runOnUpdateThread(new Runnable() {
        @Override
        public void run() {
            for (Sprite s : tobedetached) {
                s.detachSelf();
                Sprite splode = createExplosion();
                splode.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splode);

            }
            tobedetached.clear();
        }
    });

}

我注意到它只能是一个splat或爆炸,因为它没有错误.如果在碰撞时溅射和爆炸都填充场景,则会发生错误.

此外,即使炸弹不击中士兵(但仍然分开并在击中地板时被爆炸云取代),它也会出现类似的错误:

我的createBomb函数:

public Sprite createBomb(float x,float y) {
    Sprite bombSprite = new Sprite(x,y,this.mBombTextureRegion,getVertexBufferObjectManager());

    MoveYModifier downModBomb = new MoveYModifier(1,60,FLOOR);

    downModBomb.addModifierListener(new IModifierListener<IEntity>() {

        @Override
        public void onModifierStarted(IModifier<IEntity> pModifier,IEntity pItem) {

        }

        @Override
        public void onModifierFinished(IModifier<IEntity> pModifier,final IEntity pItem) {
             pItem.detachSelf();
             AnimatedSprite explodeSprite = createExplosion();
             explodeSprite.setPosition(pItem.getX(),FLOOR);
             getEngine().getScene().attachChild(explodeSprite);
        }
    });

    bombSprite.registerEntityModifier(downModBomb); // register action
    return bombSprite;
}

我的onCreateScene炸弹功能和碰撞up​​dateHandler:

scene.setonScenetouchListener(new IOnScenetouchListener() {

        @Override
        public boolean onScenetouchEvent(Scene pScene,TouchEvent pScenetouchEvent) {
            if (pScenetouchEvent.getAction() == TouchEvent.ACTION_UP) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Sprite bomb = createBomb(f16Sprite.getX(),f16Sprite.getY());
                        bombGroup.attachChild(bomb);
                    }
                });

                return true;
            }
            return false;
        }
    });

    // periodic checks
    scene.registerUpdateHandler(new IUpdateHandler() {

        @Override
        public void onUpdate(float pSecondsElapsed) {
            // checkTankCollision();
            // checkSoldierBackCollision();
            checkSoldierCollision();
        }

        @Override
        public void reset() {
        }
    });

我的createExplosion方法:

public AnimatedSprite createExplosion() {
    AnimatedSprite boomSprite = new AnimatedSprite(0,this.mExplodeTextureRegion,getVertexBufferObjectManager());

    DelayModifier delay = new DelayModifier(.3f); // delay in seconds,can
                                                    // take float numbers .5
                                                    // seconds
    delay.addModifierListener(new IModifierListener<IEntity>() {

        @Override
        public void onModifierStarted(IModifier<IEntity> pModifier,IEntity pItem) {
            ((AnimatedSprite) pItem).animate(new long[] { 100,100,100 },// durations/frame
                    new int[] { 1,2,3 },// which frames
                    true); // loop
        }

        @Override
        public void onModifierFinished(IModifier<IEntity> pModifier,final IEntity pItem) {
            ((AnimatedSprite) pItem).detachSelf();
        }
    });

    boomSprite.registerEntityModifier(delay); // register action
    return boomSprite;
}

我该如何解决这个问题?循环逻辑并不完全是我的强项.我也对如何实现这个问题持开放态度.

更新:刚刚意识到,即使碰撞的结果是啪啪声或爆炸声,也没关系,如果玩家持续发送垃圾邮件(比如4-5次)整个游戏部队关闭.

– 无论何时创建焊料/罐的实例,似乎都有可允许的轰炸次数.每当炸弹袭击一名士兵时,我就会先关闭制造爆炸(所以血液板只会留在原位而不是两者).它工作正常,但超过4-6枚炸弹,游戏结束.当一个新的士兵实例产生时(意味着当旧的士兵离开屏幕并分离时),然后在游戏部队关闭之前给予玩家4-6个炸弹.

解决方法

问题可能是由于您通过调用runOnUiThread在UI线程上附加炸弹而检查更新线程上的冲突.尝试在runOnUpdateThread中添加炸弹.

通常,您希望保持一致的用于操作事物的线程,否则将出现奇怪的错误,这是调试的痛苦.

旁注:UI线程非常适合显示Toasts,请参阅此示例:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(GameActivity.this,"Hello!",Toast.LENGTH_SHORT).show();
    }
});

Android Collection Widget 的基本示例

Android Collection Widget 的基本示例

如何解决Android Collection Widget 的基本示例?

我正在创建一个基于 React Native 的应用程序,它在 Android 上运行良好。

现在我想为应用程序的 Android 版本创建一个小部件。但是,我正在努力获取带有最新 Android Studio 的兼容 Android SDK(10.0 Q)的示例集合小部件代码。如果我得到基本的 Collection 小部件就太好了,它可以只显示数组或对象数组中的列表,这将是一个很好的起点。

还想知道一些很好的教程/材料来开始使用集合小部件。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

Android ORMLite ForeignCollection关联外部集合

Android ORMLite ForeignCollection关联外部集合



《Android ORMLite ForeignCollection关联外部集合》
  
Android ORMLite ForeignCollection关联外部集合的功能,适合层级比较深,数据模型互相渗透、交叉的数据结构或集合。尤其方便解决复杂数据模型。简单期间,我们暂时以 班级 <-> 学生 这样的数据模型为例加以说明。一个班级里面有若干学生(一对多,1<-n),反过来说,若干个学生集合到一个班级中(n->1)。 在Android ORMLite中,这样的结构模型可以用@ForeignCollectionField,ForeignCollection建模。我们定义一个班级类AClass(之所以在 ''Class''前加一个‘A’,是因为Java语言中,''Class''是保留字,却刚好是我们想用的班级英文单词,真不巧,所以前面加个''A''规避),AClass包含id(主键,方便查询和更新),name以及指向一个外部Student的集合(ForeignCollection<Student>)。同样,我们定义学生类Student,Student中埋入一个字段aclass指向外部的AClass。
  
 备注:
 Android ORMLite简介文章:http://blog.csdn.net/zhangphil/article/details/46878075
 
 示例代码总共有4个文件:MainActivity.java,主Activity,用于测试。ORMLiteDatabaseHelper.java , AClass.java , Student.java 是数据库相关的代码文件,用于建模。

结构层次如图:



测试用的MainActivity.java :

package zhangphil.ormlitetest;

import java.sql.SQLException;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.ForeignCollection;

import zhangphil.ormlitetest.database.AClass;
import zhangphil.ormlitetest.database.ORMLiteDatabaseHelper;
import zhangphil.ormlitetest.database.Student;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

	private Dao<AClass, Integer> mClassDao;
	private Dao<Student, Integer> mStudentDao;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ORMLiteDatabaseHelper mDatabaseHelper = ORMLiteDatabaseHelper
				.getInstance(this);

		mClassDao = mDatabaseHelper.getClassDao();
		mStudentDao = mDatabaseHelper.getStudentDao();

		// 创建5个班级用以演示。
		for (int i = 1; i < 6; i++) {
			AClass aclass = new AClass();
			aclass.id = i;
			aclass.name = i + "班";
			try {
				mClassDao.createIfNotExists(aclass);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		// 找到id=1的1班。
		AClass class1 = null;
		try {
			class1 = mClassDao.queryForId(1);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		// 创建19个学生,这19个学生都归属到1班。
		for (int i = 1; i < 20; i++) {
			Student s = new Student();
			s.id = i;
			s.name = "学生" + i;

			// 将新创建的这些学生所在班级指针指向1班。
			// 数据模型:id=1的1班和这19个学生是1对多的学生,换句话说,这19个学生是1班的学生。
			s.aclass = class1;

			try {
				mStudentDao.createIfNotExists(s);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onStart() {
		super.onStart();

		/**
		 * 下面我们演示更新一个Student的信息, 然后向上,依据外键,从Student - > Class更新班级信息。
		 * 
		 * */

		// 假设我们更新其中id=1的这个学生所在的这个班级的name变成“一班”。
		Student s1 = null;
		try {
			s1 = mStudentDao.queryForId(1);

			s1.aclass.name = "一班";

			// 更新1班的名字从“1班”变成“一班”
			mClassDao.update(s1.aclass);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		// 显示我们更新后的结果。
		AClass class1 = null;
		try {
			class1 = mClassDao.queryForId(1);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		ForeignCollection<Student> students = class1.students;
		for (Student s : students) {
			Toast.makeText(this, s.toString(), Toast.LENGTH_SHORT).show();
		}
	}
}




以下是数据库相关的建模:

AClass.java :

package zhangphil.ormlitetest.database;

import com.j256.ormlite.dao.ForeignCollection;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "classes")
public class AClass {

	@DatabaseField(canBeNull = false, dataType = DataType.LONG, id = true)
	public long id;

	@DatabaseField(canBeNull = false, defaultValue = "a class", dataType = DataType.STRING)
	public String name;

	@ForeignCollectionField(eager = false)
	public ForeignCollection<Student> students = null;

	public AClass() {

	}
}


Student.java :

package zhangphil.ormlitetest.database;

import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "students")
public class Student {

	public Student(String name, int student_id) {
		this.name = name;
		this.id = student_id;
	}

	@DatabaseField(canBeNull = false, dataType = DataType.INTEGER, id = true)
	public int id;

	@DatabaseField(canBeNull = false, dataType = DataType.STRING)
	public String name;

	@DatabaseField(canBeNull = false, foreign = true, foreignAutoRefresh = true)
	public AClass aclass;

	public Student() {

	}

	@Override
	public String toString() {
		return "id:" + id + " 姓名:" + name + " 所在班级:" + aclass.name;
	}
}


ORMLiteDatabaseHelper.java :

package zhangphil.ormlitetest.database;

import java.sql.SQLException;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;

import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

public class ORMLiteDatabaseHelper extends OrmLiteSqliteOpenHelper {

	private static ORMLiteDatabaseHelper mDatabaseHelper = null;

	private Dao<AClass, Integer> mClassDao = null;
	private Dao<Student, Integer> mStudentDao = null;

	private final static String DataBase_NAME = "school.db";
	private final static int DataBase_VERSION = 1;

	public ORMLiteDatabaseHelper(Context context, String databaseName,
			CursorFactory factory, int databaseVersion) {
		super(context, DataBase_NAME, factory, DataBase_VERSION);
	}

	public static ORMLiteDatabaseHelper getInstance(Context context) {
		if (mDatabaseHelper == null) {
			mDatabaseHelper = new ORMLiteDatabaseHelper(context, DataBase_NAME,
					null, DataBase_VERSION);
		}

		return mDatabaseHelper;
	}

	@Override
	public void onCreate(SQLiteDatabase arg0, ConnectionSource connectionSource) {

		Log.d(this.getClass().getName(), "ORMLite数据库 -> onCreate");

		try {
			TableUtils.createTableIfNotExists(connectionSource, AClass.class);
			TableUtils.createTableIfNotExists(connectionSource, Student.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onUpgrade(SQLiteDatabase database,
			ConnectionSource connectionSource, int oldVersion, int newVersion) {

		Log.i(this.getClass().getName(), "数据库 -> onUpgrade");

		try {
			// 删除旧的数据库表。
			TableUtils.dropTable(connectionSource, AClass.class, true);
			TableUtils.dropTable(connectionSource, Student.class, true);

			// 重新创建新版的数据库。
			onCreate(database, connectionSource);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public Dao<Student, Integer> getStudentDao() {
		if (mStudentDao == null) {
			try {
				mStudentDao = getDao(Student.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}

		return mStudentDao;
	}

	public Dao<AClass, Integer> getClassDao() {
		if (mClassDao == null) {
			try {
				mClassDao = getDao(AClass.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}

		return mClassDao;
	}

	@Override
	public void close() {
		super.close();
		mClassDao = null;
		mStudentDao = null;
	}
}

android – Robolectric:使用ormlite进行测试

android – Robolectric:使用ormlite进行测试

我正在尝试使用robolectric测试Ormlite DAO,但数据库行为与从我的Android应用程序中使用它时的行为不同.我的DAO在Android应用程序上运行得非常好.

阅读robolectric阴影和调试代码,我遇到了ShadowSQLiteOpenHelper(代码here).

有谁知道这个暗影是否足以测试ormlite daos?或者我必须创建自己的影子才能实现这一目标?这里有任何线索/提示/建议/示例吗?

提前致谢.

额外信息:

测试方法:

@Test
public void basictest() throws sqlException {
    assertNotNull(randomStringResource); // Injection of an android resource: OK
    assertthat(randomStringResource, equalTo("Event")); // With correct value: OK
    assertNotNull(eventDao); // Dao injection: OK
    assertthat(eventDao.countOf(), equalTo(0L)); // Table empty: OK

    Event e1 = new Event("e1", new Date());
    eventDao.create(e1);

    assertNotNull(e1.getId()); // ID generated by Ormlite: OK
    assertthat(eventDao.countOf(), equalTo(1L)); // Table not empty: OK
    assertthat("e1", equalTo(eventDao.queryForId(e1.getId()).getName())); // Query for inserted event: Throws exception
}

运行此测试时遇到的一些问题:

>使用“camelCased”属性名查询实体的错误:在最后一行测试时抛出错误(related problem).从来没有像运行Android应用程序这样的问题.
>当我更改其中一个属性名称(例如,isEnabled为启用)以避免camelCase问题时,之前的错误仍然存​​在…似乎内存数据库未应用我在实体上所做的更改.

使用的版本:

> Robolectric 1.1
> Ormlite 4.41

解决方法:

很抱歉复活你的主题,但我遇到了同样的问题.

我正在使用Ormlite 4.45和Robolectric 2.1.

在ShadowSQLiteCursor.java中,cacheColumnNames方法在每个列名称上调用toLowerCase.所以我决定使用我自己的(不调用toLowerCase)来扩展ShadowsqliteCursor:

/**
* Simulates an Android Cursor object, by wrapping a JDBC ResultSet.
*/
@Implements(value = sqliteCursor.class, inheritImplementationMethods = true)
public class ShadowCaseSensitivesqliteCursor extends ShadowsqliteCursor {

private ResultSet resultSet;

public void __constructor__(sqliteCursorDriver driver, String editTable, sqliteQuery query) {}

/**
 * Stores the column names so they are retrievable after the resultSet has closed
 */
private void cacheColumnNames(ResultSet rs) {
    try {
        ResultSetMetaData MetaData = rs.getMetaData();
        int columnCount = MetaData.getColumnCount();
        columnNameArray = new String[columnCount];
        for(int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
            String cName = MetaData.getColumnName(columnIndex);
            this.columnNames.put(cName, columnIndex - 1);
            this.columnNameArray[columnIndex - 1] = cName;
        }
    } catch(sqlException e) {
        throw new RuntimeException("sql exception in cacheColumnNames", e);
    }
}
}

我的答案显然来得太晚,但可能会帮助别人!

我们今天的关于在Android中使用ORMLite持久保存Collection类android持久化存储方式的分享就到这里,谢谢您的阅读,如果想了解更多关于Android AndEngine:正确处理Collission Detection、Android Collection Widget 的基本示例、Android ORMLite ForeignCollection关联外部集合、android – Robolectric:使用ormlite进行测试的相关信息,可以在本站进行搜索。

本文标签: